Skip to content

Commit

Permalink
Improve code coverage in `src/components/UserPortal/Register/Register…
Browse files Browse the repository at this point in the history
….tsx` (#3248)

* Improve code coverage in register.tsx

* Achieved 100% Code coverage
  • Loading branch information
hars-21 authored Jan 11, 2025
1 parent cd0f54c commit 018155d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 39 deletions.
98 changes: 66 additions & 32 deletions src/components/UserPortal/Register/Register.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { vi } from 'vitest';
* GraphQL mock data is used for testing user registration functionality.
*/

// GraphQL Mock Data
const MOCKS = [
{
request: {
Expand All @@ -54,6 +55,7 @@ const MOCKS = [
},
];

// Form Data
const formData = {
firstName: 'John',
lastName: 'Doe',
Expand All @@ -62,16 +64,26 @@ const formData = {
confirmPassword: 'johnDoe',
};

const link = new StaticMockLink(MOCKS, true);
// Additional GraphQL Mock Data for Error Handling
const ERROR_MOCKS = [
{
request: {
query: SIGNUP_MUTATION,
variables: {
firstName: 'Error',
lastName: 'Test',
email: '[email protected]',
password: 'password',
},
},
error: new Error('GraphQL error occurred'),
},
];

async function wait(ms = 100): Promise<void> {
await act(() => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
});
}
// Static Mock Link
const link = new StaticMockLink(MOCKS, true);

// Mock toast
vi.mock('react-toastify', () => ({
toast: {
success: vi.fn(),
Expand All @@ -80,12 +92,18 @@ vi.mock('react-toastify', () => ({
},
}));

// Mock setCurrentMode function
const setCurrentMode: React.Dispatch<SetStateAction<string>> = vi.fn();

// Test setup props
const props = {
setCurrentMode,
};

async function waitForAsync(): Promise<void> {
await act(() => new Promise((resolve) => setTimeout(resolve, 100)));
}

describe('Testing Register Component [User Portal]', () => {
it('Component should be rendered properly', async () => {
render(
Expand All @@ -100,7 +118,7 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();
});

it('Expect the mode to be changed to Login', async () => {
Expand All @@ -116,7 +134,7 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.click(screen.getByTestId('setLoginBtn'));

Expand All @@ -136,7 +154,7 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.click(screen.getByTestId('registerBtn'));

Expand All @@ -156,7 +174,7 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.type(screen.getByTestId('emailInput'), formData.email);
userEvent.click(screen.getByTestId('registerBtn'));
Expand All @@ -177,12 +195,10 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.type(screen.getByTestId('passwordInput'), formData.password);

userEvent.type(screen.getByTestId('emailInput'), formData.email);

userEvent.click(screen.getByTestId('registerBtn'));

expect(toast.error).toHaveBeenCalledWith('Please enter valid details.');
Expand All @@ -201,20 +217,17 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.type(screen.getByTestId('passwordInput'), formData.password);

userEvent.type(screen.getByTestId('emailInput'), formData.email);

userEvent.type(screen.getByTestId('firstNameInput'), formData.firstName);

userEvent.click(screen.getByTestId('registerBtn'));

expect(toast.error).toHaveBeenCalledWith('Please enter valid details.');
});

test("Expect toast.error to be called if confirmPassword doesn't match with password", async () => {
it("Expect toast.error to be called if confirmPassword doesn't match with password", async () => {
render(
<MockedProvider addTypename={false} link={link}>
<BrowserRouter>
Expand All @@ -227,16 +240,12 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.type(screen.getByTestId('passwordInput'), formData.password);

userEvent.type(screen.getByTestId('emailInput'), formData.email);

userEvent.type(screen.getByTestId('firstNameInput'), formData.firstName);

userEvent.type(screen.getByTestId('lastNameInput'), formData.lastName);

userEvent.click(screen.getByTestId('registerBtn'));

expect(toast.error).toHaveBeenCalledWith(
Expand All @@ -257,27 +266,52 @@ describe('Testing Register Component [User Portal]', () => {
</MockedProvider>,
);

await wait();
await waitForAsync();

userEvent.type(screen.getByTestId('passwordInput'), formData.password);

userEvent.type(
screen.getByTestId('confirmPasswordInput'),
formData.confirmPassword,
);

userEvent.type(screen.getByTestId('emailInput'), formData.email);

userEvent.type(screen.getByTestId('firstNameInput'), formData.firstName);

userEvent.type(screen.getByTestId('lastNameInput'), formData.lastName);

userEvent.click(screen.getByTestId('registerBtn'));

await wait();
await waitForAsync();

expect(toast.success).toHaveBeenCalledWith(
'Successfully registered. Please wait for admin to approve your request.',
);
});

// Error Test Case
it('Expect toast.error to be called if GraphQL mutation fails', async () => {
render(
<MockedProvider addTypename={false} mocks={ERROR_MOCKS}>
<BrowserRouter>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<Register {...props} />
</I18nextProvider>
</Provider>
</BrowserRouter>
</MockedProvider>,
);

await waitForAsync();

// Fill out the form with error-triggering values
userEvent.type(screen.getByTestId('passwordInput'), 'password');
userEvent.type(screen.getByTestId('confirmPasswordInput'), 'password');
userEvent.type(screen.getByTestId('emailInput'), '[email protected]');
userEvent.type(screen.getByTestId('firstNameInput'), 'Error');
userEvent.type(screen.getByTestId('lastNameInput'), 'Test');
userEvent.click(screen.getByTestId('registerBtn'));

await waitForAsync();

// Assert that toast.error is called with the error message
expect(toast.error).toHaveBeenCalledWith('GraphQL error occurred');
});
});
7 changes: 0 additions & 7 deletions src/components/UserPortal/Register/Register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
toast.success(t('afterRegister') as string); // Success message

// Reset form fields
/* istanbul ignore next */
setRegisterVariables({
firstName: '',
lastName: '',
Expand All @@ -86,7 +85,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
});
} catch (error: unknown) {
// Handle any errors during registration
/* istanbul ignore next */
errorHandler(t, error);
}
}
Expand All @@ -96,7 +94,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
* Updates the state with the first name input value.
* @param e - Change event from the input element
*/
/* istanbul ignore next */
const handleFirstName = (e: ChangeEvent<HTMLInputElement>): void => {
const firstName = e.target.value;
setRegisterVariables({ ...registerVariables, firstName });
Expand All @@ -106,7 +103,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
* Updates the state with the last name input value.
* @param e - Change event from the input element
*/
/* istanbul ignore next */
const handleLastName = (e: ChangeEvent<HTMLInputElement>): void => {
const lastName = e.target.value;
setRegisterVariables({ ...registerVariables, lastName });
Expand All @@ -116,7 +112,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
* Updates the state with the email input value.
* @param e - Change event from the input element
*/
/* istanbul ignore next */
const handleEmailChange = (e: ChangeEvent<HTMLInputElement>): void => {
const email = e.target.value;
setRegisterVariables({ ...registerVariables, email });
Expand All @@ -126,7 +121,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
* Updates the state with the password input value.
* @param e - Change event from the input element
*/
/* istanbul ignore next */
const handlePasswordChange = (e: ChangeEvent<HTMLInputElement>): void => {
const password = e.target.value;

Expand All @@ -137,7 +131,6 @@ export default function register(props: InterfaceRegisterProps): JSX.Element {
* Updates the state with the confirm password input value.
* @param e - Change event from the input element
*/
/* istanbul ignore next */
const handleConfirmPasswordChange = (
e: ChangeEvent<HTMLInputElement>,
): void => {
Expand Down

0 comments on commit 018155d

Please sign in to comment.