This commit is contained in:
nasir@endelospay.com
2025-07-11 20:22:12 +05:00
commit 8c74b0e23f
120 changed files with 206874 additions and 0 deletions

310
tests/mocks/authMocks.js Normal file
View File

@@ -0,0 +1,310 @@
/**
* @fileoverview Authentication mocking utilities for Laravel Healthcare MCP Server tests
* Provides comprehensive mocking for authentication tokens and Sanctum authentication
*/
import { jest } from "@jest/globals";
/**
* Authentication Mock Manager for handling authentication-related mocks
*/
export class AuthMockManager {
constructor() {
this.tokens = new Map();
this.credentials = new Map();
this.authHistory = [];
this.authenticationCleared = false;
}
/**
* Create a mock AuthManager instance
* @returns {Object} Mock AuthManager instance
*/
createMockAuthManager() {
const mockAuthManager = {
authenticate: jest.fn(),
getToken: jest.fn(),
validateToken: jest.fn(),
refreshToken: jest.fn(),
logout: jest.fn(),
validateAllCredentials: jest.fn(),
getCacheStats: jest.fn(),
credentials: {},
tokenCache: new Map(),
};
// Setup method implementations
mockAuthManager.authenticate.mockImplementation(
async (authType, credentials) => {
this.authHistory.push({
action: "authenticate",
authType,
credentials: { ...credentials, password: "[REDACTED]" },
timestamp: new Date().toISOString(),
});
if (this.shouldAuthenticationSucceed(authType, credentials)) {
const token = this.generateMockToken(authType);
this.tokens.set(authType, token);
return { success: true, token };
} else {
throw new Error(`Authentication failed for ${authType}`);
}
}
);
mockAuthManager.getToken.mockImplementation((authType) => {
return this.tokens.get(authType) || null;
});
mockAuthManager.validateToken.mockImplementation(
async (token, authType) => {
const storedToken = this.tokens.get(authType);
return storedToken === token;
}
);
mockAuthManager.refreshToken.mockImplementation(async (authType) => {
if (this.tokens.has(authType)) {
const newToken = this.generateMockToken(authType);
this.tokens.set(authType, newToken);
return { success: true, token: newToken };
}
throw new Error(`No token found for ${authType}`);
});
mockAuthManager.logout.mockImplementation(async (authType) => {
this.tokens.delete(authType);
this.authHistory.push({
action: "logout",
authType,
timestamp: new Date().toISOString(),
});
return { success: true };
});
mockAuthManager.validateAllCredentials.mockImplementation(async () => {
const results = {};
for (const authType of Object.values(global.testConstants.AUTH_TYPES)) {
if (authType === "public") continue;
results[authType] = {
valid: this.hasValidCredentials(authType),
error: this.hasValidCredentials(authType)
? null
: `Invalid credentials for ${authType}`,
};
}
return results;
});
mockAuthManager.getCacheStats.mockImplementation(() => ({
size: this.tokens.size,
keys: Array.from(this.tokens.keys()),
lastAccess: new Date().toISOString(),
}));
return mockAuthManager;
}
/**
* Generate a mock authentication token
* @param {string} authType - Authentication type
* @returns {string} Mock token
*/
generateMockToken(authType) {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2);
return `${authType}_token_${timestamp}_${random}`;
}
/**
* Set mock credentials for an authentication type
* @param {string} authType - Authentication type
* @param {Object} credentials - Mock credentials
*/
setMockCredentials(authType, credentials) {
this.credentials.set(authType, credentials);
this.authenticationCleared = false; // Authentication is now available
}
/**
* Check if authentication should succeed
* @param {string} authType - Authentication type
* @param {Object} credentials - Provided credentials
* @returns {boolean} Whether authentication should succeed
*/
shouldAuthenticationSucceed(authType, credentials) {
const mockCredentials = this.credentials.get(authType);
if (!mockCredentials) {
// Default success for test credentials
return (
credentials.username === `test_${authType}` &&
credentials.password === "test_password"
);
}
return (
credentials.username === mockCredentials.username &&
credentials.password === mockCredentials.password
);
}
/**
* Check if valid credentials exist for auth type
* @param {string} authType - Authentication type
* @returns {boolean} Whether valid credentials exist
*/
hasValidCredentials(authType) {
return (
this.credentials.has(authType) ||
process.env[`${authType.toUpperCase()}_USERNAME`]
);
}
/**
* Setup default mock credentials for all auth types
*/
setupDefaultCredentials() {
const authTypes = [
"provider",
"patient",
"partner",
"affiliate",
"network",
];
authTypes.forEach((authType) => {
this.setMockCredentials(authType, {
username: `test_${authType}`,
password: "test_password",
email: `test@${authType}.example.com`,
});
});
}
/**
* Mock Sanctum token authentication
* @param {string} token - Bearer token
* @returns {Object} Mock user data
*/
mockSanctumAuth(token) {
if (!token || !token.startsWith("Bearer ")) {
throw new Error("Invalid token format");
}
const actualToken = token.replace("Bearer ", "");
// Find auth type from token
let authType = "provider";
for (const [type, storedToken] of this.tokens.entries()) {
if (storedToken === actualToken) {
authType = type;
break;
}
}
return {
id: `mock_${authType}_user_123`,
email: `test@${authType}.example.com`,
role: authType,
permissions: this.getMockPermissions(authType),
tokenType: "Bearer",
expiresAt: new Date(Date.now() + 3600000).toISOString(), // 1 hour from now
};
}
/**
* Get mock permissions for auth type
* @param {string} authType - Authentication type
* @returns {Array} Array of permissions
*/
getMockPermissions(authType) {
const permissions = {
provider: [
"read:patients",
"write:patients",
"read:prescriptions",
"write:prescriptions",
],
patient: ["read:own_data", "write:own_data"],
partner: ["read:business_data", "write:business_data"],
affiliate: ["read:affiliate_data", "write:affiliate_data"],
network: ["read:network_data", "write:network_data"],
};
return permissions[authType] || [];
}
/**
* Create mock HIPAA-compliant authentication context
* @param {string} authType - Authentication type
* @returns {Object} HIPAA-compliant auth context
*/
createHIPAAAuthContext(authType) {
return {
userId: `mock_${authType}_user_123`,
role: authType,
permissions: this.getMockPermissions(authType),
sessionId: `session_${Date.now()}`,
ipAddress: "127.0.0.1",
userAgent: "Jest Test Suite",
loginTime: new Date().toISOString(),
lastActivity: new Date().toISOString(),
hipaaCompliant: true,
auditTrail: {
enabled: true,
logLevel: "detailed",
},
};
}
/**
* Get authentication history
* @returns {Array} Array of authentication events
*/
getAuthHistory() {
return [...this.authHistory];
}
/**
* Clear authentication history
*/
clearHistory() {
this.authHistory = [];
}
/**
* Reset all authentication mocks
*/
reset() {
this.tokens.clear();
this.credentials.clear();
this.authHistory = [];
this.authenticationCleared = true;
}
/**
* Check if authentication has been cleared
*/
isAuthenticationCleared() {
return this.authenticationCleared;
}
/**
* Simulate token expiration
* @param {string} authType - Authentication type
*/
expireToken(authType) {
this.tokens.delete(authType);
this.authHistory.push({
action: "token_expired",
authType,
timestamp: new Date().toISOString(),
});
}
}
// Export singleton instance
export const authMockManager = new AuthMockManager();

