Skip to content

Commit 4394aa1

Browse files
Add tests for agent email sign-in block in BaseLoginForm
Adds two tests covering the new isAgentEmail guard in validateAndSubmitForm: one verifies the error message appears and beginSignIn is not called for agent emails, the other verifies normal emails proceed to sign-in as expected. Co-authored-by: Nicolás Bonet <NicolasBonet@users.noreply.github.com>
1 parent be0c849 commit 4394aa1

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

tests/ui/BaseLoginFormTest.tsx

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import type * as ReactNavigationNative from '@react-navigation/native';
2+
import {fireEvent, render, screen, waitFor} from '@testing-library/react-native';
3+
import React from 'react';
4+
import Onyx from 'react-native-onyx';
5+
import {LoginProvider} from '@pages/signin/SignInLoginContext';
6+
import {beginSignIn} from '@userActions/Session';
7+
import ONYXKEYS from '@src/ONYXKEYS';
8+
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
9+
10+
jest.mock('@react-navigation/native', () => {
11+
const actualNav = jest.requireActual<typeof ReactNavigationNative>('@react-navigation/native');
12+
return {
13+
...actualNav,
14+
useIsFocused: () => true,
15+
};
16+
});
17+
18+
const AGENT_ERROR = "Agent accounts can't be signed into directly. To use an agent, sign in with your own account and access it via Copilot.";
19+
const INVALID_EMAIL_ERROR = 'The email entered is invalid. Please fix the format and try again.';
20+
21+
jest.mock('@hooks/useLocalize', () =>
22+
jest.fn(() => ({
23+
translate: jest.fn((key: string) => {
24+
switch (key) {
25+
case 'loginForm.error.agentSignInBlocked':
26+
return AGENT_ERROR;
27+
case 'loginForm.error.invalidFormatEmailLogin':
28+
return INVALID_EMAIL_ERROR;
29+
case 'loginForm.phoneOrEmail':
30+
return 'Phone or email';
31+
case 'loginForm.loginForm':
32+
return 'Login form';
33+
case 'common.continue':
34+
return 'Continue';
35+
case 'common.signInWith':
36+
return 'Sign in with';
37+
case 'common.pleaseEnterEmailOrPhoneNumber':
38+
return 'Please enter an email or phone number';
39+
default:
40+
return key;
41+
}
42+
}),
43+
numberFormat: jest.fn(),
44+
})),
45+
);
46+
47+
jest.mock('@hooks/useResponsiveLayout', () =>
48+
jest.fn(() => ({
49+
shouldUseNarrowLayout: false,
50+
isInNarrowPaneModal: false,
51+
})),
52+
);
53+
54+
jest.mock('@userActions/Session', () => ({
55+
beginSignIn: jest.fn(),
56+
clearAccountMessages: jest.fn(),
57+
clearSignInData: jest.fn(),
58+
}));
59+
60+
jest.mock('@userActions/CloseAccount', () => ({
61+
setDefaultData: jest.fn(),
62+
}));
63+
64+
// Use require to get the default export after all jest.mock calls are hoisted
65+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
66+
const BaseLoginForm = require('@pages/signin/LoginForm/BaseLoginForm').default;
67+
68+
const mockBeginSignIn = beginSignIn as jest.MockedFunction<typeof beginSignIn>;
69+
70+
function renderForm() {
71+
return render(
72+
<LoginProvider>
73+
<BaseLoginForm isVisible />
74+
</LoginProvider>,
75+
);
76+
}
77+
78+
describe('BaseLoginForm', () => {
79+
beforeAll(() => {
80+
Onyx.init({keys: ONYXKEYS});
81+
});
82+
83+
beforeEach(async () => {
84+
jest.clearAllMocks();
85+
await Onyx.set(ONYXKEYS.ACCOUNT, {
86+
isLoading: false,
87+
errors: null,
88+
});
89+
await waitForBatchedUpdates();
90+
});
91+
92+
it('shows agent sign-in blocked error when an agent email is entered', async () => {
93+
renderForm();
94+
95+
const input = screen.getByTestId('username');
96+
fireEvent.changeText(input, 'agent_123@expensify.ai');
97+
98+
const continueButton = screen.getByText('Continue');
99+
fireEvent.press(continueButton);
100+
101+
await waitFor(() => {
102+
expect(screen.getByText(AGENT_ERROR)).toBeTruthy();
103+
});
104+
expect(mockBeginSignIn).not.toHaveBeenCalled();
105+
});
106+
107+
it('proceeds with sign-in for a normal email', async () => {
108+
renderForm();
109+
110+
const input = screen.getByTestId('username');
111+
fireEvent.changeText(input, 'user@expensify.com');
112+
113+
const continueButton = screen.getByText('Continue');
114+
fireEvent.press(continueButton);
115+
116+
await waitFor(() => {
117+
expect(mockBeginSignIn).toHaveBeenCalledWith('user@expensify.com');
118+
});
119+
});
120+
});

0 commit comments

Comments
 (0)