import React from 'react';
import { vi, describe, expect, test, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { showModal, useConfig, usePatient } from '@openmrs/esm-framework';
import { type MedicationDispense, type MedicationRequestBundle, MedicationDispenseStatus } from '../types';
import DispenseForm from './dispense-form.workspace';
import { saveMedicationDispense } from '../medication-dispense/medication-dispense.resource';
import { updateMedicationRequestFulfillerStatus } from '../medication-request/medication-request.resource';
const mockUseConfig = vi.mocked(useConfig);
const mockUsePatient = vi.mocked(usePatient);
const mockShowModal = vi.mocked(showModal);
const mockCloseWorkspace = vi.fn();
const mockLaunchChildWorkspace = vi.fn();
const mockSaveMedicationDispense = vi.mocked(saveMedicationDispense);
const mockUpdateMedicationRequestFulfillerStatus = vi.mocked(updateMedicationRequestFulfillerStatus);
vi.mock('../medication-dispense/medication-dispense.resource', () => ({
__esModule: true,
saveMedicationDispense: vi.fn(),
}));
vi.mock('../medication-request/medication-request.resource', () => ({
__esModule: true,
updateMedicationRequestFulfillerStatus: vi.fn(),
}));
// Mock workspace props required by Workspace2DefinitionProps
const mockWorkspaceProps = {
launchChildWorkspace: mockLaunchChildWorkspace,
windowProps: {},
groupProps: {},
workspaceName: 'dispense-form',
windowName: 'dispense-form-window',
isRootWorkspace: true,
promptBeforeClosing: vi.fn(),
setTitle: vi.fn(),
showActionMenu: true,
};
// Mock the child components
vi.mock('./medication-dispense-review.component', () => ({
__esModule: true,
default: () =>
Medication Dispense Review
,
}));
vi.mock('./stock-dispense/stock-dispense.component', () => ({
__esModule: true,
default: () => Stock Dispense
,
}));
const mockPatient = {
uuid: 'patient-uuid',
display: 'Test Patient',
identifiers: [],
person: {
age: 30,
attributes: [],
birthDate: '1990-01-01',
gender: 'M',
display: 'Test Patient',
preferredAddress: {},
uuid: 'patient-uuid',
},
};
const createMockMedicationDispense = (): MedicationDispense => ({
resourceType: 'MedicationDispense',
status: MedicationDispenseStatus.completed,
medicationCodeableConcept: {
text: 'Test Medication',
coding: [
{
code: 'medication-code',
},
],
},
medicationReference: {
reference: 'Medication/med-uuid',
display: 'Test Medication',
},
subject: {
reference: 'Patient/patient-uuid',
display: 'Test Patient',
},
performer: [
{
actor: {
reference: 'Practitioner/prac-uuid',
display: 'Test Practitioner',
},
},
],
location: {
reference: 'Location/loc-uuid',
display: 'Test Location',
},
quantity: {
value: 30,
code: '385055001',
},
dosageInstruction: [
{
timing: {
code: {
coding: [
{
code: 'timing-code',
display: 'Once daily',
},
],
},
},
asNeededBoolean: false,
route: {
coding: [
{
code: 'route-code',
display: 'Oral',
},
],
},
doseAndRate: [
{
doseQuantity: {
value: 1,
code: '385055001',
},
},
],
},
],
substitution: {
wasSubstituted: false,
},
});
const createMockMedicationRequestBundle = (numberOfRepeatsAllowed: number | null): MedicationRequestBundle => ({
request: {
resourceType: 'MedicationRequest',
id: 'request-uuid',
meta: {
lastUpdated: '2023-01-01T00:00:00.000Z',
},
status: 'active' as any,
intent: 'order',
priority: 'routine',
medicationReference: {
reference: 'Medication/med-uuid',
display: 'Test Medication',
},
subject: {
reference: 'Patient/patient-uuid',
display: 'Test Patient',
},
encounter: {
reference: 'Encounter/enc-uuid',
type: 'Encounter',
},
requester: {
reference: 'Practitioner/prac-uuid',
type: 'Practitioner',
identifier: {
value: 'PRAC123',
},
display: 'Test Practitioner',
},
dosageInstruction: [
{
timing: {
code: {
coding: [
{
code: 'timing-code',
display: 'Once daily',
},
],
},
},
asNeededBoolean: false,
route: {
coding: [
{
code: 'route-code',
display: 'Oral',
},
],
},
doseAndRate: [
{
doseQuantity: {
value: 1,
code: '385055001',
},
},
],
},
],
dispenseRequest: {
numberOfRepeatsAllowed: numberOfRepeatsAllowed,
quantity: {
value: 30,
code: '385055001',
},
validityPeriod: {
start: '2023-01-01',
},
},
},
dispenses: [],
});
beforeEach(() => {
mockShowModal.mockReturnValue(vi.fn());
mockSaveMedicationDispense.mockResolvedValue({ ok: true, status: 201, data: { status: 'completed' } } as any);
mockUpdateMedicationRequestFulfillerStatus.mockResolvedValue({} as any);
mockUseConfig.mockReturnValue({
dispenseBehavior: {
allowModifyingPrescription: false,
restrictTotalQuantityDispensed: false,
},
completeOrderWithThisDispense: true,
enableStockDispense: false,
});
mockUsePatient.mockReturnValue({
patient: mockPatient,
isLoading: false,
error: null,
patientUuid: 'patient-uuid',
} as any);
});
describe('DispenseForm - Complete Order Checkbox Auto-Default', () => {
test('should default checkbox to true when numberOfRepeatsAllowed is 0', () => {
const medicationDispense = createMockMedicationDispense();
const medicationRequestBundle = createMockMedicationRequestBundle(0);
render(
,
);
const checkbox = screen.getByRole('checkbox', { name: /complete order with this dispense/i });
expect(checkbox).toBeChecked();
});
test('should default checkbox to true when numberOfRepeatsAllowed is null', () => {
const medicationDispense = createMockMedicationDispense();
const medicationRequestBundle = createMockMedicationRequestBundle(null);
render(
,
);
const checkbox = screen.getByRole('checkbox', { name: /complete order with this dispense/i });
expect(checkbox).toBeChecked();
});
test('should default checkbox to false when numberOfRepeatsAllowed is greater than 0', () => {
const medicationDispense = createMockMedicationDispense();
const medicationRequestBundle = createMockMedicationRequestBundle(2);
render(
,
);
const checkbox = screen.getByRole('checkbox', { name: /complete order with this dispense/i });
expect(checkbox).not.toBeChecked();
});
test('should allow user to manually uncheck the checkbox even when auto-defaulted to true', async () => {
const user = userEvent.setup();
const medicationDispense = createMockMedicationDispense();
const medicationRequestBundle = createMockMedicationRequestBundle(0);
render(
,
);
const checkbox = screen.getByRole('checkbox', { name: /complete order with this dispense/i });
expect(checkbox).toBeChecked();
// User manually unchecks the checkbox
await user.click(checkbox);
expect(checkbox).not.toBeChecked();
});
test('should not auto-default checkbox in edit mode', () => {
const medicationDispense = createMockMedicationDispense();
medicationDispense.id = 'existing-dispense-id'; // Existing dispense
const medicationRequestBundle = createMockMedicationRequestBundle(0);
render(
,
);
// In edit mode, the checkbox should not be rendered at all
const checkbox = screen.queryByRole('checkbox', { name: /complete order with this dispense/i });
expect(checkbox).not.toBeInTheDocument();
});
test('should not show duplicate warning for retrospective dispense when only later dispenses are in the lookback window', async () => {
const user = userEvent.setup();
const medicationDispense = {
...createMockMedicationDispense(),
whenHandedOver: '2026-03-12T10:00:00.000Z',
};
const recentDispense = {
...createMockMedicationDispense(),
id: 'existing-dispense-id',
whenHandedOver: '2026-03-26T10:00:00.000Z',
};
const medicationRequestBundle = {
...createMockMedicationRequestBundle(0),
dispenses: [recentDispense],
};
mockUseConfig.mockReturnValue({
dispenseBehavior: {
allowModifyingPrescription: false,
restrictTotalQuantityDispensed: false,
},
completeOrderWithThisDispense: true,
enableStockDispense: false,
enableDuplicateDispenseCheck: true,
duplicateCheckWindowDays: 7,
} as any);
render(
,
);
await user.click(screen.getByRole('button', { name: /dispense prescription/i }));
expect(mockShowModal).not.toHaveBeenCalled();
expect(mockSaveMedicationDispense).toHaveBeenCalled();
});
});