Skip to content

Commit

Permalink
Merge pull request #2717 from Hyperkid123/use-chrome-auth
Browse files Browse the repository at this point in the history
Replace user object from redux by chrome auth context value.
  • Loading branch information
Hyperkid123 authored Dec 1, 2023
2 parents 341f716 + 0fa923f commit 995742d
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 71 deletions.
5 changes: 3 additions & 2 deletions src/components/GlobalFilter/GlobalFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GlobalFilterTag, GlobalFilterWorkloads, ReduxState, SID } from '../../r
import { FlagTagsFilter } from '../../@types/types';
import { isGlobalFilterAllowed } from '../../utils/common';
import InternalChromeContext from '../../utils/internalChromeContext';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

const useLoadTags = (hasAccess = false) => {
const navigate = useNavigate();
Expand Down Expand Up @@ -128,7 +129,7 @@ const GlobalFilter = ({ hasAccess }: { hasAccess: boolean }) => {
const GlobalFilterWrapper = () => {
const [hasAccess, setHasAccess] = useState(false);
const globalFilterRemoved = useSelector(({ globalFilter: { globalFilterRemoved } }: ReduxState) => globalFilterRemoved);
const userLoaded = useSelector(({ chrome: { user } }: ReduxState) => Boolean(user));
const chromeAuth = useContext(ChromeAuthContext);
const { pathname } = useLocation();
const { getUserPermissions } = useContext(InternalChromeContext);

Expand Down Expand Up @@ -157,7 +158,7 @@ const GlobalFilterWrapper = () => {
mounted = false;
};
}, []);
return isGlobalFilterEnabled && userLoaded ? <GlobalFilter hasAccess={hasAccess} /> : null;
return isGlobalFilterEnabled && chromeAuth.ready ? <GlobalFilter hasAccess={hasAccess} /> : null;
};

export default GlobalFilterWrapper;
7 changes: 4 additions & 3 deletions src/components/GlobalFilter/GlobalFilterMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FormEvent, Fragment, MouseEventHandler, useMemo } from 'react';
import React, { FormEvent, Fragment, MouseEventHandler, useContext, useMemo } from 'react';
import { Group, GroupFilter, GroupType } from '@redhat-cloud-services/frontend-components/ConditionalFilter';
import { useIntl } from 'react-intl';

Expand All @@ -18,6 +18,7 @@ import { CommonSelectedTag, ReduxState } from '../../redux/store';
import { updateSelected } from './globalFilterApi';
import { fetchAllTags } from '../../redux/actions';
import { FlagTagsFilter } from '../../@types/types';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

export type GlobalFilterMenuGroupKeys = GroupType;

