Skip to content

Commit

Permalink
(test) O3-4165: Add tests for lab test panel view (#2088)
Browse files Browse the repository at this point in the history
* Add tests for lab test panel view

* PR comments

* Remove translation mock

* PR comments

* Tweaks

---------

Co-authored-by: Dennis Kigen <[email protected]>
  • Loading branch information
ODORA0 and denniskigen authored Nov 11, 2024
1 parent b5ec1f3 commit 64dd1cd
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 2 deletions.
1 change: 1 addition & 0 deletions __mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './groupedResults.mock';
export * from './immunizations.mock';
export * from './location.mock';
export * from './medication.mock';
export * from './mockBasePanel.mock';
export * from './mockDeceasedPatient';
export * from './patient-flags.mock';
export * from './programs.mock';
Expand Down
105 changes: 105 additions & 0 deletions __mocks__/mockBasePanel.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { type OBSERVATION_INTERPRETATION } from '@openmrs/esm-patient-common-lib';
import { ObsRecord } from '../packages/esm-patient-tests-app/src/types';

export const mockConceptMeta = {
display: '',
hiNormal: 0,
hiAbsolute: 0,
hiCritical: 0,
lowNormal: 0,
lowAbsolute: 0,
lowCritical: 0,
units: 'g/dL',
range: '12-16',
getInterpretation: function (value: string): OBSERVATION_INTERPRETATION {
const numValue = Number(value);
if (numValue > this.hiNormal) return 'HIGH';
if (numValue < this.lowNormal) return 'LOW';
return 'NORMAL';
},
};

export const mockBasePanel: ObsRecord = {
resourceType: 'Observation',
id: 'test-id',
conceptUuid: 'test-uuid',
category: [
{
coding: [
{
system: 'test-system',
code: 'test-code',
display: 'Laboratory',
},
],
},
],
code: {
coding: [
{
code: 'test-code',
display: 'Test Display',
},
],
text: 'Test Text',
},
effectiveDateTime: '2024-01-01T10:00:00Z',
issued: '2024-01-01T10:00:00Z',
name: 'Complete Blood Count',
value: '120',
interpretation: 'NORMAL' as OBSERVATION_INTERPRETATION,
relatedObs: [],
meta: mockConceptMeta,
referenceRange: [],
};

export const mockObservations: Array<ObsRecord> = [
{
...mockBasePanel,
id: '1',
name: 'Hemoglobin',
value: '14',
interpretation: 'NORMAL' as OBSERVATION_INTERPRETATION,
meta: {
...mockConceptMeta,
units: 'g/dL',
range: '12-16',
},
},
{
...mockBasePanel,
id: '2',
name: 'Hematocrit',
value: '42',
interpretation: 'HIGH' as OBSERVATION_INTERPRETATION,
meta: {
...mockConceptMeta,
units: '%',
range: '35-45',
},
},
];

export const mockObservationsWithInterpretations: Array<ObsRecord> = [
{
...mockBasePanel,
id: '1',
name: 'Normal Test',
value: '14',
interpretation: 'NORMAL' as OBSERVATION_INTERPRETATION,
},
{
...mockBasePanel,
id: '2',
name: 'High Test',
value: '42',
interpretation: 'HIGH' as OBSERVATION_INTERPRETATION,
},
{
...mockBasePanel,
id: '3',
name: 'Low Test',
value: '2',
interpretation: 'LOW' as OBSERVATION_INTERPRETATION,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
import { type OBSERVATION_INTERPRETATION } from '@openmrs/esm-patient-common-lib';
import { type ObsRecord } from '../../types';
import { mockBasePanel, mockObservations, mockConceptMeta, mockObservationsWithInterpretations } from '__mocks__';
import LabSetPanel from './panel.component';

const mockUseLayoutType = jest.mocked(useLayoutType);
const mockIsDesktop = jest.mocked(isDesktop);

describe('LabSetPanel', () => {
const user = userEvent.setup();
const mockSetActivePanel = jest.fn();

it('renders the panel header, columns, and observations when provided', () => {
render(
<LabSetPanel
activePanel={null}
observations={mockObservations}
panel={mockBasePanel}
setActivePanel={mockSetActivePanel}
/>,
);

expect(screen.getByRole('table')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /complete blood count/i })).toBeInTheDocument();
expect(screen.getByText('01 — Jan — 2024 • 10:00')).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /test name/i })).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /value/i })).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /reference range/i })).toBeInTheDocument();
expect(screen.getByText(/test name/i)).toBeInTheDocument();
expect(screen.getByText(/value/i)).toBeInTheDocument();
expect(screen.getByText(/reference range/i)).toBeInTheDocument();
expect(screen.getByRole('row', { name: /hemoglobin 14 g\/dL 12-16 g\/dL/i })).toBeInTheDocument();
expect(screen.getByRole('row', { name: /hematocrit 42 % 35-45 %/i })).toBeInTheDocument();
});

