Skip to content

Commit

Permalink
chore: add missing unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jjarvisp committed Feb 22, 2025
1 parent 8b4876c commit de9956d
Show file tree
Hide file tree
Showing 4 changed files with 472 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import * as React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';

import { useAuthenticator, UseAuthenticator } from '@aws-amplify/ui-react-core';
import { SelectMfaType } from '../SelectMfaType';
import { AuthenticatorServiceFacade } from '@aws-amplify/ui';

jest.mock('@aws-amplify/ui-react-core');

jest.mock('../../hooks/useCustomComponents', () => ({
useCustomComponents: () => ({
components: {
Header: () => null,
Footer: () => null,
SelectMfaType: { Header: () => null, Footer: () => null },
},
}),
}));

const fieldLabel = 'Select MFA Type';
const fieldInput = { name: 'mfa_type', value: 'EMAIL' };

const mockUpdateForm = jest.fn();
const mockSubmitForm = jest.fn();
const mockToSignIn = jest.fn();

const mockUseAuthenticator = jest.mocked(useAuthenticator);

const mockUseAuthenticatorOutput: Partial<UseAuthenticator> = {
authStatus: 'authenticated',
challengeName: 'SELECT_MFA_TYPE',
error: undefined as unknown as AuthenticatorServiceFacade['error'],
route: 'selectMfaType',
submitForm: mockSubmitForm,
toSignIn: mockToSignIn,
updateForm: mockUpdateForm,
allowedMfaTypes: ['EMAIL', 'TOTP'],
validationErrors: {} as AuthenticatorServiceFacade['validationErrors'],
fields: [
{
name: 'mfa_type',
label: fieldLabel,
required: true,
type: 'radio',
radioOptions: [
{
label: 'EMAIL',
value: 'EMAIL',
},
{
label: 'TOTP',
value: 'TOTP',
},
],
},
],
};

mockUseAuthenticator.mockReturnValue(mockUseAuthenticatorOutput as any);

const props = {
className: '',
variation: 'default' as const,
};

describe('SelectMfaType', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders as expected ', () => {
const mathRandomSpy = jest.spyOn(Math, 'random').mockReturnValue(0.1);

const { container } = render(<SelectMfaType {...props} />);
expect(container).toMatchSnapshot();

mathRandomSpy.mockRestore();
});

it('sends change event on form input', async () => {
render(<SelectMfaType {...props} />);

const radioButton = await screen.findByText(fieldInput.value);

fireEvent.click(radioButton);

expect(mockUpdateForm).toHaveBeenCalledWith(fieldInput);
});

it('sends submit event on form submit', async () => {
render(<SelectMfaType {...props} />);

const radioButton = await screen.findByText(fieldInput.value);

fireEvent.click(radioButton);

expect(mockUseAuthenticatorOutput.updateForm).toHaveBeenCalledWith(
fieldInput
);

const submitButton = await screen.findByRole('button', { name: 'Confirm' });
fireEvent.click(submitButton);

expect(mockSubmitForm).toHaveBeenCalledTimes(1);
});

it('displays error if present', async () => {
mockUseAuthenticator.mockReturnValue({
...mockUseAuthenticatorOutput,
error: 'mockError',
} as any);

render(<SelectMfaType {...props} />);

expect(await screen.findByText('mockError')).toBeInTheDocument();
});

it('handles back to sign in button as expected', async () => {
render(<SelectMfaType {...props} />);

const backToSignInButton = await screen.findByRole('button', {
name: 'Back to Sign In',
});

fireEvent.click(backToSignInButton);

expect(mockToSignIn).toHaveBeenCalledTimes(1);
});

