Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
CynthiaKamau committed Jan 16, 2025
1 parent ee9e145 commit dd56bad
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 21 deletions.
60 changes: 60 additions & 0 deletions __mocks__/forms/rfe-forms/diagnosis-test-form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "Diagnosis test",
"pages": [
{
"label": "1",
"sections": [
{
"label": "Select diagnosis",
"isExpanded": "true",
"questions": [
{
"label": "Test Diagnosis 1",
"id": "diagnosis1",
"type": "diagnosis",
"questionOptions": {
"rendering": "repeating",
"dataSource": "diagnoses",
"isSearchable": "false",
"diagnosis": {
"isConfirmed": "true",
"rank": 1,
"conceptClasses": [
"8d4918b0-c2cc-11de-8d13-0010c6dffd0f",
"8d492954-c2cc-11de-8d13-0010c6dffd0f",
"8d492b2a-c2cc-11de-8d13-0010c6dffd0f"
]
}
}
},
{
"label": "Test Diagnosis 2",
"id": "diagnosis2",
"type": "diagnosis",
"questionOptions": {
"rendering": "repeating",
"dataSource": "diagnoses",
"isSearchable": "false",
"diagnosis": {
"isConfirmed": "true",
"rank": 1,
"conceptClasses": [
"8d4918b0-c2cc-11de-8d13-0010c6dffd0f",
"8d492954-c2cc-11de-8d13-0010c6dffd0f",
"8d492b2a-c2cc-11de-8d13-0010c6dffd0f"
]
}
}
}
]
}
]
}
],
"processor": "EncounterFormProcessor",
"encounterType": "e22e39fd-7db2-45e7-80f1-60fa0d5a4378",
"referencedForms": [],
"uuid": "29ce67d1-892b-45be-84ce-8e36aa9ca37f",
"description": "re",
"version": "1.0"
}
13 changes: 8 additions & 5 deletions src/adapters/encounter-diagnosis-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { type FormContextProps } from '../provider/form-provider';
import { type OpenmrsEncounter, type FormField } from '../types';
import { gracefullySetSubmission } from '../utils/common-utils';
import { isEmpty } from '../validators/form-validator';
import { voidObs } from './obs-adapter';
import { isTrue } from '../utils/boolean-utils';

export let assignedDiagnosesIds: string[] = [];

