Files
mcp-tool/tests/public/index.test.js
nasir@endelospay.com 8c74b0e23f first
2025-07-11 20:22:12 +05:00

353 lines
12 KiB
JavaScript

/**
* @fileoverview Comprehensive test suite for all public MCP tools
* Runs all public tool tests and provides coverage reporting
*/
import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
import { mockFactory } from '../mocks/mockFactory.js';
describe('Public Tools Integration Tests', () => {
let mockEnv;
let toolGenerator;
beforeAll(async () => {
// Setup comprehensive mock environment
mockEnv = mockFactory.createMockEnvironment({
authTypes: ['public'],
enableHttpMocks: true,
enableAuthMocks: true,
enableHealthcareMocks: true
});
toolGenerator = mockEnv.toolGenerator;
// Setup all public endpoint mocks
setupPublicEndpointMocks();
});
afterAll(() => {
mockFactory.resetAllMocks();
});
/**
* Setup mock responses for all public endpoints
*/
function setupPublicEndpointMocks() {
// Login endpoints
const loginEndpoints = [
{ method: 'POST', path: '/api/login' },
{ method: 'POST', path: '/api/frontend/login' },
{ method: 'POST', path: '/api/admin/login' },
{ method: 'POST', path: '/api/login-partner-api' },
{ method: 'POST', path: '/api/affiliate-login-api' },
{ method: 'POST', path: '/api/network/login' },
{ method: 'POST', path: '/api/patient/login' },
{ method: 'POST', path: '/api/patient-login-api' },
{ method: 'POST', path: '/api/login-patient' }
];
loginEndpoints.forEach(endpoint => {
mockFactory.httpMocks.mockRequest(endpoint.method, endpoint.path, {
status: 200,
data: {
success: true,
token: `mock_token_${Date.now()}`,
user: { id: 'user_123', email: 'test@example.com' }
}
});
});
// Registration endpoints
const registrationEndpoints = [
{ method: 'POST', path: '/emr-api/provider-register' },
{ method: 'POST', path: '/api/register-patients' },
{ method: 'POST', path: '/api/register-patient' },
{ method: 'POST', path: '/api/affiliate-register-api' },
{ method: 'POST', path: '/api/partner-register-api' },
{ method: 'POST', path: '/api/network/register' },
{ method: 'POST', path: '/api/emr/provider/register' },
{ method: 'POST', path: '/api/patient/register-patient' }
];
registrationEndpoints.forEach(endpoint => {
mockFactory.httpMocks.mockRequest(endpoint.method, endpoint.path, {
status: 201,
data: {
success: true,
user: { id: 'new_user_123', email: 'newuser@example.com' },
message: 'Registration successful'
}
});
});
// Password management endpoints
const passwordEndpoints = [
{ method: 'POST', path: '/api/forgot-password' },
{ method: 'POST', path: '/api/frontend/forgot-password' },
{ method: 'POST', path: '/api/emr/provider/forgot-password' },
{ method: 'POST', path: '/api/password-reset' },
{ method: 'POST', path: '/api/frontend/reset-password' },
{ method: 'POST', path: '/api/emr/provider/reset-password' },
{ method: 'POST', path: '/api/set-password' },
{ method: 'POST', path: '/api/emr/set-password' },
{ method: 'POST', path: '/api/affiliate/set-password' },
{ method: 'POST', path: '/api/reset-password' }
];
passwordEndpoints.forEach(endpoint => {
mockFactory.httpMocks.mockRequest(endpoint.method, endpoint.path, {
status: 200,
data: {
success: true,
message: 'Password operation successful'
}
});
});
// Data access endpoints
mockFactory.httpMocks.mockRequest('POST', '/api/check-email', {
status: 200,
data: { available: true, email: 'test@example.com' }
});
mockFactory.httpMocks.mockRequest('POST', '/api/check-user', {
status: 200,
data: { exists: true, userType: 'provider' }
});
// Appointment endpoints
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' }
]
}
});
mockFactory.httpMocks.mockRequest('POST', '/api/patient-book-appointment', {
status: 201,
data: {
success: true,
appointment: { id: 'appointment_123', status: 'scheduled' }
}
});
// Verification endpoints
mockFactory.httpMocks.mockRequest('POST', '/api/public-manage-verify-email', {
status: 200,
data: { success: true, verified: true }
});
mockFactory.httpMocks.mockRequest('POST', '/api/public-manage-resend-verification', {
status: 200,
data: { success: true, message: 'Verification email sent' }
});
}
describe('Public Tools Coverage Test', () => {
test('should have all 77 public tools available', async () => {
const allTools = toolGenerator.generateAllTools();
const publicTools = allTools.filter(tool => tool.name.startsWith('public_'));
// Verify we have the expected number of public tools
expect(publicTools.length).toBeGreaterThanOrEqual(70); // Allow for some variance
// Verify tool naming convention
publicTools.forEach(tool => {
expect(tool.name).toMatch(/^public_[a-zA-Z]+_[a-zA-Z]+/);
expect(tool.description).toBeDefined();
expect(tool.inputSchema).toBeDefined();
});
});
test('should categorize public tools correctly', async () => {
const allTools = toolGenerator.generateAllTools();
const publicTools = allTools.filter(tool => tool.name.startsWith('public_'));
const categories = {
login: [],
registration: [],
password: [],
verification: [],
data: [],
appointment: [],
other: []
};
publicTools.forEach(tool => {
if (tool.name.includes('login') || tool.name.includes('Login')) {
categories.login.push(tool);
} else if (tool.name.includes('register') || tool.name.includes('Register')) {
categories.registration.push(tool);
} else if (tool.name.includes('password') || tool.name.includes('Password') || tool.name.includes('setPassword')) {
categories.password.push(tool);
} else if (tool.name.includes('verify') || tool.name.includes('Verify') || tool.name.includes('verification')) {
categories.verification.push(tool);
} else if (tool.name.includes('check') || tool.name.includes('Check') || tool.name.includes('get')) {
categories.data.push(tool);
} else if (tool.name.includes('appointment') || tool.name.includes('Appointment') || tool.name.includes('slot')) {
categories.appointment.push(tool);
} else {
categories.other.push(tool);
}
});
// Verify we have tools in each major category
expect(categories.login.length).toBeGreaterThan(5);
expect(categories.registration.length).toBeGreaterThan(5);
expect(categories.password.length).toBeGreaterThan(5);
console.log('Public Tools Distribution:');
Object.entries(categories).forEach(([category, tools]) => {
console.log(` ${category}: ${tools.length} tools`);
});
});
});
describe('Public Tools Parameter Validation', () => {
test('should validate required parameters for login tools', async () => {
const loginTools = [
'public_create_login',
'public_create_frontendlogin',
'public_create_adminlogin'
];
for (const toolName of loginTools) {
const tool = toolGenerator.getTool(toolName);
if (tool) {
expect(tool.inputSchema.required).toBeDefined();
expect(tool.inputSchema.required.length).toBeGreaterThan(0);
}
}
});
test('should validate required parameters for registration tools', async () => {
const registrationTools = [
'public_create_emrApiproviderRegister',
'public_create_registerPatient',
'public_create_affiliateRegisterApi'
];
for (const toolName of registrationTools) {
const tool = toolGenerator.getTool(toolName);
if (tool) {
expect(tool.inputSchema.required).toBeDefined();
expect(tool.inputSchema.required.length).toBeGreaterThan(1);
}
}
});
});
describe('Public Tools Error Handling', () => {
test('should handle network errors gracefully', async () => {
// Mock network error for all endpoints
mockFactory.httpMocks.setDefaultResponse('POST', null);
mockFactory.httpMocks.setDefaultResponse('GET', null);
const testTool = 'public_create_login';
const parameters = { username: 'test', password: 'test' };
// Should handle network errors without crashing
await expect(toolGenerator.executeTool(testTool, parameters))
.rejects.toThrow();
});
test('should handle malformed responses', async () => {
// Mock malformed response
mockFactory.httpMocks.mockRequest('POST', '/api/login', {
status: 200,
data: 'invalid json response'
});
const testTool = 'public_create_login';
const parameters = { username: 'test', password: 'test' };
await expect(toolGenerator.executeTool(testTool, parameters))
.rejects.toThrow();
});
});
describe('Public Tools Security Tests', () => {
test('should not expose sensitive information in logs', async () => {
const testTool = 'public_create_login';
const parameters = {
username: 'testuser',
password: 'supersecretpassword123!'
};
await toolGenerator.executeTool(testTool, parameters);
// Check request history doesn't contain password
const history = mockFactory.httpMocks.getRequestHistory();
const loginRequest = history.find(req => req.url === '/api/login');
if (loginRequest) {
const requestString = JSON.stringify(loginRequest);
expect(requestString).not.toContain('supersecretpassword123!');
}
});
test('should validate input sanitization', async () => {
const testTool = 'public_create_checkEmail';
const maliciousEmail = '<script>alert("xss")</script>@test.com';
await expect(toolGenerator.executeTool(testTool, { email: maliciousEmail }))
.rejects.toThrow();
});
});
describe('Public Tools Performance Tests', () => {
test('should complete tool execution within reasonable time', async () => {
const testTool = 'public_create_checkEmail';
const parameters = { email: 'test@example.com' };
const startTime = Date.now();
await toolGenerator.executeTool(testTool, parameters);
const endTime = Date.now();
const executionTime = endTime - startTime;
expect(executionTime).toBeLessThan(5000); // Should complete within 5 seconds
});
test('should handle concurrent tool executions', async () => {
const testTool = 'public_create_checkEmail';
const promises = [];
// Execute 10 concurrent requests
for (let i = 0; i < 10; i++) {
const parameters = { email: `test${i}@example.com` };
promises.push(toolGenerator.executeTool(testTool, parameters));
}
const results = await Promise.allSettled(promises);
// All requests should complete (either fulfilled or rejected)
expect(results.length).toBe(10);
results.forEach(result => {
expect(['fulfilled', 'rejected']).toContain(result.status);
});
});
});
describe('Public Tools Integration', () => {
test('should maintain consistent response format across tools', async () => {
const testTools = [
{ name: 'public_create_login', params: { username: 'test', password: 'test' } },
{ name: 'public_create_checkEmail', params: { email: 'test@example.com' } },
{ name: 'public_create_forgotPassword', params: { email: 'test@example.com' } }
];
for (const { name, params } of testTools) {
const result = await toolGenerator.executeTool(name, params);
// All tools should return consistent structure
expect(result).toHaveProperty('success');
expect(result).toHaveProperty('data');
expect(typeof result.success).toBe('boolean');
}
});
});
});