/** * @fileoverview Tests for patient portal and authentication MCP tools * Tests patient login, portal access, and patient-specific authentication */ import { describe, test, expect, beforeEach, afterEach } from '@jest/globals'; import { mockFactory } from '../mocks/mockFactory.js'; describe('Patient Portal and Authentication Tools', () => { let mockEnv; let toolGenerator; let mockToken; beforeEach(() => { mockEnv = mockFactory.createMockEnvironment({ authTypes: ['patient'], enableHttpMocks: true, enableAuthMocks: true, enableHealthcareMocks: true }); toolGenerator = mockEnv.toolGenerator; // Setup patient authentication mockToken = 'patient_token_123'; mockFactory.authMocks.setMockCredentials('patient', { username: 'test_patient', password: 'test_password' }); }); afterEach(() => { mockFactory.resetAllMocks(); }); describe('patient_create_patientlogin', () => { test('should successfully login patient', async () => { // Setup const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'patientpassword' }; // Mock successful patient login mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_token_456', user: { id: 'patient_456', email: 'patient@test.com', role: 'patient', firstName: 'John', lastName: 'Doe', portalAccess: true }, permissions: ['read:own_data', 'write:own_data'], message: 'Patient login successful' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.user.role).toBe('patient'); expect(result.data.user.portalAccess).toBe(true); expect(result.data.permissions).toContain('read:own_data'); }); test('should handle invalid patient credentials', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'wrongpassword' }; // Mock authentication failure mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', null, true, { response: { status: 401, data: { error: 'Invalid patient credentials' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should handle disabled portal access', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'disabled@test.com', password: 'password' }; // Mock disabled portal access mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', null, true, { response: { status: 403, data: { error: 'Portal access is disabled for this patient' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); describe('patient_create_patientLoginApi', () => { test('should successfully login via API', async () => { // Setup const toolName = 'patient_create_patientLoginApi'; const parameters = { email: 'patient@test.com', password: 'patientpassword' }; // Mock successful API login mockFactory.httpMocks.mockRequest('POST', '/api/patient-login-api', { status: 200, data: { success: true, token: 'patient_api_token_789', user: { id: 'patient_789', email: 'patient@test.com', role: 'patient' }, apiAccess: true, tokenExpiry: new Date(Date.now() + 3600000).toISOString() } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.apiAccess).toBe(true); expect(result.data.tokenExpiry).toBeDefined(); }); }); describe('patient_create_loginPatient', () => { test('should successfully login patient with alternative endpoint', async () => { // Setup const toolName = 'patient_create_loginPatient'; const parameters = { email: 'patient@test.com', password: 'patientpassword' }; // Mock successful login mockFactory.httpMocks.mockRequest('POST', '/api/login-patient', { status: 200, data: { success: true, token: 'patient_login_token_101', patient: { id: 'patient_101', email: 'patient@test.com', firstName: 'Jane', lastName: 'Smith', dateOfBirth: '1985-03-15', portalEnabled: true } } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.patient.portalEnabled).toBe(true); expect(result.data.patient.firstName).toBe('Jane'); }); }); describe('Patient Authentication Security Tests', () => { test('should validate email format for patient login', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'invalid-email-format', password: 'password' }; await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should handle account lockout after failed attempts', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'locked@test.com', password: 'password' }; // Mock account lockout mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', null, true, { response: { status: 423, data: { error: 'Account temporarily locked due to multiple failed login attempts', lockoutExpiry: new Date(Date.now() + 900000).toISOString() // 15 minutes } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should enforce password complexity for patient accounts', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: '123' // Weak password }; // Mock weak password rejection mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', null, true, { response: { status: 400, data: { error: 'Password does not meet security requirements' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should audit patient login activities for HIPAA compliance', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'validpassword' }; // Mock login with audit trail mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_token_audit', user: { id: 'patient_audit', email: 'patient@test.com', role: 'patient' }, auditTrail: { loginTime: new Date().toISOString(), ipAddress: '127.0.0.1', userAgent: 'Jest Test Suite', sessionId: 'session_123', hipaaCompliant: true } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.auditTrail).toBeDefined(); expect(result.data.auditTrail.hipaaCompliant).toBe(true); expect(result.data.auditTrail.sessionId).toBeDefined(); }); test('should handle concurrent login sessions', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'password' }; // Mock concurrent session handling mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'new_session_token', user: { id: 'patient_concurrent', email: 'patient@test.com', role: 'patient' }, sessionInfo: { currentSessions: 2, maxAllowedSessions: 3, previousSessionTerminated: false } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.sessionInfo.currentSessions).toBe(2); expect(result.data.sessionInfo.maxAllowedSessions).toBe(3); }); test('should validate patient portal access permissions', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'restricted@test.com', password: 'password' }; // Mock restricted portal access mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'restricted_token', user: { id: 'patient_restricted', email: 'restricted@test.com', role: 'patient', portalAccess: false }, restrictions: { reason: 'Account under review', contactSupport: true } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.user.portalAccess).toBe(false); expect(result.data.restrictions.reason).toBe('Account under review'); }); test('should handle two-factor authentication for patient accounts', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient2fa@test.com', password: 'password', twoFactorCode: '123456' }; // Mock 2FA verification mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_2fa_token', user: { id: 'patient_2fa', email: 'patient2fa@test.com', role: 'patient', twoFactorEnabled: true }, twoFactorVerified: true } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.user.twoFactorEnabled).toBe(true); expect(result.data.twoFactorVerified).toBe(true); }); test('should handle expired patient accounts', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'expired@test.com', password: 'password' }; // Mock expired account mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', null, true, { response: { status: 403, data: { error: 'Patient account has expired', expirationDate: '2024-12-31', renewalRequired: true } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should validate patient data access scope', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'password' }; // Mock login with data access scope const mockPatient = mockFactory.healthcareMocks.createHIPAACompliantData('patient', 'patient'); mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_scope_token', user: mockPatient, dataAccessScope: { ownDataOnly: true, medicalRecords: true, prescriptions: true, appointments: true, billing: false // Limited billing access } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.dataAccessScope.ownDataOnly).toBe(true); expect(result.data.dataAccessScope.medicalRecords).toBe(true); expect(result.data.dataAccessScope.billing).toBe(false); }); test('should handle patient consent verification', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'password' }; // Mock login with consent verification mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_consent_token', user: { id: 'patient_consent', email: 'patient@test.com', role: 'patient' }, consentStatus: { hipaaConsent: true, dataProcessingConsent: true, marketingConsent: false, lastUpdated: '2025-01-01' } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.consentStatus.hipaaConsent).toBe(true); expect(result.data.consentStatus.dataProcessingConsent).toBe(true); expect(result.data.consentStatus.marketingConsent).toBe(false); }); }); describe('Patient Portal Feature Access Tests', () => { test('should validate patient portal feature availability', async () => { const toolName = 'patient_create_patientlogin'; const parameters = { email: 'patient@test.com', password: 'password' }; // Mock login with feature access mockFactory.httpMocks.mockRequest('POST', '/api/patient/login', { status: 200, data: { success: true, token: 'patient_features_token', user: { id: 'patient_features', email: 'patient@test.com', role: 'patient' }, portalFeatures: { viewMedicalRecords: true, scheduleAppointments: true, viewPrescriptions: true, messaging: true, billing: false, labResults: true, telehealth: true } } }); const result = await toolGenerator.executeTool(toolName, parameters); expect(result.data.portalFeatures.viewMedicalRecords).toBe(true); expect(result.data.portalFeatures.scheduleAppointments).toBe(true); expect(result.data.portalFeatures.billing).toBe(false); }); }); });