it('disables the submit button if confirmation is pending', async () => {
mockUseAuthenticator.mockReturnValue({
...mockUseAuthenticatorOutput,
isPending: true,
} as any);

render(<SelectMfaType {...props} />);

const submitButton = await screen.findByRole('button', {
name: 'Confirming',
});

expect(submitButton).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SelectMfaType renders as expected 1`] = `
<div>
<div
class=""
data-amplify-authenticator=""
data-variation="default"
>
<div
data-amplify-container=""
>
<div
data-amplify-router=""
>
<form
data-amplify-authenticator-select-mfa-type=""
data-amplify-form=""
method="post"
>
<fieldset
class="amplify-flex"
style="flex-direction: column;"
>
<div
class="amplify-flex"
style="flex-direction: column;"
>
<fieldset
class="amplify-flex amplify-fieldset amplify-fieldset--plain amplify-field amplify-radiogroupfield"
label="Select MFA Type"
required=""
role="radiogroup"
>
<legend
class="amplify-visually-hidden"
>
Select MFA Type
</legend>
<div
aria-hidden="true"
class="amplify-fieldset__legend"
>
Select MFA Type
</div>
<div
class="amplify-flex amplify-radiogroup"
id="amplify-id-:r1:"
>
<label
class="amplify-flex amplify-radio"
>
<span
class="amplify-text amplify-radio__label"
>
EMAIL
</span>
<input
aria-invalid="false"
class="amplify-input amplify-field-group__control amplify-visually-hidden amplify-radio__input"
name="mfa_type"
type="radio"
value="EMAIL"
/>
<span
aria-hidden="true"
class="amplify-flex amplify-radio__button"
/>
</label>
<label
class="amplify-flex amplify-radio"
>
<span
class="amplify-text amplify-radio__label"
>
TOTP
</span>
<input
aria-invalid="false"
class="amplify-input amplify-field-group__control amplify-visually-hidden amplify-radio__input"
name="mfa_type"
type="radio"
value="TOTP"
/>
<span
aria-hidden="true"
class="amplify-flex amplify-radio__button"
/>
</label>
</div>
</fieldset>
</div>
<div
class="amplify-flex"
style="flex-direction: column;"
>
<button
class="amplify-button amplify-field-group__control amplify-button--primary"
type="submit"
>
Confirm
</button>
<button
class="amplify-button amplify-field-group__control amplify-button--link amplify-button--small"
type="button"
>
Back to Sign In
</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';

import { useAuthenticator, UseAuthenticator } from '@aws-amplify/ui-react-core';
import { SetupEmail } from '../SetupEmail';
import { AuthenticatorServiceFacade } from '@aws-amplify/ui';

jest.mock('@aws-amplify/ui-react-core');

jest.mock('../../hooks/useCustomComponents', () => ({
useCustomComponents: () => ({
components: {
Header: () => null,
Footer: () => null,
SetupEmail: { Header: () => null, Footer: () => null },
},
}),
}));

const fieldLabel = 'Seteup Email';
const fieldInput = { name: 'email', value: '[email protected]' };

const mockUpdateForm = jest.fn();
const mockSubmitForm = jest.fn();
const mockToSignIn = jest.fn();

const mockUseAuthenticator = jest.mocked(useAuthenticator);

const mockUseAuthenticatorOutput: Partial<UseAuthenticator> = {
authStatus: 'authenticated',
challengeName: 'MFA_SETUP',
error: undefined as unknown as AuthenticatorServiceFacade['error'],
route: 'setupEmail',
submitForm: mockSubmitForm,
toSignIn: mockToSignIn,
updateForm: mockUpdateForm,
validationErrors: {} as AuthenticatorServiceFacade['validationErrors'],
fields: [
{
name: 'email',
label: fieldLabel,
required: true,
type: 'email',
},
],
};

mockUseAuthenticator.mockReturnValue(mockUseAuthenticatorOutput as any);

const props = {
className: '',
variation: 'default' as const,
};

describe('SetupEmail', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders as expected ', () => {
const mathRandomSpy = jest.spyOn(Math, 'random').mockReturnValue(0.1);

const { container } = render(<SetupEmail {...props} />);
expect(container).toMatchSnapshot();

mathRandomSpy.mockRestore();
});

it('sends change event on form input', async () => {
render(<SetupEmail {...props} />);

const emailField = await screen.findByLabelText(fieldLabel);

fireEvent.input(emailField, { target: fieldInput });

expect(mockUpdateForm).toHaveBeenCalledWith(fieldInput);
});

it('sends submit event on form submit', async () => {
render(<SetupEmail {...props} />);

const emailField = await screen.findByLabelText(fieldLabel);

fireEvent.input(emailField, { target: fieldInput });

expect(mockUpdateForm).toHaveBeenCalledWith(fieldInput);

const submitButton = await screen.findByRole('button', { name: 'Confirm' });

fireEvent.click(submitButton);

expect(mockSubmitForm).toHaveBeenCalledTimes(1);
});

it('displays error if present', async () => {
mockUseAuthenticator.mockReturnValue({
...mockUseAuthenticatorOutput,
error: 'mockError',
} as any);

render(<SetupEmail {...props} />);

expect(await screen.findByText('mockError')).toBeInTheDocument();
});

it('handles back to sign in button as expected', async () => {
render(<SetupEmail {...props} />);

const backToSignInButton = await screen.findByRole('button', {
name: 'Back to Sign In',
});

fireEvent.click(backToSignInButton);

expect(mockToSignIn).toHaveBeenCalledTimes(1);
});

it('disables the submit button if confirmation is pending', async () => {
mockUseAuthenticator.mockReturnValue({
...mockUseAuthenticatorOutput,
isPending: true,
} as any);

render(<SetupEmail {...props} />);

const submitButton = await screen.findByRole('button', {
name: 'Confirming',
});

expect(submitButton).toBeDisabled();
});
});
Loading

0 comments on commit de9956d

Please sign in to comment.