first
This commit is contained in:
459
tests/public/data-access.test.js
Normal file
459
tests/public/data-access.test.js
Normal file
@@ -0,0 +1,459 @@
|
||||
/**
|
||||
* @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: '<script>alert("xss")</script>@test.com'
|
||||
};
|
||||
|
||||
// Should reject malicious input
|
||||
await expect(toolGenerator.executeTool(toolName, parameters))
|
||||
.rejects.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user