Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into add-ip-range-inpu…
Browse files Browse the repository at this point in the history
…t-to-manage-sat
  • Loading branch information
florkbr committed Sep 9, 2024
2 parents 5434805 + a3ec183 commit 80a7b5c
Show file tree
Hide file tree
Showing 32 changed files with 729 additions and 220 deletions.
1 change: 1 addition & 0 deletions config/webpack.plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const plugins = (dev = false, beta = false, restricted = false) => {
{ '@openshift/dynamic-plugin-sdk': { singleton: true, requiredVersion: deps['@openshift/dynamic-plugin-sdk'] } },
{ '@patternfly/quickstarts': { singleton: true, requiredVersion: deps['@patternfly/quickstarts'] } },
{ '@redhat-cloud-services/chrome': { singleton: true, requiredVersion: deps['@redhat-cloud-services/chrome'] } },
{ '@scalprum/core': { singleton: true, requiredVersion: deps['@scalprum/core'] } },
{ '@scalprum/react-core': { singleton: true, requiredVersion: deps['@scalprum/react-core'] } },
{ '@unleash/proxy-client-react': { singleton: true, requiredVersion: deps['@unleash/proxy-client-react'] } },
getDynamicModules(process.cwd()),
Expand Down
131 changes: 131 additions & 0 deletions cypress/component/ChromeRoutes/ChromeRoute.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { useEffect, useRef, useState } from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import ChromeRoute from '../../../src/components/ChromeRoute';
import { initializeVisibilityFunctions } from '../../../src/utils/VisibilitySingleton';
import { ChromeUser } from '@redhat-cloud-services/types';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { IntlProvider } from 'react-intl';
import ScalprumProvider from '@scalprum/react-core';
import { initialize, removeScalprum } from '@scalprum/core';

const defaultUser: ChromeUser = {
entitlements: {},
identity: {
user: {
is_org_admin: true,
is_active: true,
is_internal: true,
email: '[email protected]',
first_name: 'Joe',
last_name: 'Doe',
locale: 'en',
username: 'jdoe',
},
org_id: '1',
type: 'User',
account_number: '2',
internal: {
org_id: '1',
account_id: '3',
},
},
};

const defaultVisibilityOptions: Parameters<typeof initializeVisibilityFunctions>[0] = {
getToken: () => Promise.resolve('token'),
getUser: () => Promise.resolve(defaultUser),
getUserPermissions: () => Promise.resolve([]),
isPreview: false,
};

const Wrapper = ({ children, getUser }: React.PropsWithChildren<{ getUser?: () => Promise<ChromeUser> }>) => {
const [isReady, setIsReady] = useState(false);
const visibilityOptions: Parameters<typeof initializeVisibilityFunctions>[0] = {
getToken: defaultVisibilityOptions.getToken,
getUser: getUser ?? defaultVisibilityOptions.getUser,
getUserPermissions: defaultVisibilityOptions.getUserPermissions,
isPreview: defaultVisibilityOptions.isPreview,
};
const scalprum = useRef(
initialize({
appsConfig: {
foo: {
name: 'foo',
manifestLocation: '/bar/manifest.json',
},
},
})
);
useEffect(() => {
initializeVisibilityFunctions(visibilityOptions);
// mock the module
scalprum.current.exposedModules['foo#foo'] = {
default: () => <div id="foobar">FooBar</div>,
};

setIsReady(true);
return () => {
removeScalprum();
};
}, []);

if (!isReady) {
return null;
}

return (
<IntlProvider locale="en">
<ScalprumProvider scalprum={scalprum.current}>
<Provider store={createStore((state) => state)}>
<BrowserRouter>
<Routes>
<Route path="*" element={children} />
</Routes>
</BrowserRouter>
</Provider>
</ScalprumProvider>
</IntlProvider>
);
};

describe('ChromeRoute', () => {
it('should render not found route if permissions are not met', () => {
cy.mount(
<Wrapper>
<ChromeRoute module="foo" scope="foo" path="*" permissions={[{ method: 'withEmail', args: ['@nonsense.com'] }] as any} />
</Wrapper>
);

cy.contains('We lost that page').should('be.visible');
});

it('should not render page if there is error while checking permissions', () => {
cy.mount(
<Wrapper getUser={() => Promise.reject('expected error')}>
<ChromeRoute module="foo" scope="foo" path="*" permissions={[{ method: 'withEmail', args: ['@redhat.com'] }] as any} />
</Wrapper>
);

cy.contains('We lost that page').should('be.visible');
});

it('should render page if permissions are met', () => {
cy.mount(
<Wrapper>
<ChromeRoute module="foo" scope="foo" path="*" permissions={[{ method: 'withEmail', args: ['@redhat.com'] }] as any} />
</Wrapper>
);

cy.contains('FooBar').should('be.visible');
});

it('should render route if no permissions are provided', () => {
cy.mount(
<Wrapper>
<ChromeRoute module="foo" scope="foo" path="*" />
</Wrapper>
);
cy.contains('FooBar').should('be.visible');
});
});
130 changes: 130 additions & 0 deletions cypress/component/Preview/BetaSwitcher.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { PropsWithChildren } from 'react';
import { Provider, createStore, useSetAtom } from 'jotai';
import { useHydrateAtoms } from 'jotai/utils';
import BetaSwitcher from '../../../src/components/BetaSwitcher';
import { userConfigAtom } from '../../../src/state/atoms/userConfigAtom';
import { ChromeUserConfig } from '../../../src/utils/initUserConfig';
import { isPreviewAtom } from '../../../src/state/atoms/releaseAtom';

const HydrateAtoms = ({ initialValues, children }: PropsWithChildren<{ initialValues: any }>) => {
useHydrateAtoms(initialValues);
return children;
};

const TestProvider = ({ initialValues, children }: PropsWithChildren<{ initialValues: any }>) => (
<Provider>
<HydrateAtoms initialValues={initialValues}>{children}</HydrateAtoms>
</Provider>
);

const Wrapper = () => {
return <BetaSwitcher />;
};

describe('BetaSwitcher', () => {
it('should show preview modal on first user preview toggle', () => {
const userConfig: ChromeUserConfig = {
data: {
uiPreview: false,
uiPreviewSeen: false,
},
} as ChromeUserConfig;
cy.intercept('POST', 'api/chrome-service/v1/user/mark-preview-seen', {
data: {
uiPreview: true,
uiPreviewSeen: true,
},
});
cy.mount(
<TestProvider
initialValues={[
[userConfigAtom, userConfig],
[isPreviewAtom, false],
]}
>
<Wrapper />
</TestProvider>
);

cy.contains('turn on Preview mode').should('exist');

cy.get('#preview-toggle').click();
cy.contains('Turn on').should('exist');
cy.contains('Turn on').click();
cy.contains('Welcome to preview').should('exist');
cy.wait(5000);
// popover disappears after 5 seconds on its own
cy.contains('Welcome to preview').should('not.exist');
cy.contains('turn off Preview mode').should('exist');

// turn off preview again
cy.get('#preview-toggle').click();
cy.contains('turn on Preview mode').should('exist');
});

it('should not show preview modal on subsequent user preview toggles', () => {
const userConfig: ChromeUserConfig = {
data: {
uiPreview: false,
uiPreviewSeen: true,
},
} as ChromeUserConfig;
cy.mount(
<TestProvider
initialValues={[
[userConfigAtom, userConfig],
[isPreviewAtom, false],
]}
>
<Wrapper />
</TestProvider>
);

cy.contains('turn on Preview mode').should('exist');
cy.contains('Turn on').should('not.exist');

cy.get('#preview-toggle').click();
cy.contains('turn off Preview mode').should('exist');

// turn off preview again
cy.get('#preview-toggle').click();
cy.contains('turn on Preview mode').should('exist');
});

it('should hide the entire banner in stable environment, but show in preview', () => {
const FakePreviewToggle = () => {
const togglePreview = useSetAtom(isPreviewAtom);
return <button onClick={() => togglePreview()}>Fake</button>;
};
const userConfig: ChromeUserConfig = {
data: {
uiPreview: false,
uiPreviewSeen: true,
},
} as ChromeUserConfig;
const store = createStore();
store.set(isPreviewAtom, false);
cy.mount(
<TestProvider
initialValues={[
[userConfigAtom, userConfig],
[isPreviewAtom, false],
]}
>
<Wrapper />
<FakePreviewToggle />
</TestProvider>
);

// if the node is turned off immediately it sometimes doesn't render the banner and the test fails
cy.wait(1000);
cy.get('.pf-v5-c-menu-toggle').click();
cy.get('.pf-v5-c-menu__item-text').should('exist');
cy.get('.pf-v5-c-menu__item-text').click();
cy.get('.pf-v5-c-menu-toggle').should('not.exist');

// turn preview and banner should show
cy.contains('Fake').click();
cy.contains('Welcome to preview').should('exist');
});
});
11 changes: 11 additions & 0 deletions docs/disablingPf4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Disabling PF4 styling

> Note: This flag is mean to be used for debugging purposes to help visually identify usage of outdated PF version
## To remove PF4 styling support follow these steps

1. Open your browser developer tool and access the "console" tab
2. Run this command: `window.insights.chrome.enable.disabledPf4()`
3. Refresh the browser page

> Note: The flag uses localStorage for storage. The browser will remember the flag until the local storage is cleared. To remove the flag run `localStorage.clear()` command in you console and refresh the page.
37 changes: 8 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"url": "^0.11.3",
"utility-types": "^3.11.0",
"wait-on": "^7.2.0",
"webpack": "^5.92.1",
"webpack": "^5.94.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.2",
Expand Down
1 change: 1 addition & 0 deletions src/@types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export type ModuleRoute = {
dynamic?: boolean;
props?: Record<string, unknown>;
supportCaseData?: SupportCaseConfig;
permissions?: NavItemPermission[];
};

export type RemoteModule = {
Expand Down
5 changes: 4 additions & 1 deletion src/auth/OIDCConnector/OIDCProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const OIDCProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
| undefined
>(undefined);
async function setupSSO() {
const { data } = await loadFedModules();
const {
// ignore $schema from the data as it is an spec ref
data: { $schema: ignore, ...data },
} = await loadFedModules();
try {
const {
chrome: {
Expand Down
Loading

0 comments on commit 80a7b5c

Please sign in to comment.