export const EncounterDiagnosisAdapter: FormFieldValueAdapter = {
transformFieldValue: function (field: FormField, value: any, context: FormContextProps) {
if (field.meta.initialValue?.omrsObject && isEmpty(value)) {
return gracefullySetSubmission(field, undefined, voidObs(field.meta.initialValue.omrsObject as OpenmrsObs));
return gracefullySetSubmission(field, undefined, voidDiagnosis(field.meta.initialValue.omrsObject as OpenmrsObs));
}
if (!isEmpty(value)) {
const previousDiagnosis = field.meta.initialValue?.omrsObject as OpenmrsResource;
Expand Down Expand Up @@ -68,7 +67,7 @@ export const EncounterDiagnosisAdapter: FormFieldValueAdapter = {
},
};

const constructNewDiagnosis = (value: any, field: FormField, patientUuid: string) => {
const constructNewDiagnosis = (value: string, field: FormField, patientUuid: string) => {
if (!value) {
return null;
}
Expand All @@ -86,7 +85,7 @@ const constructNewDiagnosis = (value: any, field: FormField, patientUuid: string
};

function editDiagnosis(
newEncounterDiagnosis: any,
newEncounterDiagnosis: string,
field: FormField,
previousDiagnosis: OpenmrsResource,
patientUuid: string,
Expand All @@ -105,9 +104,13 @@ function editDiagnosis(
};
}

export function hasPreviousDiagnosisValueChanged(previousDiagnosis: OpenmrsResource, newValue: any) {
export function hasPreviousDiagnosisValueChanged(previousDiagnosis: OpenmrsResource, newValue: string) {
if (isEmpty(previousDiagnosis)) {
return false;
}
return previousDiagnosis.value !== newValue;
}

export function voidDiagnosis(obs: OpenmrsObs) {
return { uuid: obs.uuid, voided: true };
}
138 changes: 122 additions & 16 deletions src/form-engine.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import dayjs from 'dayjs';
import userEvent from '@testing-library/user-event';
import { act, cleanup, render, screen, within } from '@testing-library/react';
import { act, cleanup, render, screen, waitFor, within } from '@testing-library/react';
import {
ExtensionSlot,
OpenmrsDatePicker,
Expand Down Expand Up @@ -44,14 +44,18 @@ import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-for
import readOnlyValidationForm from '__mocks__/forms/rfe-forms/read-only-validation-form.json';
import jsExpressionValidationForm from '__mocks__/forms/rfe-forms/js-expression-validation-form.json';
import hidePagesAndSectionsForm from '__mocks__/forms/rfe-forms/hide-pages-and-sections-form.json';
import diagnosisForm from '__mocks__/forms/rfe-forms/diagnosis-test-form.json';

import FormEngine from './form-engine.component';
import { type SessionMode } from './types';
import { use } from 'i18next';

const patientUUID = '8673ee4f-e2ab-4077-ba55-4980f408773e';
const visit = mockVisit;
const formsResourcePath = when((url: string) => url.includes(`${restBaseUrl}/form/`));
const clobDataResourcePath = when((url: string) => url.includes(`${restBaseUrl}/clobdata/`));
const conceptResourcePath = when((url: string) => url.includes(`${restBaseUrl}/concept/`));

global.ResizeObserver = require('resize-observer-polyfill');

const mockOpenmrsFetch = jest.mocked(openmrsFetch);
Expand All @@ -60,25 +64,56 @@ const mockUsePatient = jest.mocked(usePatient);
const mockUseSession = jest.mocked(useSession);
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);

mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange, isInvalid, invalidText }) => {
return (
<>
<label htmlFor={id}>{labelText}</label>
<input
id={id}
value={value ? dayjs(value as unknown as string).format('DD/MM/YYYY') : ''}
onChange={(evt) => {
onChange(dayjs(evt.target.value).toDate());
}}
/>
{isInvalid && <span>{invalidText}</span>}
</>
);
});
// mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange, isInvalid, invalidText }) => {
// return (
// <>
// <label htmlFor={id}>{labelText}</label>
// <input
// id={id}
// value={value ? dayjs(value as unknown as string).format('DD/MM/YYYY') : ''}
// onChange={(evt) => {
// onChange(dayjs(evt.target.value).toDate());
// }}
// />
// {isInvalid && <span>{invalidText}</span>}
// </>
// );
// });

when(mockOpenmrsFetch).calledWith(formsResourcePath).mockReturnValue({ data: demoHtsOpenmrsForm });
when(mockOpenmrsFetch).calledWith(clobDataResourcePath).mockReturnValue({ data: demoHtsForm });

jest.mock('./registry/registry', () => {
const originalModule = jest.requireActual('./registry/registry');
return {
...originalModule,
getRegisteredDataSource: jest.fn().mockResolvedValue({
fetchData: jest.fn().mockImplementation((...args) => {
if (args[1].class?.length && !args[1].referencedValue.key) {
// concept DS
return Promise.resolve([
{
uuid: 'stage-1-uuid',
display: 'stage 1',
},
{
uuid: 'stage-2-uuid',
display: 'stage 2',
},
]);
}
}),
fetchSingleItem: jest.fn().mockImplementation((uuid: string) => {
return Promise.resolve({
uuid,
display: 'stage 1',
});
}),
toUuidAndDisplay: (data) => data,
}),
};
});

jest.mock('../src/api', () => {
const originalModule = jest.requireActual('../src/api');

Expand Down Expand Up @@ -1047,6 +1082,77 @@ describe('Form engine component', () => {
});
});

describe('Diagnisis field', () => {
it('should test addition of a diagnosis', async () => {
await act(async () => {
renderForm(null, diagnosisForm);
});
const addButtons = screen.getAllByRole('button', { name: 'Add' });
expect(addButtons.length).toBeGreaterThan(0);
await user.click(addButtons[0]);
expect(screen.getByRole('button', { name: /Remove/i })).toBeInTheDocument();
expect(screen.getAllByRole('combobox', { name: /^test diagnosis 1$/i }).length).toEqual(2);
});

it('should render diagnosis field', async () => {
await act(async () => {
renderForm(null, diagnosisForm);
});
const initialDiagnosis = screen.getAllByRole('combobox', { name: /test diagnosis 1|test diagnosis 2/i });
expect(initialDiagnosis.length).toBe(2);
});

it('should save diagnosis field on form submission', async () => {
await act(async () => {
renderForm(null, diagnosisForm);
});
const saveEncounterMock = jest.spyOn(api, 'saveEncounter');

const combobox = await screen.findByRole('combobox', { name: /test diagnosis 1/i });
expect(combobox).toBeInTheDocument();

await userEvent.click(combobox);
await waitFor(() => {
expect(screen.getByText('stage 1')).toBeInTheDocument();
expect(screen.getByText('stage 2')).toBeInTheDocument();
});
await user.click(screen.getByText('stage 1'));
await user.click(screen.getByRole('button', { name: /save/i }));
expect(saveEncounterMock).toHaveBeenCalledTimes(1);
const [_, encounter] = saveEncounterMock.mock.calls[0];
expect(encounter.diagnoses.length).toBe(1);
expect(encounter.diagnoses[0]).toEqual({
patient: '8673ee4f-e2ab-4077-ba55-4980f408773e',
condition: null,
diagnosis: {
coded: 'stage-1-uuid',
},
certainty: 'CONFIRMED',
rank: 1,
formFieldPath: `rfe-forms-diagnosis1`,
formFieldNamespace: 'rfe-forms',
});
});

it('should test removing of a diagnosis field', async () => {
await act(async () => {
renderForm(null, diagnosisForm);
});

const addButtons = screen.getAllByRole('button', { name: 'Add' });
expect(addButtons.length).toBeGreaterThan(0);
await user.click(addButtons[0]);
expect(screen.getByRole('button', { name: /Remove/i })).toBeInTheDocument();
expect(screen.getAllByRole('combobox', { name: /^test diagnosis 1$/i }).length).toEqual(2);

const removeButton = screen.getByRole('button', { name: /Remove/i });

await user.click(removeButton);

expect(removeButton).not.toBeInTheDocument();
});
});

function renderForm(formUUID, formJson, intent?: string, mode?: SessionMode) {
render(
<FormEngine
Expand Down

0 comments on commit dd56bad

Please sign in to comment.