/** * @fileoverview Tests for public data access MCP tools * Tests email checking, user validation, and public data endpoints */ import { describe, test, expect, beforeEach, afterEach } from '@jest/globals'; import { mockFactory } from '../mocks/mockFactory.js'; describe('Public Data Access Tools', () => { let mockEnv; let toolGenerator; beforeEach(() => { mockEnv = mockFactory.createMockEnvironment({ authTypes: ['public'], enableHttpMocks: true, enableHealthcareMocks: true }); toolGenerator = mockEnv.toolGenerator; }); afterEach(() => { mockFactory.resetAllMocks(); }); describe('public_create_checkEmail', () => { test('should check if email is available', async () => { // Setup const toolName = 'public_create_checkEmail'; const parameters = { email: 'newuser@test.com' }; // Mock email availability response mockFactory.httpMocks.mockRequest('POST', '/api/check-email', { status: 200, data: { available: true, email: 'newuser@test.com', message: 'Email is available' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.available).toBe(true); expect(result.data.email).toBe('newuser@test.com'); }); test('should detect existing email', async () => { // Setup const toolName = 'public_create_checkEmail'; const parameters = { email: 'existing@test.com' }; // Mock existing email response mockFactory.httpMocks.mockRequest('POST', '/api/check-email', { status: 200, data: { available: false, email: 'existing@test.com', message: 'Email is already in use' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.available).toBe(false); }); test('should validate email format', async () => { const toolName = 'public_create_checkEmail'; const parameters = { email: 'invalid-email-format' }; await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); describe('public_create_checkUser', () => { test('should check if provider exists', async () => { // Setup const toolName = 'public_create_checkUser'; const parameters = { email: 'provider@test.com' }; // Mock provider exists response mockFactory.httpMocks.mockRequest('POST', '/api/check-user', { status: 200, data: { exists: true, email: 'provider@test.com', userType: 'provider', message: 'Provider found' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.exists).toBe(true); expect(result.data.userType).toBe('provider'); }); test('should handle non-existent user', async () => { // Setup const toolName = 'public_create_checkUser'; const parameters = { email: 'nonexistent@test.com' }; // Mock user not found response mockFactory.httpMocks.mockRequest('POST', '/api/check-user', { status: 200, data: { exists: false, email: 'nonexistent@test.com', message: 'User not found' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.exists).toBe(false); }); }); describe('public_get_appointmentParticipant', () => { test('should get appointment participants', async () => { // Setup const toolName = 'public_get_appointmentParticipant'; const parameters = { appointmentId: 'appointment_123' }; // Mock appointment participants response mockFactory.httpMocks.mockRequest('GET', '/api/appointment-participants/appointment_123', { status: 200, data: { appointmentId: 'appointment_123', participants: [ { id: 'participant_1', name: 'Dr. Smith', role: 'provider', email: 'dr.smith@test.com' }, { id: 'participant_2', name: 'John Doe', role: 'patient', email: 'john.doe@test.com' } ] } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.participants).toHaveLength(2); expect(result.data.participants[0].role).toBe('provider'); expect(result.data.participants[1].role).toBe('patient'); }); test('should handle invalid appointment ID', async () => { // Setup const toolName = 'public_get_appointmentParticipant'; const parameters = { appointmentId: 'invalid_appointment' }; // Mock not found response mockFactory.httpMocks.mockRequest('GET', '/api/appointment-participants/invalid_appointment', null, true, { response: { status: 404, data: { error: 'Appointment not found' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); describe('public_create_patientavailableSlot', () => { test('should get available appointment slots', async () => { // Setup const toolName = 'public_create_patientavailableSlot'; const parameters = { date: '2025-07-15' }; // Mock available slots response mockFactory.httpMocks.mockRequest('POST', '/api/patient/available-slots/2025-07-15', { status: 200, data: { date: '2025-07-15', availableSlots: [ { time: '09:00', duration: 30, providerId: 'provider_123', providerName: 'Dr. Smith' }, { time: '10:30', duration: 30, providerId: 'provider_123', providerName: 'Dr. Smith' }, { time: '14:00', duration: 60, providerId: 'provider_456', providerName: 'Dr. Johnson' } ] } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.availableSlots).toHaveLength(3); expect(result.data.date).toBe('2025-07-15'); }); test('should validate date format', async () => { const toolName = 'public_create_patientavailableSlot'; const parameters = { date: 'invalid-date' }; await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should handle no available slots', async () => { // Setup const toolName = 'public_create_patientavailableSlot'; const parameters = { date: '2025-12-25' // Holiday - no slots }; // Mock no slots response mockFactory.httpMocks.mockRequest('POST', '/api/patient/available-slots/2025-12-25', { status: 200, data: { date: '2025-12-25', availableSlots: [], message: 'No available slots for this date' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.availableSlots).toHaveLength(0); }); }); describe('public_create_patientBookAppointment', () => { test('should successfully book appointment', async () => { // Setup const toolName = 'public_create_patientBookAppointment'; const parameters = { patient_id: 'patient_123', start_time: '09:00', end_time: '09:30', practitioner_id: 'provider_456', appointment_date: '2025-07-15', appointment_time: '09:00', notes: 'Annual checkup', order_id: 789 }; // Mock successful booking response mockFactory.httpMocks.mockRequest('POST', '/api/patient-book-appointment', { status: 201, data: { success: true, appointment: { id: 'appointment_789', patientId: 'patient_123', practitionerId: 'provider_456', date: '2025-07-15', time: '09:00', status: 'scheduled' }, message: 'Appointment booked successfully' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.appointment.status).toBe('scheduled'); expect(result.data.appointment.date).toBe('2025-07-15'); }); test('should handle scheduling conflicts', async () => { // Setup const toolName = 'public_create_patientBookAppointment'; const parameters = { patient_id: 'patient_123', start_time: '09:00', end_time: '09:30', practitioner_id: 'provider_456', appointment_date: '2025-07-15', appointment_time: '09:00' }; // Mock conflict response mockFactory.httpMocks.mockRequest('POST', '/api/patient-book-appointment', null, true, { response: { status: 409, data: { error: 'Time slot is no longer available' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); describe('Email Verification Tools', () => { describe('public_create_publicManageVerifyEmail', () => { test('should successfully verify email', async () => { // Setup const toolName = 'public_create_publicManageVerifyEmail'; const parameters = { token: 'verification_token_123', email: 'user@test.com' }; // Mock successful verification mockFactory.httpMocks.mockRequest('POST', '/api/public-manage-verify-email', { status: 200, data: { success: true, email: 'user@test.com', verified: true, message: 'Email verified successfully' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.verified).toBe(true); }); test('should handle invalid verification token', async () => { // Setup const toolName = 'public_create_publicManageVerifyEmail'; const parameters = { token: 'invalid_token', email: 'user@test.com' }; // Mock invalid token response mockFactory.httpMocks.mockRequest('POST', '/api/public-manage-verify-email', null, true, { response: { status: 400, data: { error: 'Invalid verification token' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); describe('public_create_publicManageResendVerification', () => { test('should successfully resend verification email', async () => { // Setup const toolName = 'public_create_publicManageResendVerification'; const parameters = { email: 'user@test.com' }; // Mock successful resend mockFactory.httpMocks.mockRequest('POST', '/api/public-manage-resend-verification', { status: 200, data: { success: true, email: 'user@test.com', message: 'Verification email sent' } }); // Execute const result = await toolGenerator.executeTool(toolName, parameters); // Assert expect(result.success).toBe(true); expect(result.data.message).toContain('Verification email sent'); }); }); }); describe('Data Access Security Tests', () => { test('should handle rate limiting for email checks', async () => { const toolName = 'public_create_checkEmail'; const parameters = { email: 'test@test.com' }; // Mock rate limit response mockFactory.httpMocks.mockRequest('POST', '/api/check-email', null, true, { response: { status: 429, data: { error: 'Too many requests' } } }); await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); test('should sanitize input parameters', async () => { const toolName = 'public_create_checkEmail'; const parameters = { email: '@test.com' }; // Should reject malicious input await expect(toolGenerator.executeTool(toolName, parameters)) .rejects.toThrow(); }); }); });