Skip to content

Commit

Permalink
test: Create unit tests for application (TT-1681) (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
MariusLevang authored Sep 3, 2024
1 parent 98d9938 commit dfeb2f9
Show file tree
Hide file tree
Showing 22 changed files with 3,054 additions and 72 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci_pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
echo "CATALOGUE_API_PATH=${{ secrets.CATALOGUE_STAGE_API_PATH }}" >> $GITHUB_ENV
fi
- name: Run unit tests
run: npm run test

- name: Build application
run: npm run build

Expand Down
54 changes: 54 additions & 0 deletions __tests__/app/[id]/create/page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {beforeEach, expect, test, vi} from 'vitest';
import {render, screen} from '@testing-library/react';
import Page from '@/app/[id]/create/page';
import {fetchNewspaperTitleFromCatalog} from '@/services/catalog.data';
import {MockCatalogTitle1} from '../../../mockdata';
import * as localData from '@/services/local.data';
import {getLocalTitle, postLocalTitle} from '@/services/local.data';
import {NotFoundError} from '@/models/Errors';


beforeEach(() => {
vi.mocked(fetchNewspaperTitleFromCatalog).mockImplementation(() => Promise.resolve(MockCatalogTitle1));
vi.mocked(getLocalTitle).mockImplementation(() => Promise.reject(new NotFoundError('Title not found')));
vi.mocked(postLocalTitle).mockImplementation(() => Promise.resolve(new Response()));
render(<Page params={{id: ''}}/>);
});

test('Create title page has title', async () => {
await screen.findByText(MockCatalogTitle1.name);
expect(screen.getByText(MockCatalogTitle1.name)).toBeTruthy();
});

test('Create title page has form', async () => {
await screen.findByText('Kontaktinformasjon');
expect(screen.getByText('Navn')).toBeTruthy();
expect(screen.getByText('Avleverer')).toBeTruthy();
expect(screen.getByText('E-post')).toBeTruthy();
expect(screen.getByText('Telefon')).toBeTruthy();

expect(screen.getByText('Utgivelsesmønster')).toBeTruthy();
expect(screen.getByText('Hyllesignatur')).toBeTruthy();
expect(screen.getByText('Merknad/kommentar')).toBeTruthy();
expect(screen.getByText('Lagre')).toBeTruthy();
});

test('Create title page saves on button press', async () => {
const postSpy = vi.spyOn(localData, 'postLocalTitle');
expect(postSpy).not.toHaveBeenCalled();

(await screen.findByRole('button', {name: 'Lagre'})).click();
await vi.waitFor(() => expect(postSpy).toHaveBeenCalled());
});

test('Create title page displays error message when database is unavailable for post', async () => {
vi.mocked(postLocalTitle).mockImplementation(() => Promise.reject(new Error('')));

(await screen.findByText('Lagre')).click();
await vi.waitFor(() => expect(screen.getByText('Noe gikk galt ved lagring.', {exact: false})).toBeTruthy());
});

test('Create title page has button to return', async () => {
await screen.findByRole('button', {name: 'Tilbake til titteloversikt'});
expect(screen.getByRole('button', {name: 'Tilbake til titteloversikt'})).toBeTruthy();
});
69 changes: 69 additions & 0 deletions __tests__/app/[id]/page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {beforeEach, expect, test, vi} from 'vitest';
import {render, screen} from '@testing-library/react';
import Page from '@/app/[id]/page';
import {fetchNewspaperTitleFromCatalog} from '@/services/catalog.data';
import {MockBox1, MockCatalogTitle1, MockNewspaper1, MockTitle} from '../../mockdata';
import {getBoxForTitle, getLocalTitle, getNewspapersForBoxOnTitle} from '@/services/local.data';
import {NotFoundError} from '@/models/Errors';

beforeEach(() => {
vi.mocked(fetchNewspaperTitleFromCatalog).mockImplementation(() => Promise.resolve(MockCatalogTitle1));
vi.mocked(getLocalTitle).mockImplementation(() => Promise.resolve(MockTitle));
vi.mocked(getBoxForTitle).mockImplementation(() => Promise.resolve(MockBox1));
vi.mocked(getNewspapersForBoxOnTitle).mockImplementation(() => Promise.resolve([MockNewspaper1]));
render(<Page params={{id: ''}}/>);
});

test('Title page has title', async () => {
await screen.findByText(MockCatalogTitle1.name);
});

test('Title page displays loading text', () => {
expect(screen.getByText('Henter kontakt- og utgivelsesinformasjon...')).toBeTruthy();
});

test('Title page displays shelf', async () => {
await screen.findByText('Hyllesignatur:');
expect(screen.findByText(MockTitle.shelf!)).toBeTruthy();
});

test('Title page displays contact info', async () => {
await screen.findByText('Kontaktinformasjon:');
expect(screen.findByText(MockTitle.contact_name!)).toBeTruthy();
expect(screen.findByText(MockTitle.contact_email!)).toBeTruthy();
expect(screen.findByText(MockTitle.contact_phone!)).toBeTruthy();
expect(screen.findByText(MockTitle.vendor!)).toBeTruthy();
});

test('Title page displays release pattern', async () => {
await screen.findByText('Utgivelsesmønster:');
expect(screen.findByText('Mandag:')).toBeTruthy();
expect(screen.findByText('Tirsdag:')).toBeTruthy();
expect(screen.findByText('Onsdag:')).toBeTruthy();
expect(screen.findByText('Torsdag:')).toBeTruthy();
expect(screen.findByText('Fredag:')).toBeTruthy();
expect(screen.findByText('Lørdag:')).toBeTruthy();
expect(screen.findByText('Søndag:')).toBeTruthy();
});

test('Title page displays notes', async () => {
await screen.findByText('Merknad/kommentar på tittel:');
expect(screen.getByText(MockTitle.notes!)).toBeTruthy();
});

test('Title page displays issues', async () => {
await screen.findByText('Dag');
expect(screen.findByText('Dato')).toBeTruthy();
expect(screen.findByText('Nummer')).toBeTruthy();
expect(screen.findByText('Mottatt')).toBeTruthy();
expect(screen.findByText('Kommentar')).toBeTruthy();
expect(screen.findByText('Legg til ny utgave')).toBeTruthy();
});

test('Title page displays option to add info if newspaper not present in local db', async () => {
vi.mocked(getLocalTitle).mockImplementation(() => Promise.reject(new NotFoundError('Title not found')));
render(<Page params={{id: 'asd'}}/>);

await screen.findByText('Legg til informasjon');
expect(screen.findByText('Fant ikke kontakt- og utgivelsesinformasjon for denne tittelen. Ønsker du å legge til?')).toBeTruthy();
});
16 changes: 16 additions & 0 deletions __tests__/app/page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {beforeEach, expect, test} from 'vitest';
import {render, screen} from '@testing-library/react';
import Home from '@/app/page';


beforeEach(() => {
render(<Home/>);
});

test('Startpage has hugin logo', () => {
expect(screen.getByAltText('Hugin logo')).toBeTruthy();
});

test('Startpage has search bar', () => {
expect(screen.getByRole('combobox', { name: 'Søk etter avistittel', })).toBeTruthy();
});
8 changes: 8 additions & 0 deletions __tests__/components/ActiveLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {expect, test} from 'vitest';
import {render, screen} from '@testing-library/react';
import ActiveLabel from '@/components/ActiveLabel';

test('ActiveLabel renders with text', () => {
render(<ActiveLabel/>);
expect(screen.getByText('Aktiv')).toBeTruthy();
});
36 changes: 36 additions & 0 deletions __tests__/components/BoxRegistrationModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {beforeEach, expect, test, vi} from 'vitest';
import * as localData from '@/services/local.data';
import {getBoxById, postNewBoxForTitle} from '@/services/local.data';
import {fireEvent, render, screen} from '@testing-library/react';
import BoxRegistrationModal from '@/components/BoxRegistrationModal';
import {MockBox1} from '../mockdata';

beforeEach(() => {
vi.mocked(getBoxById).mockImplementation(() => Promise.resolve(MockBox1));
vi.mocked(postNewBoxForTitle).mockImplementation(() => Promise.resolve(MockBox1));
render(<BoxRegistrationModal text={'boxText'} titleId='123' titleName='title' closeModal={() => {}} updateBoxInfo={() => {}}/>);
});

test('Box registration has field for box id', () => {
expect(screen.getByRole('textbox', {name: 'Eske id'})).toBeTruthy();
});

test('Box registration has calendar for start date', () => {
expect(screen.getAllByText('1.')).toBeTruthy();
expect(screen.getAllByText('2.')).toBeTruthy();
expect(screen.getByText('9.')).toBeTruthy();
expect(screen.getByText('16.')).toBeTruthy();
expect(screen.getByText('21.')).toBeTruthy();
expect(screen.getByText('22.')).toBeTruthy();
expect(screen.getAllByText('28.')).toBeTruthy();
});

test('Box registration saves on button press', async () => {
const saveSpy = vi.spyOn(localData, 'postNewBoxForTitle');
expect(saveSpy).not.toHaveBeenCalled();

fireEvent.change(screen.getByRole('textbox', {name: 'Eske id'}), {target: {value: '123'}});
screen.getByRole('button', {name: 'Lagre ny eske'}).click();

await vi.waitFor(() => expect(saveSpy).toHaveBeenCalled());
});
73 changes: 73 additions & 0 deletions __tests__/components/ContactAndReleaseInfo.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {beforeEach, expect, test, vi} from 'vitest';
import {cleanup, render, screen} from '@testing-library/react';
import ContactAndReleaseInfo from '@/components/ContactAndReleaseInfo';
import {MockTitle} from '../mockdata';


beforeEach(() => {
render(<ContactAndReleaseInfo titleFromDb={MockTitle} onSubmit={() => Promise.resolve(new Response())} />);
});

test('Contact and release does not open in edit mode', () => {
expect(screen.getByText('Kontaktinformasjon', {exact: false})).toBeTruthy();
expect(screen.getByText('Avleverer:', {exact: false})).toBeTruthy();
expect(screen.getByText('Kontaktperson:', {exact: false})).toBeTruthy();
expect(screen.getByText('E-post:', {exact: false})).toBeTruthy();
expect(screen.getByText('Telefon:', {exact: false})).toBeTruthy();

expect(screen.queryByRole('textbox', {name: 'Avleverer'})).toBeNull();
expect(screen.queryByRole('textbox', {name: 'Navn'})).toBeNull();
expect(screen.queryByRole('textbox', {name: 'E-post'})).toBeNull();
expect(screen.queryByRole('textbox', {name: 'Telefon'})).toBeNull();
});

test('Contact and release can be edited after button press', async () => {
screen.getByRole('button', {name: 'Rediger'}).click();
await vi.waitFor(() => screen.getByRole('textbox', {name: 'Avleverer'}));

expect(screen.getByRole('textbox', {name: 'Avleverer'})).toBeTruthy();
expect(screen.getByRole('textbox', {name: 'Navn'})).toBeTruthy();
expect(screen.getByRole('textbox', {name: 'E-post'})).toBeTruthy();
expect(screen.getByRole('textbox', {name: 'Telefon'})).toBeTruthy();
});

test('Contact and release shows success on successful button press', async () => {
screen.getByRole('button', {name: 'Rediger'}).click();
await vi.waitFor(() => screen.getByRole('textbox', {name: 'Avleverer'}));

screen.getByRole('button', {name: 'Lagre'}).click();
await vi.waitFor(() => screen.getByText('Kontakt- og utgivelsesinformasjon lagret!'));
});

test('Contact and release should have release pattern', async () => {
expect(screen.getByText('Mandag:')).toBeTruthy();
expect(screen.getByText('Tirsdag:')).toBeTruthy();
expect(screen.getByText('Onsdag:')).toBeTruthy();
expect(screen.getByText('Torsdag:')).toBeTruthy();
expect(screen.getByText('Fredag:')).toBeTruthy();
expect(screen.getByText('Lørdag:')).toBeTruthy();
expect(screen.getByText('Søndag:')).toBeTruthy();

screen.getByRole('button', {name: 'Rediger'}).click();
await vi.waitFor(() => screen.getByRole('heading', {name: 'Utgivelsesmønster:'}));
expect(screen.getAllByRole('gridcell', {name: '1'})).toBeTruthy();
expect(screen.getAllByRole('gridcell', {name: '0'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Mandag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Tirsdag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Onsdag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Torsdag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Fredag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Lørdag'})).toBeTruthy();
expect(screen.getByRole('rowheader', {name: 'Søndag'})).toBeTruthy();
});

test('Contact and release should show error message on unsuccessful submit', async () => {
cleanup();
render(<ContactAndReleaseInfo titleFromDb={MockTitle} onSubmit={() => Promise.reject(new Response())} />);

screen.getByRole('button', {name: 'Rediger'}).click();
await vi.waitFor(() => screen.getByRole('textbox', {name: 'Avleverer'}));

screen.getByRole('button', {name: 'Lagre'}).click();
await vi.waitFor(() => screen.getByText('Noe gikk galt ved lagring', {exact: false}));
});
44 changes: 44 additions & 0 deletions __tests__/components/EditTextInput.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {beforeEach, expect, test, vi} from 'vitest';
import {render, screen} from '@testing-library/react';
import EditTextInput from '@/components/EditTextInput';
import { userEvent } from '@testing-library/user-event';

beforeEach(() => {
render(<EditTextInput name='navn' value='verdi' onSubmit={() => Promise.resolve(new Response('', {status: 200}))} onSuccess={() => {}}/>);
});

test('EditTextInput does not open in edit mode', () => {
expect(screen.getByText('navn:')).toBeTruthy();
expect(screen.getByText('verdi')).toBeTruthy();

expect(screen.queryByRole('textbox')).toBeNull();
});

test('EditTextInput can be edited after button press', async () => {
screen.getByRole('button').click();
await vi.waitFor(() => expect(screen.getByRole('textbox')).toBeTruthy());
});

test('EditTextInput shows success and exit edit mode on successful button press', async () => {
screen.getByRole('button').click();
await vi.waitFor(() => expect(screen.getByRole('textbox')).toBeTruthy());

// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
await userEvent.type(screen.getByRole('textbox'), ' ny');

screen.getByTestId('save-button').click();
await vi.waitFor(() => expect(screen.getByText('Lagret!')).toBeTruthy());
expect(screen.queryByRole('textbox')).toBeNull();
expect(screen.getByText('verdi ny')).toBeTruthy();
});

test('EditTextInput should abort new changes when abort button is pressed', async () => {
screen.getByRole('button').click();
await vi.waitFor(() => expect(screen.getByRole('textbox')).toBeTruthy());

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
await userEvent.keyboard('trøkk');

screen.getByTestId('abort-button').click();
await vi.waitFor(() => expect(screen.queryByRole('textbox')).toBeNull());
});
33 changes: 33 additions & 0 deletions __tests__/components/ErrorModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {beforeEach, expect, test, vi} from 'vitest';
import {render, screen} from '@testing-library/react';
import ErrorModal from '@/components/ErrorModal';
import {userEvent} from '@testing-library/user-event';


beforeEach(() => {
render(<ErrorModal text='Feilmelding'/>);
});

test('ErrorModal should render with text and button', () => {
expect(screen.getByText('Feilmelding', {exact: false})).toBeTruthy();
expect(screen.getByText('Kontakt tekst-teamet', {exact: false})).toBeTruthy();
expect(screen.getByText('dersom problemet vedvarer', {exact: false})).toBeTruthy();
expect(screen.getByRole('button', {name: 'Lukk'})).toBeTruthy();
});

test('ErrorModal should close when button is pressed', async () => {
screen.getByRole('button', {name: 'Lukk'}).click();
await vi.waitFor(() => expect(screen.queryByText('Feilmelding', {exact: false})).toBeNull());
});

test('ErrorModal should close when escape is pressed', async () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
await userEvent.keyboard('{Escape}');
await vi.waitFor(() => expect(screen.queryByText('Feilmelding', {exact: false})).toBeNull());
});

test('ErrorModal should close when outside is clicked', async () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
await userEvent.click(document.body);
await vi.waitFor(() => expect(screen.queryByText('Feilmelding', {exact: false})).toBeNull());
});
21 changes: 21 additions & 0 deletions __tests__/components/Header.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {beforeEach, expect, test} from 'vitest';
import {render, screen} from '@testing-library/react';
import Header from '@/components/Header';

beforeEach(() => {
render(<Header/>);
});

test('Header should have logo and Hugin-text', () => {
expect(screen.getByText('Hugin')).toBeTruthy();
expect(screen.getByAltText('Hugin logo')).toBeTruthy();
expect(screen.getByRole('img')).toBeTruthy();
});

test('Header should have login button', () => {
expect(screen.getByText('Logg inn')).toBeTruthy();
});

test('Header should not as default not show search bar', () => {
expect(screen.queryByRole('searchbox')).toBeFalsy();
});
Loading

0 comments on commit dfeb2f9

Please sign in to comment.