import { describe, it, expect, vi } from "vitest" // Mock tls to simulate an SMTP server over implicit TLS let lastWrites: string[] = [] vi.mock("tls", () => { type Listener = (...args: unknown[]) => void class MockSocket { listeners: Record = {} writes: string[] = [] // very small state machine of server responses private step = 0 private enqueue(messages: string | string[], type: "data" | "end" = "data") { const chunks = Array.isArray(messages) ? messages : [messages] chunks.forEach((chunk, index) => { const delay = index === 0 ? 0 : 1 setTimeout(() => { if (type === "end") { void chunk this.emit("end") return } this.emit("data", Buffer.from(chunk)) }, delay) }) } on(event: string, cb: Listener) { this.listeners[event] = this.listeners[event] || [] this.listeners[event].push(cb) return this } removeListener(event: string, cb: Listener) { if (!this.listeners[event]) return this this.listeners[event] = this.listeners[event].filter((f) => f !== cb) return this } emit(event: string, data?: unknown) { for (const cb of this.listeners[event] || []) cb(data) } write(chunk: string) { this.writes.push(chunk) const line = chunk.replace(/\r?\n/g, "") // Respond depending on client command if (this.step === 0 && line.startsWith("EHLO")) { this.step = 1 this.enqueue(["250-local\r\n", "250 OK\r\n"]) } else if (this.step === 1 && line === "AUTH LOGIN") { this.step = 2 this.enqueue("334 VXNlcm5hbWU6\r\n") } else if (this.step === 2) { this.step = 3 this.enqueue("334 UGFzc3dvcmQ6\r\n") } else if (this.step === 3) { this.step = 4 this.enqueue("235 Auth OK\r\n") } else if (this.step === 4 && line.startsWith("MAIL FROM:")) { this.step = 5 this.enqueue("250 FROM OK\r\n") } else if (this.step === 5 && line.startsWith("RCPT TO:")) { this.step = 6 this.enqueue("250 RCPT OK\r\n") } else if (this.step === 6 && line === "DATA") { this.step = 7 this.enqueue("354 End data with .\r\n") } else if (this.step === 7 && line.endsWith(".")) { this.step = 8 this.enqueue("250 Queued\r\n") } else if (this.step === 8 && line === "QUIT") { this.enqueue("", "end") } } end() {} } function connect(_port: number, _host: string, _opts: unknown, cb?: () => void) { const socket = new MockSocket() lastWrites = socket.writes // initial server greeting setTimeout(() => { cb?.() socket.emit("data", Buffer.from("220 Mock SMTP Ready\r\n")) }, 0) return socket as unknown as NodeJS.WritableStream & { on: MockSocket["on"] } } return { default: { connect }, connect, __getLastWrites: () => lastWrites } }) describe("sendSmtpMail", () => { it("performs AUTH LOGIN and sends a message", async () => { const { sendSmtpMail } = await import("@/server/email-smtp") await expect( sendSmtpMail( { host: "smtp.mock", port: 465, username: "user@example.com", password: "secret", from: "Sender ", }, "rcpt@example.com", "Subject here", "

Hello

" ) ).resolves.toBeUndefined() }) it("extracts envelope address from parentheses or raw email", async () => { const { sendSmtpMail } = await import("@/server/email-smtp") const tlsMock = (await import("tls")) as unknown as { __getLastWrites: () => string[] } await sendSmtpMail( { host: "smtp.mock", port: 465, username: "user@example.com", password: "secret", from: "Chatwoot chat@esdrasrenan.com.br (chat@esdrasrenan.com.br)", }, "rcpt@example.com", "Subject", "

Hi

" ) const writes = tlsMock.__getLastWrites() expect(writes.some((w) => /MAIL FROM:\r\n/.test(w))).toBe(true) }) })