From 3e3b12c5243bf09d8070976ab250dfe8b190265a Mon Sep 17 00:00:00 2001 From: Johnny Bouder Date: Wed, 3 Jul 2024 11:23:21 -0400 Subject: [PATCH] Fix sso issues and unit tests. --- src/hooks/use-auth-sso.test.tsx | 137 +++++++++++--------------------- src/hooks/use-auth.ts | 39 +++++---- 2 files changed, 64 insertions(+), 112 deletions(-) diff --git a/src/hooks/use-auth-sso.test.tsx b/src/hooks/use-auth-sso.test.tsx index 50a4e63..9dfee30 100644 --- a/src/hooks/use-auth-sso.test.tsx +++ b/src/hooks/use-auth-sso.test.tsx @@ -7,24 +7,19 @@ interface ContextWrapperProps { } vi.mock('react-oidc-context', () => ({ - useAuth: vi.fn().mockImplementation(() => ({ - signinRedirect: vi.fn().mockResolvedValue(true), - signoutRedirect: vi.fn().mockResolvedValue(true), + useAuth: () => ({ isAuthenticated: true, + isLoading: false, user: { profile: undefined, }, - })), -})); - -vi.mock('@src/utils/auth', () => ({ - getSignInRedirectUrl: vi.fn(() => 'mocked-redirect-url'), // Replace with the expected URL + signinRedirect: vi.fn(), + signoutRedirect: vi.fn(), + }), })); describe('useAuth', () => { - const OLD_ENV = process.env; - beforeEach(() => { - process.env = { ...OLD_ENV }; + afterEach(() => { vi.clearAllMocks(); }); @@ -32,7 +27,7 @@ describe('useAuth', () => { {children} ); - test('should call signIn with SSO and no configs', async () => { + it('should set isSignedIn to true when authenticated with sso', async () => { const { result } = renderHook(() => useAuth(), { wrapper: contextWrapper, }); @@ -40,103 +35,61 @@ describe('useAuth', () => { await act(async () => { result.current.signIn(true); }); - expect(result.current.signIn).toBeTruthy(); - }); - test('should call signIn with SSO and available configs', async () => { - process.env.SSO_AUTHORITY = 'http://localhost'; - process.env.SSO_CLIENT_ID = 'dev-client'; + expect(result.current.isSignedIn).toBe(true); + }); + it('should set isSignedIn to true when authenticated without sso', () => { const { result } = renderHook(() => useAuth(), { wrapper: contextWrapper, }); - await act(async () => { - result.current.signIn(true); + act(() => { + result.current.signIn(false); }); - expect(result.current.signIn).toBeTruthy(); + + expect(result.current.isSignedIn).toBe(true); }); - it('should set isSignedIn to true when authenticated with sso', () => { + it('should sign out and set isSignedIn to false when authenticated', () => { const { result } = renderHook(() => useAuth(), { wrapper: contextWrapper, }); act(() => { + result.current.signOut(); + }); + + expect(result.current.isSignedIn).toBe(false); + }); + + it('should set isSignedIn to true when authenticated and with profile', async () => { + vi.mock('react-oidc-context', () => ({ + useAuth: () => ({ + isAuthenticated: true, + isLoading: false, + user: { + profile: { + firstName: 'John', + lastName: 'Doe', + displayName: 'John Doe', + emailAddress: 'jdoe@test.com', + phoneNumber: '1234567890', + }, + }, + signinRedirect: vi.fn(), + signoutRedirect: vi.fn(), + }), + })); + + const { result } = renderHook(() => useAuth(), { + wrapper: contextWrapper, + }); + + await act(async () => { result.current.signIn(true); }); expect(result.current.isSignedIn).toBe(true); }); - - // it('should not authenticated with sso and error', () => { - // vi.mock('react-oidc-context', () => ({ - // useAuth: vi.fn().mockImplementation(() => ({ - // signinRedirect: vi.fn().mockRejectedValue(true), - // signoutRedirect: vi.fn(), - // isAuthenticated: false, - // })), - // })); - // const { result } = renderHook(() => useAuth(), { - // wrapper: contextWrapper, - // }); - - // act(() => { - // result.current.signIn(true); - // }); - - // expect(result.current.isSignedIn).toBe(true); - // }); - - // it('should set isSignedIn to true when authenticated without sso', () => { - // const { result } = renderHook(() => useAuth(), { - // wrapper: contextWrapper, - // }); - - // act(() => { - // result.current.signIn(false); - // }); - - // expect(result.current.isSignedIn).toBe(true); - // }); - - // it('should sign out and set isSignedIn to false when authenticated', () => { - // const { result } = renderHook(() => useAuth(), { - // wrapper: contextWrapper, - // }); - - // act(() => { - // result.current.signOut(); - // }); - - // expect(result.current.isSignedIn).toBe(false); - // }); - - // it('should set isSignedIn to true when authenticated and with profile', () => { - // vi.mock('react-oidc-context', () => ({ - // useAuth: vi.fn().mockImplementation(() => ({ - // signinRedirect: vi.fn().mockResolvedValue(true), - // signoutRedirect: vi.fn().mockResolvedValue(true), - // isAuthenticated: true, - // user: { - // profile: { - // firstName: 'John', - // lastName: 'Doe', - // displayName: 'John Doe', - // emailAddress: 'jdoe@test.com', - // phoneNumber: '1234567890', - // }, - // }, - // })), - // })); - // const { result } = renderHook(() => useAuth(), { - // wrapper: contextWrapper, - // }); - - // act(() => { - // result.current.signIn(false); - // }); - - // expect(result.current.isSignedIn).toBe(true); - // }); }); diff --git a/src/hooks/use-auth.ts b/src/hooks/use-auth.ts index ce903d4..fe03ac1 100644 --- a/src/hooks/use-auth.ts +++ b/src/hooks/use-auth.ts @@ -11,7 +11,7 @@ const useAuth = () => { const [isSignedIn, setIsSignedIn] = useRecoilState(signedIn); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(); - const [currentUserData, setCurrentUserDate] = useRecoilState< + const [currentUserData, setCurrentUserData] = useRecoilState< User | undefined >(currentUser); @@ -32,12 +32,12 @@ const useAuth = () => { useEffect(() => { setIsLoading(auth.isLoading); - }, [auth.isLoading, setIsSignedIn]); + }, [auth.isLoading, setIsLoading]); useEffect(() => { const profile = auth.user?.profile; - if (profile) { - setCurrentUserDate({ + if (profile && !currentUserData) { + setCurrentUserData({ firstName: profile.given_name, lastName: profile.family_name, displayName: profile.name, @@ -45,35 +45,34 @@ const useAuth = () => { phoneNumber: profile.phone_number, }); } - }, [auth.user?.profile, setCurrentUserDate]); + }, [auth.user?.profile, currentUserData, setCurrentUserData]); + + useEffect(() => { + if (auth.error) { + setError(auth.error.message); + setIsSignedIn(false); + } + }, [auth.error, setIsSignedIn]); const signIn = (isSso: boolean): void => { if (isSso) { - auth - .signinRedirect({ redirect_uri: getSignInRedirectUrl() }) - .catch((err) => { - setError(err); - }); + auth.signinRedirect({ redirect_uri: getSignInRedirectUrl() }); } else { setIsSignedIn(true); - setCurrentUserDate(userData); + setCurrentUserData(userData); } }; const signOut = (): void => { setIsSignedIn(false); - setCurrentUserDate({} as User); + setCurrentUserData({} as User); if (auth.isAuthenticated) { - auth - .signoutRedirect({ - post_logout_redirect_uri: getSignInRedirectUrl(), - }) - .catch((err) => { - setError(err); - }); + auth.signoutRedirect({ + post_logout_redirect_uri: getSignInRedirectUrl(), + }); } else { setIsSignedIn(false); - setCurrentUserDate({} as User); + setCurrentUserData({} as User); } };