Skip to content

Commit

Permalink
[DEV-1314] EmailFormWrapper unit tests (#581)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremygordillo authored Feb 7, 2024
1 parent 3d01f5b commit 4caeaaf
Show file tree
Hide file tree
Showing 7 changed files with 675 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/dull-swans-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-website": patch
---

Add EmailFormWrapper unit tests
10 changes: 9 additions & 1 deletion apps/nextjs-website/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { JestConfigWithTsJest } from 'ts-jest';

const jestConfig: JestConfigWithTsJest = {
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.+(ts|tsx)'],
testMatch: ['**/__tests__/**/*test.+(ts|tsx)'],
moduleFileExtensions: ['ts', 'js', 'tsx'],
testEnvironment: 'jsdom',
transform: {
// See the discussion https://github.com/vercel/next.js/issues/8663
'^.+\\.(ts|tsx)$': ['ts-jest', { tsconfig: 'tsconfig.jest.json' }],
Expand All @@ -12,6 +13,13 @@ const jestConfig: JestConfigWithTsJest = {
// Needed or else if some test files imports a file from the src folder using the Next naming convention, it will fail.
// Example: import { shared } from '@/_contents/translations'; returns Cannot find module '@/_contents/translations' from 'src/some-file.ts'
'@/(.*)': '<rootDir>/src/$1',
'^uuid$': require.resolve('uuid'),
// This configuration is used to tell Jest how to handle imports of certain file types in your tests that are not JavaScript or TypeScrip
// When Jest runs, it replaces any import of the matched file types with this mock file.
// This is useful because these static files aren't particularly relevant to the tests but are often imported by the modules you're testing.
// By mapping these imports to a mock file, you can avoid errors that might occur when Jest tries to parse these static files.
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|less)$':
'<rootDir>/src/__tests__/__mocks__/fileMock.js',
},
};

Expand Down
2 changes: 2 additions & 0 deletions apps/nextjs-website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"swiper": "^10.0.3"
},
"devDependencies": {
"@testing-library/react": "^14.1.2",
"@types/jest": "^29.5.1",
"@types/node": "18.16.*",
"@types/react": "18.2.21",
Expand All @@ -52,6 +53,7 @@
"eslint-config-custom": "*",
"eslint-config-next": "13.4.19",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.7.0",
"jest-mock-extended": "^3.0.5",
"openapi-types": "^12.1.3",
"ts-jest": "^29.1.1",
Expand Down
2 changes: 2 additions & 0 deletions apps/nextjs-website/src/__tests__/__mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line functional/immutable-data, functional/no-expression-statements
module.exports = {};
125 changes: 125 additions & 0 deletions apps/nextjs-website/src/__tests__/components/EmailFormWrapper.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { render, fireEvent } from '@testing-library/react';
import EmailFormWrapper from '@/components/organisms/EmailFormWrapper/EmailFormWrapper';
import Wrapper from './Wrapper';

describe('EmailFormWrapper', () => {
const mockOnCancel = jest.fn();
const mockOnSave = jest.fn((email: string) => Promise.resolve());
const mockOnEdit = jest.fn();

const item = {
editable: true,
name: 'email',
title: 'Email',
value: '[email protected]',
onEdit: mockOnEdit,
};

it('should render EditEmailForm when isEditing is true', () => {
const { getByRole } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={true}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

expect(getByRole('textbox')).toBeTruthy();
});

it('should render InfoCardItem when isEditing is false', () => {
const { getAllByText } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={false}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

expect(getAllByText(item.value)).toBeTruthy();
});

it('should call onEdit when edit button is clicked', () => {
const { getByRole } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={false}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

fireEvent.click(getByRole('button'));
expect(mockOnEdit).toHaveBeenCalled();
});

it('should call onCancel when cancel button is clicked', () => {
const { getAllByRole } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={true}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

fireEvent.click(getAllByRole('button', { name: /annulla/i })[0]);
expect(mockOnCancel).toHaveBeenCalled();
});

it('should not call onSave when save button is clicked and email input has not valid value', () => {
const { getByRole, getAllByRole } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={true}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

fireEvent.change(getByRole('textbox'), {
target: { value: 'updated' },
});

fireEvent.click(getAllByRole('button', { name: /conferma/i })[0]);
expect(mockOnSave).not.toHaveBeenCalled();
});

it('should call onSave when save button is clicked and email input is valid', () => {
const { getByRole, getAllByRole } = render(
<Wrapper>
<EmailFormWrapper
item={item}
isEditing={true}
onCancel={mockOnCancel}
onSave={mockOnSave}
onEdit={mockOnEdit}
/>
</Wrapper>
);

fireEvent.change(getByRole('textbox'), {
target: { value: '[email protected]' },
});

fireEvent.click(getAllByRole('button', { name: /conferma/i })[0]);
expect(mockOnSave).toHaveBeenCalled();
});
});
12 changes: 12 additions & 0 deletions apps/nextjs-website/src/__tests__/components/Wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NextIntlClientProvider } from 'next-intl';
import { PropsWithChildren } from 'react';

import messages from '@/messages/it.json';

const Wrapper = ({ children }: PropsWithChildren) => (
<NextIntlClientProvider locale={'it'} messages={messages}>
{children}
</NextIntlClientProvider>
);

export default Wrapper;
Loading

0 comments on commit 4caeaaf

Please sign in to comment.