From fbdd3053b437bcc8782d5f237218f69001c1330f Mon Sep 17 00:00:00 2001 From: Mike Allison Date: Thu, 21 May 2026 18:50:57 +0000 Subject: [PATCH 1/2] test(journeys-admin): enhance ImpersonateDialog tests with Firebase authentication mocks - Added mocks for Firebase authentication to improve test reliability. - Updated tests to verify user impersonation and session handling. - Removed unnecessary Apollo client usage in ImpersonateDialog component. --- .../ImpersonateDialog.spec.tsx | 32 +++++++++++++++++++ .../ImpersonateDialog/ImpersonateDialog.tsx | 14 +++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx index 0bca761a115..349473695f7 100644 --- a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx +++ b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx @@ -1,14 +1,34 @@ import { MockedProvider } from '@apollo/client/testing' import { fireEvent, render, waitFor } from '@testing-library/react' +import { UserCredential, signInWithCustomToken } from 'firebase/auth' import { SnackbarProvider } from 'notistack' import { USER_IMPERSONATE } from './ImpersonateDialog' import { ImpersonateDialog } from '.' +const mockLoginWithCredential = jest.fn().mockResolvedValue(undefined) + +jest.mock('firebase/auth', () => ({ + getAuth: jest.fn(() => ({})), + signInWithCustomToken: jest.fn() +})) + +jest.mock('../../../../../libs/auth', () => ({ + loginWithCredential: (...args: unknown[]) => mockLoginWithCredential(...args) +})) + +const mockSignInWithCustomToken = signInWithCustomToken as jest.MockedFunction< + typeof signInWithCustomToken +> + const onClose = jest.fn() describe('JourneyView/Menu/ImpersonateDialog', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + it('should not set journey impersonate on close', async () => { const { getByRole } = render( @@ -27,6 +47,9 @@ describe('JourneyView/Menu/ImpersonateDialog', () => { }) it('should impersonate user on submit', async () => { + const credential = { user: {} } as unknown as UserCredential + mockSignInWithCustomToken.mockResolvedValue(credential) + const result = jest.fn(() => ({ data: { userImpersonate: 'accessToken' @@ -59,6 +82,15 @@ describe('JourneyView/Menu/ImpersonateDialog', () => { await waitFor(() => { expect(result).toHaveBeenCalled() }) + // signs in as the impersonated user, then refreshes the server-side + // session cookie so SSR runs as that user (otherwise journey edits 403) + await waitFor(() => { + expect(mockSignInWithCustomToken).toHaveBeenCalledWith( + {}, + 'accessToken' + ) + }) + expect(mockLoginWithCredential).toHaveBeenCalledWith(credential) }) it('shows notistack error alert when impersonate fails to update', async () => { diff --git a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.tsx b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.tsx index c8a0c31a960..7bfd78ce425 100644 --- a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.tsx +++ b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.tsx @@ -1,4 +1,4 @@ -import { ApolloError, gql, useApolloClient, useMutation } from '@apollo/client' +import { ApolloError, gql, useMutation } from '@apollo/client' import Alert from '@mui/material/Alert' import AlertTitle from '@mui/material/AlertTitle' import TextField from '@mui/material/TextField' @@ -15,6 +15,7 @@ import { UserImpersonate, UserImpersonateVariables } from '../../../../../../__generated__/UserImpersonate' +import { loginWithCredential } from '../../../../../libs/auth' export const USER_IMPERSONATE = gql` mutation UserImpersonate($email: String!) { @@ -35,7 +36,6 @@ export function ImpersonateDialog({ UserImpersonate, UserImpersonateVariables >(USER_IMPERSONATE) - const client = useApolloClient() const { enqueueSnackbar } = useSnackbar() const { t } = useTranslation('apps-journeys-admin') @@ -51,8 +51,14 @@ export function ImpersonateDialog({ }) if (data?.userImpersonate != null) { const auth = getAuth() - await signInWithCustomToken(auth, data.userImpersonate) - await client.resetStore() + const credential = await signInWithCustomToken( + auth, + data.userImpersonate + ) + // Refresh the server-side session cookie so SSR (e.g. the journey + // editor) runs as the impersonated user rather than the superuser. + // loginWithCredential reloads the page once the cookie is set. + await loginWithCredential(credential) } handleClose(formikHelpers.resetForm)() } catch (error) { From b59db6d059c8068502f284f0c2aaef1c215352ec Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 18:58:02 +0000 Subject: [PATCH 2/2] fix: lint issues --- .../ImpersonateDialog/ImpersonateDialog.spec.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx index 349473695f7..f005a1c6ead 100644 --- a/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx +++ b/apps/journeys-admin/src/components/PageWrapper/NavigationDrawer/UserNavigation/ImpersonateDialog/ImpersonateDialog.spec.tsx @@ -85,10 +85,7 @@ describe('JourneyView/Menu/ImpersonateDialog', () => { // signs in as the impersonated user, then refreshes the server-side // session cookie so SSR runs as that user (otherwise journey edits 403) await waitFor(() => { - expect(mockSignInWithCustomToken).toHaveBeenCalledWith( - {}, - 'accessToken' - ) + expect(mockSignInWithCustomToken).toHaveBeenCalledWith({}, 'accessToken') }) expect(mockLoginWithCredential).toHaveBeenCalledWith(credential) })