Skip to content

Commit

Permalink
vitest corrections (#3978)
Browse files Browse the repository at this point in the history
* vitest fixes.

* re-install moment-timezone.

* remove only modifier

* snapshot update.

* skip failing test.

* vitest performance and mocking corrections.

* ensure console warnings are treated as failures.

* try skipping troublesome test.

* acquisition file owners.
  • Loading branch information
devinleighsmith authored Apr 30, 2024
1 parent 415021e commit 649aa4e
Show file tree
Hide file tree
Showing 30 changed files with 480 additions and 240 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/app-react.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
- run: npm run build --if-present
working-directory: ${{env.working-directory}}

- run: npm run coverage -- --maxWorkers=2
- run: npm run coverage -- --bail 1 --maxWorkers 1 --minWorkers 1
working-directory: ${{env.working-directory}}
env:
REACT_APP_TENANT: MOTI
Expand Down
17 changes: 15 additions & 2 deletions source/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions source/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"happy-dom": "14.7.1",
"husky": "6.0.0",
"jest-styled-components": "7.2.0",
"moment-timezone": "0.5.45",
"msw": "1.0.1",
"prettier": "2.7.1",
"pretty": "2.0.0",
Expand All @@ -117,7 +118,7 @@
"vite-plugin-svgr": "4.2.0",
"vite-tsconfig-paths": "4.2.3",
"vitest": "1.5.0",
"vitest-fail-on-console": "^0.6.3",
"vitest-fail-on-console": "0.6.3",
"vitest-sonar-reporter": "2.0.0"
},
"overrides": {
Expand All @@ -137,10 +138,10 @@
"start": "vite",
"build": "tsc && vite build",
"serve": "vite preview",
"test": "tsc && vitest run",
"test-u": "tsc && vitest run -u",
"test": "tsc && vitest run --reporter=default",
"test-u": "tsc && vitest run -u --reporter=default",
"test:watch": "vitest watch",
"coverage": "vitest run --coverage --reporter=vitest-sonar-reporter",
"coverage": "vitest run --coverage",
"update-snapshots": "vitest run -u",
"eject": "react-scripts eject",
"lint": "eslint src/ --ext .jsx,.js,.ts,.tsx --max-warnings 0",
Expand Down
81 changes: 56 additions & 25 deletions source/frontend/src/AppRouter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ import { tenantsSlice } from './store/slices/tenants';
import { defaultTenant } from './tenants/config/defaultTenant';
import {
act,
mockKeycloak,
flushPromises,
prettyDOM,
render,
renderAsync,
RenderOptions,
screen,
waitFor,
} from './utils/test-utils';
import { renderDate } from './components/Table';
import { vi } from 'vitest';
import { useApiTenants } from './hooks/pims-api/useApiTenants';

vi.mock('axios');
const mockedAxios = vi.mocked(axios);
Expand All @@ -59,6 +60,9 @@ vi.mock('react', () => {
return React as any;
});

vi.mock('./hooks/pims-api/useApiTenants');
vi.mocked(useApiTenants).mockImplementation(() => ({ getSettings: jest.fn() }));

// Need to mock this library for unit tests
vi.mock('react-visibility-sensor', () => {
return {
Expand Down Expand Up @@ -209,7 +213,7 @@ vi.mock('react-visibility-sensor', () => {
});

describe('PSP routing', () => {
const setup = (url = '/', renderOptions: RenderOptions = {}) => {
const setup = async (url = '/', renderOptions: RenderOptions = {}) => {
history.replace(url);

const defaultUserInfo = {
Expand Down Expand Up @@ -237,7 +241,7 @@ describe('PSP routing', () => {
initialized: true,
}));

const utils = render(
const utils = await renderAsync(
<AuthStateContext.Provider value={{ ready: true }}>
<AppRouter />
</AuthStateContext.Provider>,
Expand All @@ -254,6 +258,7 @@ describe('PSP routing', () => {

beforeEach(() => {
vi.mocked(mockedAxios.get).mockResolvedValue({ data: {}, status: 200 });
vi.unmock('@/components/common/mapFSM/MapStateMachineContext');
});

afterEach(() => {
Expand All @@ -262,89 +267,115 @@ describe('PSP routing', () => {

describe('public routes', () => {
it('should redirect unauthenticated user to the login page', async () => {
const { getByText } = setup('/');
await waitFor(async () => {
await setup('/');
});
await screen.findByText('v1.0.0.0');
expect(getByText('Sign into PIMS with your government issued IDIR')).toBeVisible();
expect(screen.getByText('Sign into PIMS with your government issued IDIR')).toBeVisible();
});

it('should show header and footer links', async () => {
const { getByRole } = setup('/');
await waitFor(async () => {
await setup('/');
});
await screen.findByText('v1.0.0.0');
expect(getByRole('link', { name: 'Disclaimer' })).toHaveAttribute(
expect(screen.getByRole('link', { name: 'Disclaimer' })).toHaveAttribute(
'href',
'http://www.gov.bc.ca/gov/content/home/disclaimer',
);
});

it('should show a page for non-supported browsers', async () => {
const { getByText } = setup('/ienotsupported');
await waitFor(async () => {
await setup('/ienotsupported');
});
await screen.findByText('v1.0.0.0');
expect(
getByText('Please use a supported internet browser such as Chrome, Firefox or Edge.'),
screen.getByText(
'Please use a supported internet browser such as Chrome, Firefox or Edge.',
),
).toBeVisible();
});

it('should show the access denied page', async () => {
const { getByText, getByRole } = setup('/forbidden');
await waitFor(async () => {
await setup('/forbidden');
});
await screen.findByText('v1.0.0.0');
expect(getByText('You do not have permission to view this page')).toBeVisible();
expect(getByRole('link', { name: 'Go back to the map' })).toBeVisible();
expect(screen.getByText('You do not have permission to view this page')).toBeVisible();
expect(screen.getByRole('link', { name: 'Go back to the map' })).toBeVisible();
});

it.each(['/page-not-found', '/fake-url'])(
'should show the not found page when route is %s',
async url => {
const { getByText, getByRole } = setup(url);
await waitFor(async () => {
await setup(url);
});
await screen.findByText('v1.0.0.0');
expect(getByText('Page not found')).toBeVisible();
expect(getByRole('link', { name: 'Go back to the map' })).toBeVisible();
expect(screen.getByText('Page not found')).toBeVisible();
expect(screen.getByRole('link', { name: 'Go back to the map' })).toBeVisible();
},
);
});

describe('authenticated routes', () => {
it('should display the property list view', async () => {
setup('/properties/list', { claims: [Claims.PROPERTY_VIEW] });
await act(async () => {
await setup('/properties/list', { claims: [Claims.PROPERTY_VIEW] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByText('Civic Address');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/View Inventory/i);
await waitFor(async () => {
const lazyElement = await screen.findByText('Civic Address');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/View Inventory/i);
});
});

it('should display the lease list view', async () => {
setup('/lease/list', { claims: [Claims.LEASE_VIEW] });
await act(async () => {
await setup('/lease/list', { claims: [Claims.LEASE_VIEW] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByText('l-1234');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/View Lease & Licenses/i);
});

it('should display the acquisition list view', async () => {
setup('/acquisition/list', { claims: [Claims.ACQUISITION_VIEW] });
await act(async () => {
await setup('/acquisition/list', { claims: [Claims.ACQUISITION_VIEW] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByText('test acq file');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/View Acquisition Files/i);
});

it('should display the research list view', async () => {
setup('/research/list', { claims: [Claims.RESEARCH_VIEW] });
await act(async () => {
await setup('/research/list', { claims: [Claims.RESEARCH_VIEW] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByText('test research file');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/View Research Files/i);
});

it('should display the admin users page at the expected route', async () => {
setup('/admin/users', { claims: [Claims.ADMIN_USERS] });
await act(async () => {
await setup('/admin/users', { claims: [Claims.ADMIN_USERS] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByText('Smith');
expect(lazyElement).toBeInTheDocument();
expect(document.title).toMatch(/Users Management/i);
});

it('should display the edit user page at the expected route', async () => {
setup('/admin/user/1', { claims: [Claims.ADMIN_USERS] });
await act(async () => {
await setup('/admin/user/1', { claims: [Claims.ADMIN_USERS] });
});
await screen.findByText('v1.0.0.0');
const lazyElement = await screen.findByDisplayValue('Smith');

Expand Down
2 changes: 1 addition & 1 deletion source/frontend/src/components/common/buttons/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classnames from 'classnames';
import React, { CSSProperties, forwardRef, MouseEventHandler } from 'react';
import { CSSProperties, forwardRef, MouseEventHandler } from 'react';
import BootstrapButton, { ButtonProps as BootstrapButtonProps } from 'react-bootstrap/Button';
import Spinner from 'react-bootstrap/Spinner';
import styled from 'styled-components';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useFormikContext } from 'formik';
import React, { useState } from 'react';
import { useState } from 'react';

import { RestrictContactType } from '@/components/contact/ContactManagerView/ContactFilterComponent/ContactFilterComponent';
import { IContactSearchResult } from '@/interfaces/IContactSearchResult';
Expand Down
2 changes: 1 addition & 1 deletion source/frontend/src/components/common/form/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import { getIn, useFormikContext } from 'formik';
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import Form from 'react-bootstrap/Form';
import { FormControlProps } from 'react-bootstrap/FormControl';
import { CSSProperties } from 'styled-components';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { RenderOptions, cleanup, mockKeycloak, render } from '@/utils/test-utils

import Header from './Header';

vi.mock('@/store/slices/tenants/useTenants');
vi.mock('@/store/slices/tenants');
(useTenants as any).mockImplementation(() => ({
getSettings: vi.fn(),
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,28 +274,7 @@ exports[`AdvancedFilterButton > renders as expected 1`] = `
href="https://leafletjs.com"
title="A JavaScript library for interactive maps"
>
<svg
aria-hidden="true"
class="leaflet-attribution-flag"
height="8"
viewBox="0 0 12 8"
width="12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0h12v4H0z"
fill="#4C7BE1"
/>
<path
d="M0 4h12v3H0z"
fill="#FFD500"
/>
<path
d="M0 7h12v1H0z"
fill="#E0BC00"
/>
</svg>
Leaflet
Leaflet
</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,28 +269,7 @@ exports[`LayersControl View > renders correctly 1`] = `
href="https://leafletjs.com"
title="A JavaScript library for interactive maps"
>
<svg
aria-hidden="true"
class="leaflet-attribution-flag"
height="8"
viewBox="0 0 12 8"
width="12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0h12v4H0z"
fill="#4C7BE1"
/>
<path
d="M0 4h12v3H0z"
fill="#FFD500"
/>
<path
d="M0 7h12v1H0z"
fill="#E0BC00"
/>
</svg>
Leaflet
Leaflet
</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,28 +155,7 @@ exports[`LayersMenu View > renders as expected 1`] = `
href="https://leafletjs.com"
title="A JavaScript library for interactive maps"
>
<svg
aria-hidden="true"
class="leaflet-attribution-flag"
height="8"
viewBox="0 0 12 8"
width="12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0h12v4H0z"
fill="#4C7BE1"
/>
<path
d="M0 4h12v3H0z"
fill="#FFD500"
/>
<path
d="M0 7h12v1H0z"
fill="#E0BC00"
/>
</svg>
Leaflet
Leaflet
</a>
</div>
</div>
Expand Down
Loading

0 comments on commit 649aa4e

Please sign in to comment.