Expand Down Expand Up @@ -91,7 +92,7 @@ export const GlobalFilterDropdown: React.FunctionComponent<GlobalFilterDropdownP
* */
const hotjarEventEmitter = typeof window.hj === 'function' ? window.hj : () => undefined;
const registeredWith = useSelector(({ globalFilter: { scope } }: ReduxState) => scope);
const userLoaded = useSelector(({ chrome: { user } }: ReduxState) => Boolean(user));
const auth = useContext(ChromeAuthContext);
const intl = useIntl();
const dispatch = useDispatch();
const GroupFilterWrapper = useMemo(
Expand All @@ -102,7 +103,7 @@ export const GlobalFilterDropdown: React.FunctionComponent<GlobalFilterDropdownP
<Fragment>
<Split id="global-filter" hasGutter className="chr-c-global-filter">
<SplitItem>
{userLoaded && allowed !== undefined ? (
{auth.ready && allowed !== undefined ? (
<GroupFilterWrapper
content={
!allowed || isDisabled
Expand Down
9 changes: 4 additions & 5 deletions src/components/Header/UserIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { Avatar } from '@patternfly/react-core/dist/dynamic/components/Avatar';
import { useSelector } from 'react-redux';
import { ReduxState } from '../../redux/store';

import ImgAvatar from '../../../static/images/img_avatar.svg';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

const UserIcon = () => {
const username = useSelector(({ chrome }: ReduxState) => chrome.user?.identity.user?.username);
const auth = useContext(ChromeAuthContext);
const [avatar, setAvatar] = useState(ImgAvatar);

const getImage = (img: HTMLImageElement) => {
Expand All @@ -17,7 +16,7 @@ const UserIcon = () => {

useEffect(() => {
const img = new Image();
img.src = `https://access.redhat.com/api/users/avatar/${username}/`;
img.src = `https://access.redhat.com/api/users/avatar/${auth.user.identity.user?.username ?? ''}/`;
img.onload = () => getImage(img);
}, []);

Expand Down
77 changes: 57 additions & 20 deletions src/components/IDPChecker/IDPChecker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { act } from 'react-dom/test-utils';
import configureStore from 'redux-mock-store';
import * as utils from '../../utils/common';
import IDPChecker from './IDPChecker';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

jest.mock('../../utils/common', () => {
const utils = jest.requireActual('../../utils/common');
Expand Down Expand Up @@ -48,11 +49,20 @@ describe('<IDPChecker />', () => {
ITLessSpy.mockReturnValueOnce(false);
const store = mockStore(initialState);
const { container, queryAllByTestId } = render(
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
<ChromeAuthContext.Provider
value={{
ready: true,
user: {
foo: 'bar',
},
}}
>
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
</ChromeAuthContext.Provider>
);

expect(queryAllByTestId('foo')).toHaveLength(1);
Expand All @@ -69,11 +79,20 @@ describe('<IDPChecker />', () => {

await act(async () => {
render(
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
<ChromeAuthContext.Provider
value={{
ready: true,
user: {
foo: 'bar',
},
}}
>
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
</ChromeAuthContext.Provider>
);
});

Expand All @@ -94,11 +113,20 @@ describe('<IDPChecker />', () => {

await act(async () => {
render(
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
<ChromeAuthContext.Provider
value={{
ready: true,
user: {
foo: 'bar',
},
}}
>
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
</ChromeAuthContext.Provider>
);
});

Expand All @@ -111,11 +139,20 @@ describe('<IDPChecker />', () => {

await act(async () => {
render(
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
<ChromeAuthContext.Provider
value={{
ready: true,
user: {
foo: 'bar',
},
}}
>
<Provider store={store}>
<IDPChecker>
<span data-testid="foo">OK</span>
</IDPChecker>
</Provider>
</ChromeAuthContext.Provider>
);
});

Expand Down
9 changes: 5 additions & 4 deletions src/components/IDPChecker/IDPChecker.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { Fragment, useEffect, useRef, useState } from 'react';
import React, { Fragment, useContext, useEffect, useRef, useState } from 'react';
import axios from 'axios';
import { useSelector } from 'react-redux';

import { ITLess } from '../../utils/common';
import IDPError from '../ErrorComponents/IDPError';
import { ReduxState } from '../../redux/store';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

const IDPStatuses = {
OK: 'OK',
Expand All @@ -22,11 +23,11 @@ const IDPChecker: React.FunctionComponent<React.PropsWithChildren> = ({ children
}
return IDPStatuses.OK;
});
const hasUser = useSelector(({ chrome: { user } }: ReduxState) => Object.keys(user || {}).length > 0);
const auth = useContext(ChromeAuthContext);
const allowStateChange = useRef(ITLessEnv);

useEffect(() => {
if (ITLessEnv && status !== IDPStatuses.PENDING && hasUser) {
if (ITLessEnv && status !== IDPStatuses.PENDING && auth.ready) {
allowStateChange.current && setStatus(IDPStatuses.PENDING);
axios
.get('/api/entitlements/v1/services')
Expand All @@ -38,7 +39,7 @@ const IDPChecker: React.FunctionComponent<React.PropsWithChildren> = ({ children
allowStateChange.current && setStatus(authError ? IDPStatuses.ERROR : IDPStatuses.OK);
});
}
}, [hasUser, missingIDP]);
}, [auth.ready, missingIDP]);

useEffect(() => {
if (missingIDP === true) {
Expand Down
6 changes: 4 additions & 2 deletions src/components/NotificationsDrawer/DrawerPanelContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { PopoverPosition } from '@patternfly/react-core/dist/dynamic/components/Popover';
import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon';
import { Badge } from '@patternfly/react-core/dist/dynamic/components/Badge';
Expand Down Expand Up @@ -28,6 +28,7 @@ import { NotificationData, ReduxState } from '../../redux/store';
import NotificationItem from './NotificationItem';
import { markAllNotificationsAsRead, markAllNotificationsAsUnread, toggleNotificationsDrawer } from '../../redux/actions';
import { filterConfig } from './notificationDrawerUtils';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

export type DrawerPanelProps = {
innerRef: React.Ref<unknown>;
Expand Down Expand Up @@ -63,7 +64,8 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => {
const navigate = useNavigate();
const dispatch = useDispatch();
const notifications = useSelector(({ chrome: { notifications } }: ReduxState) => notifications?.data || []);
const isOrgAdmin = useSelector(({ chrome }: ReduxState) => chrome.user?.identity.user?.is_org_admin);
const auth = useContext(ChromeAuthContext);
const isOrgAdmin = auth?.user?.identity?.user?.is_org_admin;

useEffect(() => {
const modifiedNotifications = (activeFilters || []).reduce(
Expand Down
65 changes: 41 additions & 24 deletions src/components/QuickStart/useQuickstartsStates.stage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Provider } from 'react-redux';
import * as axios from 'axios';

import useQuickstartsStates from './useQuickstartsStates';
import ChromeAuthContext from '../../auth/ChromeAuthContext';

jest.mock('axios', () => {
const axios = jest.requireActual('axios');
Expand All @@ -26,34 +27,35 @@ jest.mock('../../utils/common', () => {
};
});

describe('useQuickstartsStates stage', () => {
const getSpy = jest.spyOn(axios.default, 'get');
const postSpy = jest.spyOn(axios.default, 'post');
const accountStore = createStore(() => ({
chrome: {
user: {
identity: {
internal: {
account_id: 666,
},
},
const mockChromeContextValue = {
user: {
identity: {
internal: {
account_id: 666,
},
},
}));
},
ready: true,
};

const emptyStore = createStore(() => ({
chrome: {
user: undefined,
},
}));
const emptyStore = createStore(() => ({}));
const WrapperComponent = ({ children, store = emptyStore, contextValue = mockChromeContextValue }) => (
<ChromeAuthContext.Provider value={contextValue}>
<Provider store={store}>{children}</Provider>
</ChromeAuthContext.Provider>
);

describe('useQuickstartsStates stage', () => {
const getSpy = jest.spyOn(axios.default, 'get');
const postSpy = jest.spyOn(axios.default, 'post');

afterEach(() => {
getSpy.mockReset();
postSpy.mockReset();
});

test('should not call API if no account Id exists', () => {
const wrapper = ({ children }) => <Provider store={emptyStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent contextValue={{ ready: false, user: {} }}>{children}</WrapperComponent>;

const { result } = renderHook(() => useQuickstartsStates(), { wrapper });

Expand All @@ -64,7 +66,7 @@ describe('useQuickstartsStates stage', () => {
test('should call quickstarts progress API if account id exists', async () => {
getSpy.mockImplementationOnce(() => Promise.resolve({ data: { data: [] } }));

const wrapper = ({ children }) => <Provider store={accountStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent>{children}</WrapperComponent>;
let result;
await act(async () => {
const { result: resultInternal } = renderHook(() => useQuickstartsStates(), { wrapper });
Expand All @@ -91,7 +93,7 @@ describe('useQuickstartsStates stage', () => {
})
);

const wrapper = ({ children }) => <Provider store={accountStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent>{children}</WrapperComponent>;
let result;
await act(async () => {
const { result: resultInternal } = renderHook(() => useQuickstartsStates(), { wrapper });
Expand All @@ -108,7 +110,7 @@ describe('useQuickstartsStates stage', () => {
});

test('should set active quickstart id', () => {
const wrapper = ({ children }) => <Provider store={emptyStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent>{children}</WrapperComponent>;

const { result } = renderHook(() => useQuickstartsStates(), { wrapper });

Expand All @@ -119,7 +121,7 @@ describe('useQuickstartsStates stage', () => {
});

test('should set quickstarts states from object', () => {
const wrapper = ({ children }) => <Provider store={emptyStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent>{children}</WrapperComponent>;

const { result } = renderHook(() => useQuickstartsStates(), { wrapper });

Expand All @@ -130,7 +132,7 @@ describe('useQuickstartsStates stage', () => {
});

test('should set quickstarts states from function', async () => {
const wrapper = ({ children }) => <Provider store={emptyStore}>{children}</Provider>;
const wrapper = ({ children }) => <WrapperComponent>{children}</WrapperComponent>;

const { result } = renderHook(() => useQuickstartsStates(), { wrapper });

Expand All @@ -147,7 +149,22 @@ describe('useQuickstartsStates stage', () => {
progress: 'updated-state',
})
);
const wrapper = ({ children }) => <Provider store={emptyStore}>{children}</Provider>;
const wrapper = ({ children }) => (
<WrapperComponent
contextValue={{
ready: true,
user: {
identity: {
internal: {
account_id: NaN,
},
},
},
}}
>
{children}
</WrapperComponent>
);

const { result } = renderHook(() => useQuickstartsStates(), { wrapper });

Expand Down
Loading

0 comments on commit 995742d

Please sign in to comment.