Skip to content

Commit

Permalink
(test) Fix most test warnings
Browse files Browse the repository at this point in the history
This PR cleans up most of the test warnings in the Jest terminal output. This includes:

- Fixing single spa errors from incorrectly mocked modules
- Fixing validateDOMNesting warnings
- Removing unnecessary mocks for dependencies like react-hook-form
  • Loading branch information
denniskigen committed Nov 27, 2024
1 parent c8d3f06 commit 5be309e
Show file tree
Hide file tree
Showing 47 changed files with 553 additions and 438 deletions.
2 changes: 2 additions & 0 deletions __mocks__/appointments.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,12 @@ export const mockProviders = {
{
uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66',
person: { uuid: '24252571-dd5a-11e6-9d9c-0242ac150002', display: 'Dr James Cook' },
display: 'doctor - James Cook',
},
{
uuid: '3191eddf-5cc5-4fa4-94ef-dfc25e8d33e4',
person: { uuid: '89af8ba6-2ec5-4d77-b3ed-7e9e02448e96', display: 'Dr Amstrong Neil' },
display: 'doctor - Amstrong Neil',
},
],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import React from 'react';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { formatDate } from '@openmrs/esm-framework';
import { useVisit } from './visit.resource';
import VisitDetailComponent from './visit-detail.component';

const mockUseVisit = jest.mocked(useVisit);
const defaultProps = {
patientUuid: '691eed12-c0f1-11e2-94be-8c13b969e334',
visitUuid: '497b8b17-54ec-4726-87ec-3c4da8cdcaeb',
};
const mockUseVisit = jest.mocked(useVisit);

jest.mock('./visit.resource');
jest.mock('./visit.resource', () => ({
...jest.requireActual('./visit.resource'),
useVisit: jest.fn(),
}));

describe('VisitDetail', () => {
it('renders a loading spinner when data is loading', () => {
mockUseVisit.mockReturnValueOnce({
mockUseVisit.mockReturnValue({
visit: null,
error: undefined,
isLoading: true,
Expand All @@ -29,7 +31,8 @@ describe('VisitDetail', () => {

it('renders a visit detail overview when data is available', () => {
const mockVisitDate = new Date();
mockUseVisit.mockReturnValueOnce({

mockUseVisit.mockReturnValue({
visit: {
encounters: [],
startDatetime: mockVisitDate.toISOString(),
Expand All @@ -43,13 +46,14 @@ describe('VisitDetail', () => {

render(<VisitDetailComponent {...defaultProps} />);

expect(screen.getByText(/Some Visit Type/)).toBeInTheDocument();
expect(screen.getByText(formatDate(mockVisitDate), { collapseWhitespace: false })).toBeInTheDocument();
expect(screen.getByText('All Encounters')).toBeInTheDocument();
expect(screen.getByText('Visit Summary')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /some visit type/i })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /no encounters found/i })).toBeInTheDocument();
expect(screen.getByText(/there is no information to display here/i)).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /all encounters/i })).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /visit summary/i })).toBeInTheDocument();
});

it('render the Encounter Lists view when the "All Encounters" tab is clicked', async () => {
it('renders the Encounter Lists view when the "All Encounters" tab is clicked', async () => {
const user = userEvent.setup();

mockUseVisit.mockReturnValue({
Expand All @@ -74,8 +78,12 @@ describe('VisitDetail', () => {

render(<VisitDetailComponent {...defaultProps} />);

await user.click(screen.getByText('All Encounters'));
expect(screen.getByTestId('encountersTable')).toBeInTheDocument();
await user.click(screen.getByRole('tab', { name: /all encounters/i }));
expect(screen.getByRole('table')).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /time/i })).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /encounter type/i })).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /provider/i })).toBeInTheDocument();
expect(screen.getByRole('row', { name: /12:34 pm encounter type/i })).toBeInTheDocument();
});

it('renders the Visit Summaries view when the "Visit Summary" tab is clicked', async () => {
Expand Down Expand Up @@ -112,7 +120,12 @@ describe('VisitDetail', () => {

render(<VisitDetailComponent {...defaultProps} />);

await user.click(screen.getByText('Visit Summary'));
expect(screen.getByRole('tablist', { name: 'Visit summary tabs' })).toBeInTheDocument();
await user.click(screen.getByRole('tab', { name: /visit summary/i }));
expect(screen.getByRole('tablist', { name: /visit summary tabs/i })).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /notes/i })).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /tests/i })).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /medications/i })).toBeInTheDocument();
expect(screen.getByText(/no diagnoses found/i)).toBeInTheDocument();
expect(screen.getByText(/there are no notes to display for this patient/i)).toBeInTheDocument();
});
});
16 changes: 8 additions & 8 deletions packages/esm-appointments-app/src/appointments.component.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { omrsDateFormat } from './constants';
import AppointmentTabs from './appointments/appointment-tabs.component';
import AppointmentsHeader from './header/appointments-header.component';
import AppointmentMetrics from './metrics/appointments-metrics.component';
import { useParams } from 'react-router-dom';
import SelectedDateContext from './hooks/selectedDateContext';
import { omrsDateFormat } from './constants';

