/** * @fileoverview Tests for provider prescription and medication management MCP tools * Tests prescription creation, medication templates, and drug interaction checking */ import { describe, test, expect, beforeEach, afterEach } from "@jest/globals"; import { mockFactory } from "../mocks/mockFactory.js"; describe("Provider Prescription and Medication Management Tools", () => { let mockEnv; let toolGenerator; let mockToken; beforeEach(() => { mockEnv = mockFactory.createMockEnvironment({ authTypes: ["provider"], enableHttpMocks: true, enableAuthMocks: true, enableHealthcareMocks: true, }); toolGenerator = mockEnv.toolGenerator; // Setup provider authentication mockToken = "provider_token_123"; mockFactory.authMocks.setMockCredentials("provider", { username: "test_provider", password: "test_password", }); }); afterEach(() => { mockFactory.resetAllMocks(); }); describe("provider_create_prescriptionstore", () => { test("should successfully store prescription with complete medication data", async () => { // Setup const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Lisinopril", generic_name: "Lisinopril", strength: "10mg", form: "Tablet", dosage: "10mg", frequency: "Once daily", duration: "30 days", quantity: 30, refills: 2, instructions: "Take with food in the morning", prescriber_id: "provider_456", pharmacy_id: "pharmacy_789", ndc_number: "12345-678-90", dea_schedule: "Non-controlled", indication: "Hypertension", route: "Oral", start_date: "2025-07-09", end_date: "2025-08-08", }, }; // Mock successful prescription storage const mockPrescription = mockFactory.healthcareMocks.generateMockPrescription({ patientId: "patient_123", medication: { name: "Lisinopril", strength: "10mg", form: "Tablet", }, dosage: "10mg", frequency: "Once daily", duration: "30 days", }); mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", { status: 201, data: { success: true, prescription: mockPrescription, message: "Prescription stored successfully", }, } ); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.prescription.patientId).toBe("patient_123"); expect(result.data.prescription.medication.name).toBe("Lisinopril"); expect(result.data.prescription.dosage).toBe("10mg"); expect(result.data.prescription.frequency).toBe("Once daily"); }); test("should validate prescription data for drug safety", async () => { const toolName = "provider_create_prescriptionstore"; // Test invalid dosage const invalidDosageParams = { patient_id: "patient_123", medication_data: { medication_name: "Lisinopril", strength: "10mg", dosage: "invalid_dosage", // Invalid dosage format frequency: "Once daily", }, }; await expect( toolGenerator.executeTool(toolName, invalidDosageParams) ).rejects.toThrow(); // Test missing required fields const incompleteParams = { patient_id: "patient_123", medication_data: { medication_name: "Lisinopril", // Missing required fields }, }; await expect( toolGenerator.executeTool(toolName, incompleteParams) ).rejects.toThrow(); }); test("should check for drug interactions", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Warfarin", strength: "5mg", dosage: "5mg", frequency: "Once daily", current_medications: ["Aspirin", "Ibuprofen"], // Potential interactions }, }; // Mock drug interaction warning mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", { status: 200, data: { success: true, prescription: mockFactory.healthcareMocks.generateMockPrescription(), warnings: [ { type: "drug_interaction", severity: "moderate", message: "Potential interaction between Warfarin and Aspirin", recommendation: "Monitor INR levels closely", }, ], }, } ); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.success).toBe(true); expect(result.data.warnings).toBeDefined(); expect(result.data.warnings[0].type).toBe("drug_interaction"); }); test("should handle controlled substance prescriptions", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Oxycodone", strength: "5mg", dosage: "5mg", frequency: "Every 6 hours as needed", dea_schedule: "Schedule II", quantity: 20, refills: 0, // No refills for Schedule II prescriber_dea: "AB1234567", }, }; // Mock controlled substance handling mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", { status: 201, data: { success: true, prescription: { ...mockFactory.healthcareMocks.generateMockPrescription(), controlledSubstance: true, deaSchedule: "Schedule II", refills: 0, specialHandling: { requiresDeaNumber: true, electronicPrescribingRequired: true, auditTrail: true, }, }, }, } ); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.success).toBe(true); expect(result.data.prescription.controlledSubstance).toBe(true); expect(result.data.prescription.refills).toBe(0); }); }); describe("provider_create_add_medicine_template", () => { test("should successfully store medicine template", async () => { // Setup const toolName = "provider_create_add_medicine_template"; const parameters = { template_data: { template_name: "Hypertension Standard Protocol", medication_name: "Lisinopril", default_strength: "10mg", default_dosage: "10mg", default_frequency: "Once daily", default_duration: "30 days", default_quantity: 30, default_refills: 2, default_instructions: "Take with food in the morning", indication: "Hypertension", contraindications: ["Pregnancy", "Angioedema history"], monitoring_requirements: ["Blood pressure", "Kidney function"], provider_id: "provider_456", specialty: "Internal Medicine", }, }; // Mock successful template storage mockFactory.httpMocks.mockRequest("POST", "/api/add_medicine_template", { status: 201, data: { success: true, template: { id: "template_123", templateName: "Hypertension Standard Protocol", medicationName: "Lisinopril", defaultStrength: "10mg", providerId: "provider_456", createdAt: new Date().toISOString(), }, message: "Medicine template stored successfully", }, }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.template.templateName).toBe( "Hypertension Standard Protocol" ); expect(result.data.template.medicationName).toBe("Lisinopril"); }); test("should validate template data completeness", async () => { const toolName = "provider_create_add_medicine_template"; // Test missing required template data const incompleteParams = { template_data: { template_name: "Incomplete Template", // Missing medication details }, }; await expect( toolGenerator.executeTool(toolName, incompleteParams) ).rejects.toThrow(); }); }); describe("provider_create_emrimportMedicine", () => { test("should successfully import medicines from Excel file", async () => { // Setup const toolName = "provider_create_emrimportMedicine"; const parameters = { excel_file: new File(["mock excel content"], "medicines.xlsx", { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }), }; // Mock successful import mockFactory.httpMocks.mockRequest("POST", "/api/emr/import-medicines", { status: 200, data: { success: true, imported_count: 150, skipped_count: 5, errors: [], summary: { total_rows: 155, successful_imports: 150, duplicates_skipped: 3, validation_errors: 2, }, message: "Medicines imported successfully", }, }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.imported_count).toBe(150); expect(result.data.summary.total_rows).toBe(155); }); test("should handle import validation errors", async () => { const toolName = "provider_create_emrimportMedicine"; const parameters = { excel_file: new File(["invalid content"], "invalid.xlsx", { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }), }; // Mock import with validation errors mockFactory.httpMocks.mockRequest("POST", "/api/emr/import/medicine", { status: 200, data: { success: false, imported_count: 0, errors: [ { row: 2, field: "medication_name", error: "Medication name is required", }, { row: 3, field: "strength", error: "Invalid strength format", }, ], message: "Import completed with errors", }, }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.success).toBe(false); expect(result.data.errors.length).toBe(2); }); test("should validate file format", async () => { const toolName = "provider_create_emrimportMedicine"; const parameters = { excel_file: new File(["not excel"], "medicines.txt", { type: "text/plain", }), }; await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); }); describe("Prescription Security and Compliance Tests", () => { test("should require provider authentication for prescription operations", async () => { // Clear authentication mockFactory.authMocks.reset(); const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Lisinopril", strength: "10mg", }, }; // Mock authentication failure mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", null, true, { response: { status: 401, data: { error: "Provider authentication required" }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); test("should validate prescriber credentials for controlled substances", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Morphine", dea_schedule: "Schedule II", prescriber_dea: "invalid_dea", }, }; // Mock DEA validation failure mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", null, true, { response: { status: 403, data: { error: "Invalid DEA number for controlled substance" }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); test("should audit prescription activities for compliance", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Lisinopril", strength: "10mg", dosage: "10mg", frequency: "Once daily", }, }; // Mock response with audit trail mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", { status: 201, data: { success: true, prescription: mockFactory.healthcareMocks.generateMockPrescription(), auditTrail: { prescriberId: "provider_456", prescribedAt: new Date().toISOString(), patientId: "patient_123", medicationName: "Lisinopril", action: "prescription_created", ipAddress: "127.0.0.1", userAgent: "Jest Test Suite", }, }, } ); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.auditTrail).toBeDefined(); expect(result.data.auditTrail.action).toBe("prescription_created"); expect(result.data.auditTrail.prescriberId).toBe("provider_456"); }); test("should handle prescription rate limiting", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Oxycodone", dea_schedule: "Schedule II", }, }; // Mock rate limiting for controlled substances mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", null, true, { response: { status: 429, data: { error: "Too many controlled substance prescriptions" }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); test("should validate patient eligibility for prescription", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "inactive_patient", medication_data: { medication_name: "Lisinopril", strength: "10mg", }, }; // Mock patient eligibility check failure mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/inactive_patient", null, true, { response: { status: 400, data: { error: "Patient is not eligible for prescriptions" }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); }); describe("Medication Safety Tests", () => { test("should check for allergy contraindications", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "patient_123", medication_data: { medication_name: "Penicillin", strength: "500mg", patient_allergies: ["Penicillin"], // Patient allergic to prescribed medication }, }; // Mock allergy contraindication mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/patient_123", null, true, { response: { status: 400, data: { error: "Allergy contraindication detected", details: "Patient is allergic to Penicillin", }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); test("should validate dosage ranges for patient demographics", async () => { const toolName = "provider_create_prescriptionstore"; const parameters = { patient_id: "pediatric_patient", medication_data: { medication_name: "Aspirin", strength: "325mg", dosage: "325mg", patient_age: 8, // Pediatric patient - aspirin contraindicated }, }; // Mock pediatric contraindication mockFactory.httpMocks.mockRequest( "POST", "/api/emr/prescription/store/pediatric_patient", null, true, { response: { status: 400, data: { error: "Age-related contraindication", details: "Aspirin not recommended for pediatric patients", }, }, } ); await expect( toolGenerator.executeTool(toolName, parameters) ).rejects.toThrow(); }); }); });