/** * @fileoverview HTTP mocking utilities for Laravel Healthcare MCP Server tests * Provides comprehensive mocking for axios requests and API responses */ import { jest } from '@jest/globals'; /** * HTTP Mock Manager for handling axios mocks */ export class HttpMockManager { constructor() { this.mocks = new Map(); this.defaultResponses = new Map(); this.requestHistory = []; } /** * Create a mock axios instance * @returns {Object} Mock axios instance */ createMockAxios() { const mockAxios = { get: jest.fn(), post: jest.fn(), put: jest.fn(), patch: jest.fn(), delete: jest.fn(), request: jest.fn(), defaults: { headers: { common: {}, get: {}, post: {}, put: {}, patch: {}, delete: {} }, timeout: 5000, baseURL: '' }, interceptors: { request: { use: jest.fn(), eject: jest.fn() }, response: { use: jest.fn(), eject: jest.fn() } } }; // Track all requests const trackRequest = (method, url, config = {}) => { this.requestHistory.push({ method: method.toUpperCase(), url, config, timestamp: new Date().toISOString() }); }; // Setup method implementations mockAxios.get.mockImplementation((url, config) => { trackRequest('GET', url, config); return this.handleRequest('GET', url, config); }); mockAxios.post.mockImplementation((url, data, config) => { trackRequest('POST', url, { ...config, data }); return this.handleRequest('POST', url, { ...config, data }); }); mockAxios.put.mockImplementation((url, data, config) => { trackRequest('PUT', url, { ...config, data }); return this.handleRequest('PUT', url, { ...config, data }); }); mockAxios.patch.mockImplementation((url, data, config) => { trackRequest('PATCH', url, { ...config, data }); return this.handleRequest('PATCH', url, { ...config, data }); }); mockAxios.delete.mockImplementation((url, config) => { trackRequest('DELETE', url, config); return this.handleRequest('DELETE', url, config); }); return mockAxios; } /** * Handle HTTP request and return appropriate mock response * @param {string} method - HTTP method * @param {string} url - Request URL * @param {Object} config - Request configuration * @returns {Promise} Promise resolving to mock response */ async handleRequest(method, url, config = {}) { const key = `${method}:${url}`; // Check for specific mock if (this.mocks.has(key)) { const mockConfig = this.mocks.get(key); if (mockConfig.shouldFail) { throw mockConfig.error || new Error(`Mock error for ${key}`); } return mockConfig.response; } // Check for default response if (this.defaultResponses.has(method)) { return this.defaultResponses.get(method); } // Default success response return { status: 200, statusText: 'OK', data: { success: true, message: 'Mock response' }, headers: { 'content-type': 'application/json' } }; } /** * Mock a specific HTTP request * @param {string} method - HTTP method * @param {string} url - Request URL * @param {Object} response - Mock response * @param {boolean} shouldFail - Whether the request should fail * @param {Error} error - Error to throw if shouldFail is true */ mockRequest(method, url, response, shouldFail = false, error = null) { const key = `${method.toUpperCase()}:${url}`; this.mocks.set(key, { response, shouldFail, error }); } /** * Mock authentication login requests * @param {string} authType - Authentication type * @param {boolean} shouldSucceed - Whether login should succeed */ mockAuthLogin(authType, shouldSucceed = true) { const endpoints = { public: '/api/login', provider: '/api/login', patient: '/api/frontend/login', partner: '/api/login-partner-api', affiliate: '/api/affiliate-login-api', network: '/api/network/login' }; const endpoint = endpoints[authType] || '/api/login'; if (shouldSucceed) { this.mockRequest('POST', endpoint, { status: 200, data: { success: true, token: `mock_${authType}_token_${Date.now()}`, user: { id: `mock_${authType}_user_123`, email: `test@${authType}.example.com`, role: authType } } }); } else { this.mockRequest('POST', endpoint, null, true, { response: { status: 401, data: { error: 'Invalid credentials' } } }); } } /** * Mock healthcare data endpoints */ mockHealthcareEndpoints() { // Patient data endpoints this.mockRequest('GET', '/api/emr/patients', { status: 200, data: { patients: [ global.testUtils.createMockPatientData(), { ...global.testUtils.createMockPatientData(), id: 'test-patient-456' } ] } }); this.mockRequest('POST', '/api/emr/patients', { status: 201, data: { success: true, patient: global.testUtils.createMockPatientData() } }); // Provider data endpoints this.mockRequest('GET', '/api/emr/providers', { status: 200, data: { providers: [ global.testUtils.createMockProviderData(), { ...global.testUtils.createMockProviderData(), id: 'test-provider-789' } ] } }); // Prescription endpoints this.mockRequest('GET', '/api/emr/prescriptions', { status: 200, data: { prescriptions: [ global.testUtils.createMockPrescriptionData() ] } }); this.mockRequest('POST', '/api/emr/prescriptions', { status: 201, data: { success: true, prescription: global.testUtils.createMockPrescriptionData() } }); // Appointment endpoints this.mockRequest('GET', '/api/emr/appointments', { status: 200, data: { appointments: [ global.testUtils.createMockAppointmentData() ] } }); } /** * Get request history * @returns {Array} Array of request objects */ getRequestHistory() { return [...this.requestHistory]; } /** * Clear request history */ clearHistory() { this.requestHistory = []; } /** * Reset all mocks */ reset() { this.mocks.clear(); this.defaultResponses.clear(); this.requestHistory = []; } /** * Set default response for a method * @param {string} method - HTTP method * @param {Object} response - Default response */ setDefaultResponse(method, response) { this.defaultResponses.set(method.toUpperCase(), response); } } // Export singleton instance export const httpMockManager = new HttpMockManager();