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

311 lines
8.2 KiB
JavaScript

/**
* @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();