Skip to content

Commit

Permalink
(feat) O3-4239 : Add extension slot for medication dispensing actions (
Browse files Browse the repository at this point in the history
…#128)

* (feat) add prescription actions as action buttons

* (feat) O3-4239 : Add extension slot for medication dispensing actions
  • Loading branch information
donaldkibet authored Dec 3, 2024
1 parent f1ede21 commit 3e44b45
Show file tree
Hide file tree
Showing 9 changed files with 373 additions and 263 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"analyze": "webpack --mode=production --env.analyze=true",
"lint": "eslint src --ext js,jsx,ts,tsx",
"test": "jest --config jest.config.js",
"test:watch": "jest --config jest.config.js --watch",
"typescript": "tsc",
"verify": "concurrently 'yarn:lint' 'yarn:test' 'yarn:typescript'",
"coverage": "yarn test --coverage",
Expand Down
343 changes: 156 additions & 187 deletions src/components/action-buttons.component.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,130 @@
import { render } from '@testing-library/react';
import React from 'react';
import ActionButtons from './action-buttons.component';
import { type MedicationRequest, MedicationRequestStatus } from '../types';
import { useConfig } from '@openmrs/esm-framework';
import { MedicationDispenseStatus, type MedicationRequest, MedicationRequestStatus } from '../types';
import { useConfig, ExtensionSlot } from '@openmrs/esm-framework';
import DispenseActionButton from './prescription-actions/dispense-action-button.component';
import PauseActionButton from './prescription-actions/pause-action-button.component';
import CloseActionButton from './prescription-actions/close-action-button.component';
import { computeMedicationRequestStatus, getMostRecentMedicationDispenseStatus } from '../utils';

const mockedUseConfig = useConfig as jest.Mock;
const mockedExtensionSlot = ExtensionSlot as jest.Mock;
const mockPatientUuid = '558494fe-5850-4b34-a3bf-06550334ba4a';
const mockEncounterUuid = '7aee7123-9e50-4f72-a636-895d77a63e98';

const medicationRequest: MedicationRequest = {
resourceType: 'MedicationRequest',
id: 'd4f69a68-1171-4e47-8693-478df18daf40',
meta: {
lastUpdated: '2023-01-24T19:02:04.000-05:00',
},
status: MedicationRequestStatus.active,
intent: 'order',
priority: 'routine',
medicationReference: {
reference: 'Medication/c8d3444c-41a4-48d3-9ec1-811fe7b27d99',
type: 'Medication',
display: 'Ascorbic acid (Vitamin C), 250mg tablet',
},
subject: {
reference: 'Patient/558494fe-5850-4b34-a3bf-06550334ba4a',
type: 'Patient',
display: 'Dylan, Bob (ZL EMR ID: Y2CK2G)',
},
encounter: {
reference: 'Encounter/7aee7123-9e50-4f72-a636-895d77a63e98',
type: 'Encounter',
},
requester: {
reference: 'Practitioner/19e06fb0-22ea-4dd4-aafd-da14c14a1487',
type: 'Practitioner',
identifier: {
value: 'MAADH',
},
display: 'Goodrich, Mark (Identifier: MAADH)',
},
dosageInstruction: [
{
text: 'test',
timing: {
repeat: {
duration: 6,
durationUnit: 'd',
},
code: {
coding: [
{
code: '37328251-6759-4270-8a2e-8cab2c0b315b',
display: 'OD (once daily)',
},
{
system: 'http://snomed.info/sct',
code: '229797004',
display: 'OD (once daily)',
},
],
text: 'OD (once daily)',
},
},
asNeededBoolean: false,
route: {
coding: [
{
code: '46aaaca8-1f21-410a-aac9-67bfcc1fd577',
display: 'Oral',
},
{
system: 'http://snomed.info/sct',
code: '26643006',
display: 'Oral',
},
],
text: 'Oral',
},
doseAndRate: [
{
doseQuantity: {
value: 5.0,
unit: 'Ampule(s)',
system: 'http://snomed.info/sct',
code: '413516001',
},
},
],
},
],
dispenseRequest: {
validityPeriod: {
start: new Date().toISOString(),
},
numberOfRepeatsAllowed: 8,
quantity: {
value: 7.0,
unit: 'Application',
system: 'http://snomed.info/sct',
code: '413568008',
},
},
};

const medicationRequestStatus = computeMedicationRequestStatus(medicationRequest, 90);
const mostRecentMedicationDispenseStatus: MedicationDispenseStatus = getMostRecentMedicationDispenseStatus([]);

const prescriptionActionsState = {
dispensable:
medicationRequestStatus === MedicationRequestStatus.active &&
mostRecentMedicationDispenseStatus !== MedicationDispenseStatus.declined,
pauseable: true,
closeable: true,
quantityRemaining: 0,
patientUuid: mockPatientUuid,
encounterUuid: mockEncounterUuid,
medicationRequestBundle: { request: medicationRequest, dispenses: [] },
session: undefined,
providers: [],
};

describe('Action Buttons Component tests', () => {
beforeEach(() => {
mockedUseConfig.mockReturnValue({
Expand All @@ -29,100 +146,13 @@ describe('Action Buttons Component tests', () => {

test('component should render dispense button if active medication', () => {
// status = active, and validity period start set to current datetime
const medicationRequest: MedicationRequest = {
resourceType: 'MedicationRequest',
id: 'd4f69a68-1171-4e47-8693-478df18daf40',
meta: {
lastUpdated: '2023-01-24T19:02:04.000-05:00',
},
status: MedicationRequestStatus.active,
intent: 'order',
priority: 'routine',
medicationReference: {
reference: 'Medication/c8d3444c-41a4-48d3-9ec1-811fe7b27d99',
type: 'Medication',
display: 'Ascorbic acid (Vitamin C), 250mg tablet',
},
subject: {
reference: 'Patient/558494fe-5850-4b34-a3bf-06550334ba4a',
type: 'Patient',
display: 'Dylan, Bob (ZL EMR ID: Y2CK2G)',
},
encounter: {
reference: 'Encounter/7aee7123-9e50-4f72-a636-895d77a63e98',
type: 'Encounter',
},
requester: {
reference: 'Practitioner/19e06fb0-22ea-4dd4-aafd-da14c14a1487',
type: 'Practitioner',
identifier: {
value: 'MAADH',
},
display: 'Goodrich, Mark (Identifier: MAADH)',
},
dosageInstruction: [
{
text: 'test',
timing: {
repeat: {
duration: 6,
durationUnit: 'd',
},
code: {
coding: [
{
code: '37328251-6759-4270-8a2e-8cab2c0b315b',
display: 'OD (once daily)',
},
{
system: 'http://snomed.info/sct',
code: '229797004',
display: 'OD (once daily)',
},
],
text: 'OD (once daily)',
},
},
asNeededBoolean: false,
route: {
coding: [
{
code: '46aaaca8-1f21-410a-aac9-67bfcc1fd577',
display: 'Oral',
},
{
system: 'http://snomed.info/sct',
code: '26643006',
display: 'Oral',
},
],
text: 'Oral',
},
doseAndRate: [
{
doseQuantity: {
value: 5.0,
unit: 'Ampule(s)',
system: 'http://snomed.info/sct',
code: '413516001',
},
},
],
},
],
dispenseRequest: {
validityPeriod: {
start: new Date().toISOString(),
},
numberOfRepeatsAllowed: 8,
quantity: {
value: 7.0,
unit: 'Application',
system: 'http://snomed.info/sct',
code: '413568008',
},
},
};
mockedExtensionSlot.mockImplementationOnce(() => (
<div>
<DispenseActionButton {...prescriptionActionsState} />
<PauseActionButton {...prescriptionActionsState} />
<CloseActionButton {...prescriptionActionsState} />
</div>
));

const { getByText, container } = render(
<ActionButtons
Expand All @@ -136,109 +166,48 @@ describe('Action Buttons Component tests', () => {

// status = active, but validity period start time years in the past
test('component should not render dispense button if expired medication', () => {
// status = active, and validity period start set to current datetime
const medicationRequest: MedicationRequest = {
resourceType: 'MedicationRequest',
id: 'd4f69a68-1171-4e47-8693-478df18daf40',
meta: {
lastUpdated: '2023-01-24T19:02:04.000-05:00',
},
status: MedicationRequestStatus.active,
intent: 'order',
priority: 'routine',
medicationReference: {
reference: 'Medication/c8d3444c-41a4-48d3-9ec1-811fe7b27d99',
type: 'Medication',
display: 'Ascorbic acid (Vitamin C), 250mg tablet',
},
subject: {
reference: 'Patient/558494fe-5850-4b34-a3bf-06550334ba4a',
type: 'Patient',
display: 'Dylan, Bob (ZL EMR ID: Y2CK2G)',
},
encounter: {
reference: 'Encounter/7aee7123-9e50-4f72-a636-895d77a63e98',
type: 'Encounter',
},
requester: {
reference: 'Practitioner/19e06fb0-22ea-4dd4-aafd-da14c14a1487',
type: 'Practitioner',
identifier: {
value: 'MAADH',
},
display: 'Goodrich, Mark (Identifier: MAADH)',
},
dosageInstruction: [
{
text: 'test',
timing: {
repeat: {
duration: 6,
durationUnit: 'd',
},
code: {
coding: [
{
code: '37328251-6759-4270-8a2e-8cab2c0b315b',
display: 'OD (once daily)',
},
{
system: 'http://snomed.info/sct',
code: '229797004',
display: 'OD (once daily)',
},
],
text: 'OD (once daily)',
},
},
asNeededBoolean: false,
route: {
coding: [
{
code: '46aaaca8-1f21-410a-aac9-67bfcc1fd577',
display: 'Oral',
},
{
system: 'http://snomed.info/sct',
code: '26643006',
display: 'Oral',
},
],
text: 'Oral',
},
doseAndRate: [
{
doseQuantity: {
value: 5.0,
unit: 'Ampule(s)',
system: 'http://snomed.info/sct',
code: '413516001',
},
},
],
},
],
const expiredMedicationRequest = {
...medicationRequest,
dispenseRequest: {
...medicationRequest.dispenseRequest,
validityPeriod: {
start: '2019-01-24T19:02:04.000-05:00',
},
numberOfRepeatsAllowed: 8,
quantity: {
value: 7.0,
unit: 'Application',
system: 'http://snomed.info/sct',
code: '413568008',
},
},
};

const { queryByText, container } = render(
// Recalculate status with expired medication
const expiredMedicationRequestStatus = computeMedicationRequestStatus(expiredMedicationRequest, 90);
const mostRecentDispenseStatus = getMostRecentMedicationDispenseStatus([]);

// Create new state with expired medication
const expiredPrescriptionActionsState = {
...prescriptionActionsState,
dispensable:
expiredMedicationRequestStatus === MedicationRequestStatus.active &&
mostRecentDispenseStatus !== MedicationDispenseStatus.declined,
medicationRequestBundle: {
request: expiredMedicationRequest,
dispenses: [],
},
};

mockedExtensionSlot.mockImplementationOnce(() => (
<div>
<DispenseActionButton {...expiredPrescriptionActionsState} />
<PauseActionButton {...expiredPrescriptionActionsState} />
<CloseActionButton {...expiredPrescriptionActionsState} />
</div>
));

const { queryByText } = render(
<ActionButtons
patientUuid={mockPatientUuid}
encounterUuid={mockEncounterUuid}
medicationRequestBundle={{ request: medicationRequest, dispenses: [] }}
medicationRequestBundle={{ request: expiredMedicationRequest, dispenses: [] }}
/>,
);

expect(queryByText('Dispense')).not.toBeInTheDocument();
});
});
Loading

0 comments on commit 3e44b45

Please sign in to comment.