View File

@@ -0,0 +1,371 @@
/**
* @fileoverview Healthcare data mocking utilities for Laravel Healthcare MCP Server tests
* Provides HIPAA-compliant mock data and validation utilities for healthcare testing
*/
import { jest } from '@jest/globals';
/**
* Healthcare Data Mock Manager for handling healthcare-specific mock data
*/
export class HealthcareDataMockManager {
constructor() {
this.patientData = new Map();
this.providerData = new Map();
this.prescriptionData = new Map();
this.appointmentData = new Map();
this.medicalRecords = new Map();
}
/**
* Generate comprehensive mock patient data
* @param {Object} overrides - Optional field overrides
* @returns {Object} Mock patient data
*/
generateMockPatient(overrides = {}) {
const basePatient = {
id: `patient_${Date.now()}_${Math.random().toString(36).substring(2)}`,
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@test.example.com',
dateOfBirth: '1990-01-01',
genderIdentity: 'Male',
preferredPhone: '555-0123',
address: '123 Test St',
city: 'Test City',
state: 'TS',
zipcode: '12345',
status: 'active',
isPortalAccess: true,
emergencyContact: {
name: 'Jane Doe',
relationship: 'Spouse',
phone: '555-0124'
},
insurance: {
provider: 'Test Insurance',
policyNumber: 'TEST123456',
groupNumber: 'GRP789'
},
medicalHistory: {
allergies: ['Penicillin'],
conditions: ['Hypertension'],
medications: ['Lisinopril 10mg']
},
hipaaConsent: {
signed: true,
signedDate: '2025-01-01',
version: '1.0'
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
return { ...basePatient, ...overrides };
}
/**
* Generate comprehensive mock provider data
* @param {Object} overrides - Optional field overrides
* @returns {Object} Mock provider data
*/
generateMockProvider(overrides = {}) {
const baseProvider = {
id: `provider_${Date.now()}_${Math.random().toString(36).substring(2)}`,
firstName: 'Dr. Jane',
lastName: 'Smith',
emailAddress: 'dr.smith@test.example.com',
textMessageNumber: '555-0456',
username: 'drsmith',
company_name: 'Test Medical Center',
npiNumber: '1234567890',
licenseNumber: 'MD123456',
specialty: 'Internal Medicine',
accessRights: {
admin: true,
practitioner: true,
patientPortal: false
},
credentials: {
degree: 'MD',
boardCertifications: ['Internal Medicine'],
yearsExperience: 10
},
workSchedule: {
monday: { start: '09:00', end: '17:00' },
tuesday: { start: '09:00', end: '17:00' },
wednesday: { start: '09:00', end: '17:00' },
thursday: { start: '09:00', end: '17:00' },
friday: { start: '09:00', end: '17:00' }
},
hipaaTraining: {
completed: true,
completedDate: '2025-01-01',
expirationDate: '2026-01-01'
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
return { ...baseProvider, ...overrides };
}
/**
* Generate comprehensive mock prescription data
* @param {Object} overrides - Optional field overrides
* @returns {Object} Mock prescription data
*/
generateMockPrescription(overrides = {}) {
const basePrescription = {
id: `prescription_${Date.now()}_${Math.random().toString(36).substring(2)}`,
patientId: 'test-patient-123',
providerId: 'test-provider-456',
medication: {
name: 'Lisinopril',
genericName: 'Lisinopril',
strength: '10mg',
form: 'Tablet'
},
dosage: '10mg',
frequency: 'Once daily',
duration: '30 days',
quantity: 30,
refills: 2,
instructions: 'Take with food',
status: 'active',
prescribedDate: new Date().toISOString(),
startDate: new Date().toISOString(),
endDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
pharmacy: {
name: 'Test Pharmacy',
phone: '555-0789',
address: '456 Pharmacy St'
},
interactions: [],
contraindications: [],
sideEffects: ['Dizziness', 'Dry cough'],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
return { ...basePrescription, ...overrides };
}
/**
* Generate comprehensive mock appointment data
* @param {Object} overrides - Optional field overrides
* @returns {Object} Mock appointment data
*/
generateMockAppointment(overrides = {}) {
const baseAppointment = {
id: `appointment_${Date.now()}_${Math.random().toString(36).substring(2)}`,
patientId: 'test-patient-123',
providerId: 'test-provider-456',
date: '2025-07-15',
time: '10:00',
duration: 30,
type: 'consultation',
status: 'scheduled',
reason: 'Annual checkup',
notes: 'Patient reports feeling well',
location: {
room: 'Room 101',
building: 'Main Building',
address: '123 Medical Center Dr'
},
reminders: {
email: true,
sms: true,
sentAt: null
},
telehealth: {
enabled: false,
platform: null,
meetingId: null
},
billing: {
cptCodes: ['99213'],
estimatedCost: 150.00,
insuranceCovered: true
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
return { ...baseAppointment, ...overrides };
}
/**
* Generate mock medical record data
* @param {Object} overrides - Optional field overrides
* @returns {Object} Mock medical record data
*/
generateMockMedicalRecord(overrides = {}) {
const baseRecord = {
id: `record_${Date.now()}_${Math.random().toString(36).substring(2)}`,
patientId: 'test-patient-123',
providerId: 'test-provider-456',
appointmentId: 'test-appointment-101',
type: 'progress_note',
date: new Date().toISOString(),
chiefComplaint: 'Annual physical examination',
historyOfPresentIllness: 'Patient reports feeling well with no acute concerns',
physicalExam: {
vitals: {
bloodPressure: '120/80',
heartRate: 72,
temperature: 98.6,
weight: 150,
height: 68
},
general: 'Well-appearing, no acute distress',
cardiovascular: 'Regular rate and rhythm, no murmurs',
respiratory: 'Clear to auscultation bilaterally',
neurological: 'Alert and oriented x3'
},
assessment: 'Healthy adult, no acute issues',
plan: 'Continue current medications, return in 1 year',
medications: ['Lisinopril 10mg daily'],
allergies: ['Penicillin'],
diagnosis: {
primary: 'Z00.00 - Encounter for general adult medical examination',
secondary: []
},
labResults: [],
imagingResults: [],
followUp: {
required: true,
timeframe: '1 year',
provider: 'same'
},
hipaaAccess: {
accessedBy: ['test-provider-456'],
accessLog: [
{
userId: 'test-provider-456',
action: 'view',
timestamp: new Date().toISOString()
}
]
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
return { ...baseRecord, ...overrides };
}
/**
* Create HIPAA-compliant mock data with proper access controls
* @param {string} dataType - Type of data to create
* @param {string} userRole - Role of the accessing user
* @param {Object} overrides - Optional field overrides
* @returns {Object} HIPAA-compliant mock data
*/
createHIPAACompliantData(dataType, userRole, overrides = {}) {
let data;
switch (dataType) {
case 'patient':
data = this.generateMockPatient(overrides);
break;
case 'provider':
data = this.generateMockProvider(overrides);
break;
case 'prescription':
data = this.generateMockPrescription(overrides);
break;
case 'appointment':
data = this.generateMockAppointment(overrides);
break;
case 'medical_record':
data = this.generateMockMedicalRecord(overrides);
break;
default:
throw new Error(`Unknown data type: ${dataType}`);
}
// Add HIPAA compliance metadata
data.hipaaMetadata = {
accessLevel: this.getAccessLevel(userRole),
encryptionStatus: 'encrypted',
auditTrail: {
created: new Date().toISOString(),
createdBy: `mock_${userRole}_user`,
lastAccessed: new Date().toISOString(),
accessCount: 1
},
dataClassification: 'PHI', // Protected Health Information
retentionPolicy: {
retainUntil: new Date(Date.now() + 7 * 365 * 24 * 60 * 60 * 1000).toISOString(), // 7 years
autoDelete: true
}
};
return data;
}
/**
* Get access level based on user role
* @param {string} userRole - User role
* @returns {string} Access level
*/
getAccessLevel(userRole) {
const accessLevels = {
provider: 'full',
patient: 'own_data_only',
partner: 'business_data_only',
affiliate: 'limited',
network: 'network_data_only'
};
return accessLevels[userRole] || 'none';
}
/**
* Validate HIPAA compliance for mock data
* @param {Object} data - Data to validate
* @param {string} userRole - User role requesting access
* @returns {Object} Validation result
*/
validateHIPAACompliance(data, userRole) {
const validation = {
isCompliant: true,
violations: [],
warnings: []
};
// Check if data has HIPAA metadata
if (!data.hipaaMetadata) {
validation.isCompliant = false;
validation.violations.push('Missing HIPAA metadata');
}
// Check access level
const requiredAccessLevel = this.getAccessLevel(userRole);
if (data.hipaaMetadata && data.hipaaMetadata.accessLevel !== requiredAccessLevel) {
validation.warnings.push(`Access level mismatch: expected ${requiredAccessLevel}, got ${data.hipaaMetadata.accessLevel}`);
}
// Check for PHI in logs
if (data.hipaaMetadata && data.hipaaMetadata.dataClassification === 'PHI') {
validation.warnings.push('PHI data detected - ensure proper handling');
}
return validation;
}
/**
* Reset all healthcare data mocks
*/
reset() {
this.patientData.clear();
this.providerData.clear();
this.prescriptionData.clear();
this.appointmentData.clear();
this.medicalRecords.clear();
}
}
// Export singleton instance
export const healthcareDataMockManager = new HealthcareDataMockManager();

283
tests/mocks/httpMocks.js Normal file
View File

@@ -0,0 +1,283 @@
/**
* @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();

3066
tests/mocks/mockFactory.js Normal file

File diff suppressed because it is too large Load Diff