All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m26s
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
vi.unmock("../services/email.js");
|
|
|
|
const { mockSendMail } = vi.hoisted(() => ({
|
|
mockSendMail: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("nodemailer", () => ({
|
|
default: {
|
|
createTransport: vi.fn(() => ({
|
|
sendMail: mockSendMail,
|
|
})),
|
|
},
|
|
}));
|
|
|
|
vi.mock("../services/logger.js", () => ({
|
|
default: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() },
|
|
}));
|
|
|
|
import { sendVerificationEmail } from "../services/email.js";
|
|
|
|
describe("Email Service", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("sendVerificationEmail", () => {
|
|
it("constructs correct email with code", async () => {
|
|
mockSendMail.mockResolvedValueOnce({ messageId: "test-123" });
|
|
const result = await sendVerificationEmail("user@example.com", "654321");
|
|
|
|
expect(result).toBe(true);
|
|
expect(mockSendMail).toHaveBeenCalledOnce();
|
|
const opts = mockSendMail.mock.calls[0][0];
|
|
expect(opts.to).toBe("user@example.com");
|
|
expect(opts.subject).toContain("Verify");
|
|
expect(opts.text).toContain("654321");
|
|
expect(opts.html).toContain("654321");
|
|
});
|
|
|
|
it("returns false when SMTP fails", async () => {
|
|
mockSendMail.mockRejectedValueOnce(new Error("SMTP connection refused"));
|
|
const result = await sendVerificationEmail("user@example.com", "123456");
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("includes expiry notice in email body", async () => {
|
|
mockSendMail.mockResolvedValueOnce({ messageId: "test-456" });
|
|
await sendVerificationEmail("user@example.com", "111111");
|
|
const opts = mockSendMail.mock.calls[0][0];
|
|
expect(opts.text).toContain("15 minutes");
|
|
});
|
|
});
|
|
});
|