import { describe, expect, it, vi } from "vitest"; import type { MailSettings } from "../lib/mail-settings"; import { sendContactMessage, sendTestEmail } from "../lib/mail"; function createMailSettings(overrides: Partial = {}): MailSettings { return { smtp: { host: "smtp.example.com", port: 587, secure: false, username: "mailer@example.com", password: "secret", ...overrides.smtp, }, sender: { email: "hello@example.com", name: "Studio Moh", ...overrides.sender, }, recipients: { contact: "contact@example.com", test: "test@example.com", ...overrides.recipients, }, }; } describe("mail delivery", () => { it("sends contact messages with reply-to", async () => { const sendMailMock = vi.fn().mockResolvedValue({}); const createTransport = vi.fn().mockReturnValue({ sendMail: sendMailMock, }); await sendContactMessage( { locale: "en", name: "Jane Doe", email: "jane@example.com", message: "Hello from the website contact form.", }, { settings: createMailSettings(), createTransport, }, ); expect(createTransport).toHaveBeenCalledWith({ host: "smtp.example.com", port: 587, secure: false, auth: { user: "mailer@example.com", pass: "secret", }, }); expect(sendMailMock).toHaveBeenCalledWith( expect.objectContaining({ to: "contact@example.com", subject: "New contact message", replyTo: "jane@example.com", }), ); expect(sendMailMock.mock.calls[0]?.[0].text).toContain("Hello from the website contact form."); }); it("falls back to the test recipient when contact recipient is empty", async () => { const sendMailMock = vi.fn().mockResolvedValue({}); const createTransport = vi.fn().mockReturnValue({ sendMail: sendMailMock, }); await sendContactMessage( { locale: "de", name: "Jane Doe", email: "jane@example.com", message: "Fallback recipient should still work.", }, { settings: createMailSettings({ recipients: { contact: "", test: "fallback@example.com", }, }), createTransport, }, ); expect(sendMailMock).toHaveBeenCalledWith( expect.objectContaining({ to: "fallback@example.com", }), ); }); it("sends backend test emails to the configured recipient", async () => { const sendMailMock = vi.fn().mockResolvedValue({}); const createTransport = vi.fn().mockReturnValue({ sendMail: sendMailMock, }); await sendTestEmail({ settings: createMailSettings(), createTransport, }); expect(sendMailMock).toHaveBeenCalledWith( expect.objectContaining({ to: "test@example.com", subject: "SMTP test email", }), ); }); it("fails when the transport rejects the test email", async () => { const createTransport = vi.fn().mockReturnValue({ sendMail: vi.fn().mockRejectedValue(new Error("Authentication failed.")), }); await expect( sendTestEmail({ settings: createMailSettings(), createTransport, }), ).rejects.toThrow("Authentication failed."); }); });