import dayjs from 'dayjs'; import { vi, describe, expect, test } from 'vitest'; import isToday from 'dayjs/plugin/isToday'; import useSWR from 'swr'; import { openmrsFetch, type Session } from '@openmrs/esm-framework'; import { deleteMedicationDispense, initiateMedicationDispenseBody, saveMedicationDispense, useOrderConfig, useSubstitutionReasonValueSet, useSubstitutionTypeValueSet, } from './medication-dispense.resource'; import { type MedicationDispense, type MedicationRequest, MedicationDispenseStatus, MedicationRequestStatus, type Provider, } from '../types'; dayjs.extend(isToday); vi.mocked(openmrsFetch); vi.mock('swr'); describe('Medication Dispense Resource tests', () => { test('saveMedicationDispense should call medication dispense FHIR endpoint with appropriate data and method POST', () => { const medicationDispense: MedicationDispense = { dosageInstruction: undefined, id: '', location: { display: '', reference: '', type: '' }, medicationReference: { display: '', reference: '', type: '' }, meta: { lastUpdated: '' }, quantity: undefined, performer: undefined, resourceType: 'MedicationDispense', status: null, subject: { display: '', reference: '', type: '' }, substitution: { reason: [], type: undefined, wasSubstituted: false }, type: undefined, whenHandedOver: '', whenPrepared: '', }; const abortController: AbortController = { signal: undefined, abort(): void {}, }; saveMedicationDispense(medicationDispense, MedicationDispenseStatus.completed, abortController); expect(openmrsFetch).toHaveBeenCalledWith('/ws/fhir2/R4/MedicationDispense', { method: 'POST', signal: abortController.signal, headers: { 'Content-Type': 'application/json', }, body: medicationDispense, }); }); test('saveMedicationDispense should call medication dispense FHIR endpoint with appropriate data and method PUT', () => { const medicationDispense: MedicationDispense = { dosageInstruction: undefined, id: '123abc', location: { display: '', reference: '', type: '' }, medicationReference: { display: '', reference: '', type: '' }, meta: { lastUpdated: '' }, performer: undefined, quantity: undefined, resourceType: 'MedicationDispense', status: null, subject: { display: '', reference: '', type: '' }, substitution: { reason: [], type: undefined, wasSubstituted: false }, type: undefined, whenHandedOver: '', whenPrepared: '', }; const abortController: AbortController = { signal: undefined, abort(): void {}, }; saveMedicationDispense(medicationDispense, MedicationDispenseStatus.completed, abortController); expect(openmrsFetch).toHaveBeenCalledWith('/ws/fhir2/R4/MedicationDispense/123abc', { method: 'PUT', signal: abortController.signal, headers: { 'Content-Type': 'application/json', }, body: medicationDispense, }); }); test('deleteMedicationDispense should call medication request FHIR endpoint with appropriate uuid and method DELETE', () => { deleteMedicationDispense('123abc'); expect(openmrsFetch).toHaveBeenCalledWith('/ws/fhir2/R4/MedicationDispense/123abc', { method: 'DELETE' }); }); test('useOrderConfig should fetch order config via SWR', () => { // @ts-ignore useSWR.mockImplementation(() => ({ data: { data: 'mockedOrderConfig' } })); const orderConfig = useOrderConfig(); expect(orderConfig.orderConfigObject).toBe('mockedOrderConfig'); }); test('useSubstitutionTypeValueSet should call fetch substitution type value set via SWR', () => { // @ts-ignore useSWR.mockImplementation(() => ({ data: { data: 'mockedSubstitutionTypeValueSet' }, })); const result = useSubstitutionTypeValueSet('123'); expect(useSWR).toHaveBeenCalledWith('/ws/fhir2/R4/ValueSet/123', openmrsFetch); expect(result.substitutionTypeValueSet).toBe('mockedSubstitutionTypeValueSet'); }); test('useSubstitutionReasonValueSet should call fetch substitution reason value set via SWR', () => { // @ts-ignore useSWR.mockImplementation(() => ({ data: { data: 'mockedSubstitutionReasonValueSet' }, })); const result = useSubstitutionReasonValueSet('123'); expect(useSWR).toHaveBeenCalledWith('/ws/fhir2/R4/ValueSet/123', openmrsFetch); expect(result.substitutionReasonValueSet).toBe('mockedSubstitutionReasonValueSet'); }); test('initiateMedicationDispenseBody should initialize medication dispense body from request', () => { const activeMedicationRequest: MedicationRequest = { intent: '', medicationReference: { reference: 'Medication/123abc' }, meta: { lastUpdated: '' }, priority: '', resourceType: 'MedicationRequest', status: MedicationRequestStatus.active, subject: { reference: 'Patient/765432' }, dispenseRequest: { numberOfRepeatsAllowed: 0, quantity: { value: 20.0, system: 'http://snomed.info/sct', code: '123456789', unit: 'Tablet', }, validityPeriod: { start: '' }, }, encounter: { reference: '', type: '' }, requester: { display: '', identifier: { value: '' }, reference: '', type: '', }, dosageInstruction: [ { text: 'Take with food', timing: { repeat: { duration: 30.0, durationUnit: 'd', boundsDuration: undefined, }, code: { coding: [ { code: '', }, ], }, }, asNeededBoolean: false, route: { coding: [ { code: '545767', }, ], }, doseAndRate: [ { doseQuantity: { value: 5.0, unit: 'Tablet', system: 'http://snomed.info/sct', code: '385055001', }, }, ], }, ], id: '456def', }; const session: Session = { authenticated: true, sessionId: '', user: undefined, currentProvider: { uuid: 'ghi789', identifier: undefined, }, sessionLocation: { uuid: '987654', display: undefined, links: undefined, }, }; const providers: Provider[] = [ { uuid: 'ghi789', person: null, }, ]; const medicationDispense: MedicationDispense = initiateMedicationDispenseBody( activeMedicationRequest, session, providers, true, ); expect(medicationDispense.id).toBeUndefined(); expect(medicationDispense.resourceType).toBe('MedicationDispense'); expect(medicationDispense.medicationReference.reference).toBe('Medication/123abc'); expect(medicationDispense.status).toBeNull(); expect(medicationDispense.authorizingPrescription[0].reference).toBe('MedicationRequest/456def'); expect(medicationDispense.authorizingPrescription[0].type).toBe('MedicationRequest'); expect(medicationDispense.medicationCodeableConcept).toBeUndefined(); expect(medicationDispense.subject.reference).toBe('Patient/765432'); expect(medicationDispense.performer[0].actor.reference).toBe('Practitioner/ghi789'); expect(medicationDispense.location.reference).toBe('Location/987654'); expect(medicationDispense.quantity.value).toBe(20.0); expect(medicationDispense.quantity.system).toBe('http://snomed.info/sct'); expect(medicationDispense.quantity.unit).toBe('Tablet'); expect(medicationDispense.quantity.code).toBe('123456789'); expect(dayjs(medicationDispense.whenPrepared).isToday()).toBeTruthy(); expect(dayjs(medicationDispense.whenHandedOver).isToday()).toBeTruthy(); expect(medicationDispense.dosageInstruction[0].text).toBe('Take with food'); expect(medicationDispense.dosageInstruction[0].timing.repeat.duration).toBe(30.0); expect(medicationDispense.dosageInstruction[0].timing.repeat.durationUnit).toBe('d'); expect(medicationDispense.dosageInstruction[0].asNeededBoolean).toBe(false); expect(medicationDispense.dosageInstruction[0].route.coding[0].code).toBe('545767'); expect(medicationDispense.dosageInstruction[0].doseAndRate[0].doseQuantity.value).toBe(5); expect(medicationDispense.dosageInstruction[0].doseAndRate[0].doseQuantity.system).toBe('http://snomed.info/sct'); expect(medicationDispense.dosageInstruction[0].doseAndRate[0].doseQuantity.code).toBe('385055001'); expect(medicationDispense.dosageInstruction[0].doseAndRate[0].doseQuantity.unit).toBe('Tablet'); expect(medicationDispense.substitution.wasSubstituted).toBe(false); }); });