Skip to content

Commit

Permalink
(test) Add renderWithRouter wrapper (#1373)
Browse files Browse the repository at this point in the history
This adds a wrapper for rendering components with react-router-dom for testing purposes. This is needed
 because components that use routing features require a Router context to work properly. Its parameters are:

 - component: The component to render.
 - initialRoute: The initial route to set for the router. Defaults to `/`, the root path.

It uses `MemoryRouter` instead of `BrowserRouter` because `MemoryRouter` stores its history in memory, which is
suitable for testing purposes.

 - initialEntries: The initial entries to set for the router. Defaults to `['/']`, the root path.
 - it sets up a basic Routes configuration with a single Route that matches the root path and renders the component passed to the wrapper.
  • Loading branch information
denniskigen authored Nov 14, 2024
1 parent e009969 commit 7fc67b1
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithRouter } from 'tools';
import { Autosuggest } from './autosuggest.component';

const mockPersons = [
Expand Down Expand Up @@ -33,18 +33,16 @@ const mockHandleSuggestionSelected = jest.fn((field, value) => [field, value]);

describe('Autosuggest', () => {
it('renders a search box', () => {
render(
<BrowserRouter>
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>
</BrowserRouter>,
renderWithRouter(
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>,
);

expect(screen.getByRole('searchbox')).toBeInTheDocument();
Expand All @@ -54,18 +52,16 @@ describe('Autosuggest', () => {
it('renders matching search results in a list when the user types a query', async () => {
const user = userEvent.setup();

render(
<BrowserRouter>
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>
</BrowserRouter>,
renderWithRouter(
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>,
);

const searchbox = screen.getByRole('searchbox');
Expand All @@ -82,18 +78,16 @@ describe('Autosuggest', () => {
it('clears the list of suggestions when a suggestion is selected', async () => {
const user = userEvent.setup();

render(
<BrowserRouter>
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>
</BrowserRouter>,
renderWithRouter(
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>,
);

let list = screen.queryByRole('list');
Expand All @@ -117,18 +111,16 @@ describe('Autosuggest', () => {
it('changes suggestions when a search input is changed', async () => {
const user = userEvent.setup();

render(
<BrowserRouter>
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>
</BrowserRouter>,
renderWithRouter(
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>,
);

let list = screen.queryByRole('list');
Expand All @@ -149,18 +141,16 @@ describe('Autosuggest', () => {
it('hides the list of suggestions when the user clicks outside of the component', async () => {
const user = userEvent.setup();

render(
<BrowserRouter>
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>
</BrowserRouter>,
renderWithRouter(
<Autosuggest
getSearchResults={mockGetSearchResults}
getDisplayValue={(item) => item.display}
getFieldValue={(item) => item.uuid}
id="person"
labelText=""
onSuggestionSelected={mockHandleSuggestionSelected}
placeholder="Find Person"
/>,
);

const input = screen.getByRole('searchbox');
Expand Down
1 change: 1 addition & 0 deletions tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export {
mockPatientWithoutFormattedName,
patientChartBasePath,
renderWithSwr,
renderWithRouter,
waitForLoadingToFinish,
} from './test-utils';
16 changes: 14 additions & 2 deletions tools/test-utils.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Route, Routes, MemoryRouter } from 'react-router-dom';
import React, { type ReactElement } from 'react';
import { SWRConfig } from 'swr';
import { type RenderOptions, render, screen, waitForElementToBeRemoved } from '@testing-library/react';
Expand All @@ -17,6 +18,16 @@ const swrWrapper = ({ children }) => {
const renderWithSwr = (ui: ReactElement, options?: Omit<RenderOptions, 'queries'>) =>
render(ui, { wrapper: swrWrapper, ...options });

const renderWithRouter = (component: React.ReactElement, initialRoute = '/') => {
return render(
<MemoryRouter initialEntries={[initialRoute]}>
<Routes>
<Route path="/" element={component} />
</Routes>
</MemoryRouter>,
);
};

function waitForLoadingToFinish() {
return waitForElementToBeRemoved(() => [...screen.queryAllByRole('progressbar')], {
timeout: 4000,
Expand Down Expand Up @@ -141,12 +152,13 @@ const mockPatientWithoutFormattedName = {
const patientChartBasePath = `/patient/${mockPatient.id}/chart`;

export {
renderWithSwr,
waitForLoadingToFinish,
getByTextWithMarkup,
mockPatient,
mockOpenMRSIdentificationNumberIdType,
mockPatientWithLongName,
mockPatientWithoutFormattedName,
patientChartBasePath,
renderWithSwr,
renderWithRouter,
waitForLoadingToFinish,
};

0 comments on commit 7fc67b1

Please sign in to comment.