32 lines
1.6 KiB
TypeScript
32 lines
1.6 KiB
TypeScript
import { ServiceUnavailableException } from '@nestjs/common';
|
|
import { PasswordService } from './password.service';
|
|
|
|
describe('PasswordService', () => {
|
|
it('logs password reset mail delivery failures with stable error code', async () => {
|
|
const resetTokens = {
|
|
create: jest.fn((value) => value),
|
|
save: jest.fn(async (value) => ({ ...value, id: 'token-id' })),
|
|
delete: jest.fn().mockResolvedValue(undefined),
|
|
};
|
|
const service = new PasswordService(
|
|
resetTokens as any,
|
|
{ get: jest.fn((key: string) => (key === 'SMTP_HOST' ? 'smtp.example.com' : 'secret')), getOrThrow: jest.fn(() => 'secret') } as any,
|
|
{} as any,
|
|
{ findUserByEmail: jest.fn().mockResolvedValue({ id: 'user-1', email: 'maria@example.com' }) } as any,
|
|
{ sendPasswordResetMail: jest.fn().mockRejectedValue(new Error('SMTP unavailable')) } as any,
|
|
{ record: jest.fn().mockResolvedValue(undefined) } as any,
|
|
{ log: jest.fn().mockResolvedValue(undefined) } as any,
|
|
{ get: jest.fn(() => ({ correlationId: 'corr-1' })) } as any,
|
|
);
|
|
|
|
await expect(service.requestReset('maria@example.com')).rejects.toBeInstanceOf(ServiceUnavailableException);
|
|
expect((service as any).applicationErrorLogger.log).toHaveBeenCalledWith(expect.objectContaining({
|
|
code: 'PASSWORD_RESET_EMAIL_SEND_FAILED',
|
|
category: 'EMAIL',
|
|
requestContext: expect.objectContaining({ correlationId: 'corr-1', userId: 'user-1' }),
|
|
context: expect.objectContaining({ maskedRecipient: 'm***@example.com', mailProvider: 'smtp.example.com' }),
|
|
handled: true,
|
|
}));
|
|
});
|
|
});
|