it('clicking on the panel header sets the active panel', async () => {
render(
<LabSetPanel
activePanel={null}
observations={mockObservations}
panel={mockBasePanel}
setActivePanel={mockSetActivePanel}
/>,
);

const buttonElement = screen.getByRole('button', {
name: /complete blood count 01 jan 2024 10:00 test name value reference range hemoglobin 14 g\/dL 12-16 g\/dL hematocrit 42 % 35-45 %/i,
});

await user.click(buttonElement);
expect(mockSetActivePanel).toHaveBeenCalledWith(mockBasePanel);
});

it('renders the panel without reference ranges when not provided', () => {
const panelWithoutRange = {
...mockBasePanel,
meta: {
...mockConceptMeta,
range: undefined,
},
};

const observationsWithoutRange: Array<ObsRecord> = [
{
...mockBasePanel,
id: '1',
name: 'Hemoglobin',
value: '14',
interpretation: 'NORMAL' as OBSERVATION_INTERPRETATION,
meta: {
...mockConceptMeta,
units: 'g/dL',
range: undefined,
},
},
{
...mockBasePanel,
id: '2',
name: 'Hematocrit',
value: '42',
interpretation: 'HIGH' as OBSERVATION_INTERPRETATION,
meta: {
...mockConceptMeta,
units: '%',
range: undefined,
},
},
];

render(
<LabSetPanel
activePanel={null}
observations={observationsWithoutRange}
panel={panelWithoutRange}
setActivePanel={mockSetActivePanel}
/>,
);

expect(screen.getByRole('columnheader', { name: /test name/i })).toBeInTheDocument();
expect(screen.getByRole('columnheader', { name: /value/i })).toBeInTheDocument();
expect(screen.queryByRole('columnheader', { name: /reference range/i })).not.toBeInTheDocument();

expect(screen.getByRole('row', { name: /hemoglobin 14 g\/dL/i })).toBeInTheDocument();
expect(screen.getByRole('row', { name: /hematocrit/i })).toBeInTheDocument();
});

it('correctly highlights the interpretation of the observations', () => {
render(
<LabSetPanel
activePanel={null}
observations={mockObservationsWithInterpretations}
panel={mockBasePanel}
setActivePanel={mockSetActivePanel}
/>,
);

const normalTest = screen.getByRole('row', { name: /normal test 14 g\/dL 12-16 g\/dL/i });
const highTest = screen.getByRole('row', { name: /high test 42 g\/dL 12-16 g\/dL/i });
const lowTest = screen.getByRole('row', { name: /low test 2 g\/dL 12-16 g\/dL/i });

expect(normalTest).toHaveClass('check');
expect(highTest).toHaveClass('high', 'check');
expect(lowTest).toHaveClass('low', 'check');
});

it('adjusts the table size based on the layout', () => {
mockUseLayoutType.mockReturnValue('large-desktop');
mockIsDesktop.mockReturnValue(true);

const { rerender } = render(
<LabSetPanel
activePanel={null}
observations={mockObservations}
panel={mockBasePanel}
setActivePanel={mockSetActivePanel}
/>,
);

expect(screen.getByRole('table')).toHaveClass('cds--data-table--sm');

mockUseLayoutType.mockReturnValue('tablet');
mockIsDesktop.mockReturnValue(false);

rerender(
<LabSetPanel
activePanel={null}
observations={mockObservations}
panel={mockBasePanel}
setActivePanel={mockSetActivePanel}
/>,
);

expect(screen.getByRole('table')).toHaveClass('cds--data-table--md');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ const LabSetPanel: React.FC<LabSetPanelProps> = ({ panel, observations, activePa
<p className={styles.subtitleText}>
{formatDate(date, {
mode: 'wide',
time: false, // Exclude time since we are displaying it on the next line
time: false,
})}{' '}
&bull; {`${date.getUTCHours()}:${date.getUTCMinutes()}`}
&bull; {`${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`}
</p>
</div>
<DataTable rows={rowsData} headers={headers}>
Expand Down

0 comments on commit 64dd1cd

Please sign in to comment.