const Appointments: React.FC = () => {
const Appointments = () => {
const { t } = useTranslation();
const [appointmentServiceType, setAppointmentServiceType] = useState<string>('');
const [selectedDate, setSelectedDate] = useState<string>(dayjs().startOf('day').format(omrsDateFormat));
const [appointmentServiceType, setAppointmentServiceType] = useState('');
const [selectedDate, setSelectedDate] = useState(dayjs().startOf('day').format(omrsDateFormat));

let params = useParams();
const params = useParams();

useEffect(() => {
if (params.date) {
Expand All @@ -30,9 +30,9 @@ const Appointments: React.FC = () => {
return (
<SelectedDateContext.Provider value={{ selectedDate, setSelectedDate }}>
<AppointmentsHeader
title={t('appointments', 'Appointments')}
appointmentServiceType={appointmentServiceType}
onChange={setAppointmentServiceType}
title={t('appointments', 'Appointments')}
/>
<AppointmentMetrics appointmentServiceType={appointmentServiceType} />
<AppointmentTabs appointmentServiceType={appointmentServiceType} />
Expand Down
14 changes: 11 additions & 3 deletions packages/esm-appointments-app/src/appointments.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import Appointments from './appointments.component';

// TODO: Tweak the ExtensionSlot stub in the framework to not return a function. Functions are not valid React children.
describe('Appointments', () => {
it('renders the appointments dashboard', async () => {
render(<Appointments />);

await screen.findByText(/^appointments$/i);

expect(screen.getByRole('button', { name: /appointments calendar/i })).toBeInTheDocument();
expect(screen.getByPlaceholderText(/dd-mmm-yyyy/i)).toBeInTheDocument();
screen.getByRole('combobox', {
name: /select service type/i,
});
expect(
screen.getByRole('combobox', {
name: /select service type/i,
}),
).toBeInTheDocument();
expect(screen.getByRole('listbox', { name: /view/i })).toBeInTheDocument();
expect(screen.getByText(/appointment metrics/i)).toBeInTheDocument();
expect(screen.getByText(/scheduled appointments/i)).toBeInTheDocument();
expect(screen.getByText(/highest volume service/i)).toBeInTheDocument();
expect(screen.getByText(/providers booked/i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ interface AppointmentTabsProps {

const AppointmentTabs: React.FC<AppointmentTabsProps> = ({ appointmentServiceType }) => {
const { t } = useTranslation();
const [activeTabIndex, setActiveTabIndex] = useState<number>(0);
const { showUnscheduledAppointmentsTab } = useConfig<ConfigObject>();
const [activeTabIndex, setActiveTabIndex] = useState(0);

const handleTabChange = ({ selectedIndex }: { selectedIndex: number }) => {
setActiveTabIndex(selectedIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import { type ConfigObject } from '../../config-schema';
import { getPageSizes, useAppointmentSearchResults } from '../utils';
import AppointmentActions from './appointments-actions.component';
import AppointmentDetails from '../details/appointment-details.component';
import PatientSearch from '../../patient-search/patient-search.component';
import styles from './appointments-table.scss';

dayjs.extend(utc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ const mockAppointments = [
},
] as unknown as Array<Appointment>;

const mockExportAppointmentsToSpreadsheet = jest.mocked(exportAppointmentsToSpreadsheet);
const mockUseConfig = jest.mocked(useConfig<ConfigObject>);
const mockExportAppointmentsToSpreadsheet = jest.mocked(exportAppointmentsToSpreadsheet);

jest.mock('../../helpers/excel', () => {
return {
...jest.requireActual('../../helpers/excel'),
exportAppointmentsToSpreadsheet: jest.fn(),
};
});

jest.mock('../../helpers/excel');
jest.mock('../../hooks/useOverlay');
// jest.mock('../../hooks/useOverlay');

describe('AppointmentsTable', () => {
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const ScheduledAppointments: React.FC<ScheduledAppointmentsProps> = ({ appointme
// t('checkedIn', 'Checked in');
// t('expected', 'Expected');

const [currentTab, setCurrentTab] = useState<string>(null);
const [currentTab, setCurrentTab] = useState(null);
const [dateType, setDateType] = useState<DateType>('today');
const scheduledAppointmentPanels = useConnectedExtensions(scheduledAppointmentsPanelsSlot);
const { allowedExtensions, showExtension, hideExtension } = useAllowedExtensions();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Button,
DataTable,
TableContainer,
DataTableSkeleton,
Pagination,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableHeader,
TableRow,
TableBody,
TableCell,
TableToolbar,
TableToolbarContent,
TableToolbarSearch,
Pagination,
DataTableSkeleton,
Button,
} from '@carbon/react';
import { Download } from '@carbon/react/icons';
import { ConfigurableLink, useConfig, usePagination } from '@openmrs/esm-framework';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
import { type ConfigObject, configSchema } from '../../config-schema';
import { exportUnscheduledAppointmentsToSpreadsheet } from '../../helpers/excel';
import { getByTextWithMarkup } from 'tools';
import { useUnscheduledAppointments } from '../../hooks/useUnscheduledAppointments';
import { exportUnscheduledAppointmentsToSpreadsheet } from '../../helpers/excel';
import UnscheduledAppointments from './unscheduled-appointments.component';

const mockExportUnscheduledAppointmentsToSpreadsheet = jest.mocked(exportUnscheduledAppointmentsToSpreadsheet);
const mockUseUnscheduledAppointments = jest.mocked(useUnscheduledAppointments);
const mockUseConfig = jest.mocked(useConfig<ConfigObject>);

jest.mock('../../helpers/excel');
jest.mock('../../hooks/useOverlay');
jest.mock('../../hooks/useUnscheduledAppointments');
jest.mock('../../helpers/excel', () => {
return {
...jest.requireActual('../../helpers/excel'),
exportUnscheduledAppointmentsToSpreadsheet: jest.fn(),
};
});

jest.mock('../../hooks/useUnscheduledAppointments', () => {
return {
...jest.requireActual('../../hooks/useUnscheduledAppointments'),
useUnscheduledAppointments: jest.fn(),
};
});

const mockUnscheduledAppointments = [
{
Expand Down Expand Up @@ -45,6 +55,11 @@ describe('UnscheduledAppointments', () => {
...getDefaultsFromConfigSchema(configSchema),
customPatientChartUrl: 'someUrl',
});
mockUseUnscheduledAppointments.mockReturnValue({
isLoading: false,
data: mockUnscheduledAppointments,
error: null,
});
});

it('renders the component correctly', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import React, { useEffect, useState } from 'react';
import dayjs from 'dayjs';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { omrsDateFormat } from '../constants';
import { useAppointmentsCalendar } from '../hooks/useAppointmentsCalendar';
import AppointmentsHeader from '../header/appointments-header.component';
import CalendarHeader from './header/calendar-header.component';
import MonthlyCalendarView from './monthly/monthly-calendar-view.component';
import SelectedDateContext from '../hooks/selectedDateContext';
import { omrsDateFormat } from '../constants';

const AppointmentsCalendarView: React.FC = () => {
const { t } = useTranslation();
const [selectedDate, setSelectedDate] = useState<string>(dayjs().startOf('day').format(omrsDateFormat));
const [selectedDate, setSelectedDate] = useState(dayjs().startOf('day').format(omrsDateFormat));
const { calendarEvents } = useAppointmentsCalendar(dayjs(selectedDate).toISOString(), 'monthly');

let params = useParams();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const MonthlyWorkloadView: React.FC<MonthlyWorkloadViewProps> = ({ dateTime, eve
},
)}>
{isSameMonth(dateTime, dayjs(selectedDate)) && (
<p>
<div>
<span className={classNames(styles.totals)}>
{currentData?.services ? (
<div role="button" tabIndex={0}>
Expand Down Expand Up @@ -100,7 +100,7 @@ const MonthlyWorkloadView: React.FC<MonthlyWorkloadViewProps> = ({ dateTime, eve
)}
</div>
)}
</p>
</div>
)}
</div>
);
Expand Down
Loading

0 comments on commit 5be309e

Please sign in to comment.