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

456 lines
13 KiB
JavaScript

/**
* @fileoverview Tests for public password management MCP tools
* Tests password reset, forgot password, and set password functionality
*/
import { describe, test, expect, beforeEach, afterEach } from "@jest/globals";
import { mockFactory } from "../mocks/mockFactory.js";
describe("Public Password Management Tools", () => {
let mockEnv;
let toolGenerator;
beforeEach(() => {
mockEnv = mockFactory.createMockEnvironment({
authTypes: ["public"],
enableHttpMocks: true,
});
toolGenerator = mockEnv.toolGenerator;
});
afterEach(() => {
mockFactory.resetAllMocks();
});
describe("public_create_forgotPassword", () => {
test("should successfully initiate password reset", async () => {
// Setup
const toolName = "public_create_forgotPassword";
const parameters = {
email: "user@test.com",
};
// Mock successful forgot password response
mockFactory.httpMocks.mockRequest("POST", "/api/forgot-password", {
status: 200,
data: {
success: true,
message: "Password reset email sent successfully",
email: "user@test.com",
},
});
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Password reset email sent");
});
test("should validate email format", async () => {
const toolName = "public_create_forgotPassword";
const parameters = {
email: "invalid-email-format",
};
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
});
test("should handle non-existent email gracefully", async () => {
const toolName = "public_create_forgotPassword";
const parameters = {
email: "nonexistent@test.com",
};
// Mock response for non-existent email (should still return success for security)
mockFactory.httpMocks.mockRequest("POST", "/api/forgot-password", {
status: 200,
data: {
success: true,
message: "If the email exists, a reset link has been sent",
},
});
const result = await toolGenerator.executeTool(toolName, parameters);
expect(result.success).toBe(true);
});
});
describe("public_create_frontendforgotPassword", () => {
test("should successfully initiate patient password reset", async () => {
// Setup
const toolName = "public_create_frontendforgotPassword";
const parameters = {
email: "patient@test.com",
};
// Mock successful patient forgot password response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/frontend/forgot-password",
{
status: 200,
data: {
success: true,
message: "Patient password reset email sent",
email: "patient@test.com",
},
}
);
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Patient password reset");
});
});
describe("public_create_providerforgotPassword", () => {
test("should successfully initiate provider password reset", async () => {
// Setup
const toolName = "public_create_providerforgotPassword";
const parameters = {
email: "provider@test.com",
};
// Mock successful provider forgot password response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/emr/provider/forgot-password",
{
status: 200,
data: {
success: true,
message: "Provider password reset email sent",
email: "provider@test.com",
},
}
);
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Provider password reset");
});
});
describe("public_create_passwordReset", () => {
test("should successfully reset password with valid token", async () => {
// Setup
const toolName = "public_create_passwordReset";
const parameters = {
token: "valid_reset_token_123",
email: "user@test.com",
password: "NewSecurePass123!",
password_confirmation: "NewSecurePass123!",
};
// Mock successful password reset
mockFactory.httpMocks.mockRequest("POST", "/api/password-reset", {
status: 200,
data: {
success: true,
message: "Password reset successfully",
email: "user@test.com",
},
});
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Password reset successfully");
});
test("should validate password confirmation match", async () => {
const toolName = "public_create_passwordReset";
const parameters = {
token: "valid_reset_token_123",
email: "user@test.com",
password: "NewSecurePass123!",
password_confirmation: "DifferentPassword123!",
};
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
});
test("should handle invalid reset token", async () => {
const toolName = "public_create_passwordReset";
const parameters = {
token: "invalid_token",
email: "user@test.com",
password: "NewSecurePass123!",
password_confirmation: "NewSecurePass123!",
};
// Mock invalid token response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/password-reset",
null,
true,
{
response: {
status: 400,
data: { error: "Invalid or expired reset token" },
},
}
);
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
});
test("should handle expired reset token", async () => {
const toolName = "public_create_passwordReset";
const parameters = {
token: "expired_token_456",
email: "user@test.com",
password: "NewSecurePass123!",
password_confirmation: "NewSecurePass123!",
};
// Mock expired token response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/password-reset",
null,
true,
{
response: {
status: 410,
data: { error: "Reset token has expired" },
},
}
);
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
});
});
describe("public_create_frontendresetPassword", () => {
test("should successfully reset patient password", async () => {
// Setup
const toolName = "public_create_frontendresetPassword";
const parameters = {
email: "patient@test.com",
password: "NewPatientPass123!",
password_confirmation: "NewPatientPass123!",
token: "patient_reset_token_789",
};
// Mock successful patient password reset
mockFactory.httpMocks.mockRequest(
"POST",
"/api/frontend/reset-password",
{
status: 200,
data: {
success: true,
message: "Patient password reset successfully",
email: "patient@test.com",
},
}
);
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Patient password reset");
});
});
describe("public_create_setPassword", () => {
test("should successfully set password with valid token", async () => {
// Setup
const toolName = "public_create_setPassword";
const parameters = {
password: "NewPassword123!",
password_confirmation: "NewPassword123!",
token: "set_password_token_101",
};
// Mock successful password set
mockFactory.httpMocks.mockRequest("POST", "/api/set-password", {
status: 200,
data: {
success: true,
message: "Password set successfully",
},
});
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("Password set successfully");
});
test("should validate password strength requirements", async () => {
const toolName = "public_create_setPassword";
// Test weak passwords
const weakPasswords = [
"123", // Too short
"password", // No numbers/special chars
"12345678", // Only numbers
"PASSWORD", // Only uppercase
"password123", // No special characters
];
for (const weakPassword of weakPasswords) {
const parameters = {
password: weakPassword,
password_confirmation: weakPassword,
token: "valid_token",
};
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
}
});
});
describe("public_create_emrsetPassword", () => {
test("should successfully set EMR password", async () => {
// Setup
const toolName = "public_create_emrsetPassword";
const parameters = {
password: "EMRPassword123!",
password_confirmation: "EMRPassword123!",
token: "emr_token_202",
};
// Mock successful EMR password set
mockFactory.httpMocks.mockRequest("POST", "/api/emr/set-password", {
status: 200,
data: {
success: true,
message: "EMR password set successfully",
},
});
// Execute
const result = await toolGenerator.executeTool(toolName, parameters);
// Assert
expect(result.success).toBe(true);
expect(result.data.message).toContain("EMR password set");
});
});
describe("Password Security Tests", () => {
test("should enforce password complexity requirements", async () => {
const toolName = "public_create_passwordReset";
// Test various password requirements
const testCases = [
{
password: "short",
description: "too short",
},
{
password: "nouppercase123!",
description: "no uppercase",
},
{
password: "NOLOWERCASE123!",
description: "no lowercase",
},
{
password: "NoNumbers!",
description: "no numbers",
},
{
password: "NoSpecialChars123",
description: "no special characters",
},
];
for (const testCase of testCases) {
const parameters = {
token: "valid_token",
email: "test@test.com",
password: testCase.password,
password_confirmation: testCase.password,
};
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
}
});
test("should handle rate limiting for password reset attempts", async () => {
const toolName = "public_create_forgotPassword";
const parameters = {
email: "ratelimited@test.com",
};
// Mock rate limit response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/forgot-password",
null,
true,
{
response: {
status: 429,
data: { error: "Too many password reset attempts" },
},
}
);
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow();
});
test("should not expose sensitive information in error messages", async () => {
const toolName = "public_create_passwordReset";
const parameters = {
token: "invalid_token",
email: "user@test.com",
password: "ValidPass123!",
password_confirmation: "ValidPass123!",
};
// Mock generic error response
mockFactory.httpMocks.mockRequest(
"POST",
"/api/password-reset",
null,
true,
{
response: {
status: 400,
data: { error: "Invalid request" }, // Generic error message
},
}
);
await expect(
toolGenerator.executeTool(toolName, parameters)
).rejects.toThrow("Invalid request");
});
});
});