Upstream maildev/maildev state of the touched files before 661742ab9d

This commit is contained in:
upstream committed 2026-10-02 15:57:49 +02:00
1 parent a10bcd3e4c
commit 27e7633a30
2 files changed
+411

No files matched your search

+111
View File
@@ -0,0 +1,111 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import net, { type AddressInfo } from 'node:net'
import nodemailer from 'nodemailer'
import { MemoryStorage, FileStorage } from '@maildev/core'
import { SMTPServer } from '../server.js'
/** Grab an ephemeral free port so parallel test files don't collide. */
function freePort(): Promise<number> {
return new Promise((resolve) => {
const srv = net.createServer()
srv.listen(0, '127.0.0.1', () => {
const port = (srv.address() as AddressInfo).port
srv.close(() => resolve(port))
})
})
}
describe('relay delivery status', () => {
let sourceDir: string
let destDir: string
let sourceStore: MemoryStorage
let destStore: MemoryStorage
let source: SMTPServer
let dest: SMTPServer
let sourcePort: number
let destPort: number
beforeEach(async () => {
sourceDir = await mkdtemp(join(tmpdir(), 'maildev-relay-src-'))
destDir = await mkdtemp(join(tmpdir(), 'maildev-relay-dst-'))
sourceStore = new MemoryStorage()
destStore = new MemoryStorage()
await sourceStore.initialize()
await destStore.initialize()
sourcePort = await freePort()
destPort = await freePort()
dest = new SMTPServer({ storage: destStore, mailDir: destDir, port: destPort, host: '127.0.0.1' })
await dest.start()
source = new SMTPServer({ storage: sourceStore, mailDir: sourceDir, port: sourcePort, host: '127.0.0.1' })
await source.start()
source.setupRelay({ host: '127.0.0.1', port: destPort, secure: false })
source.setAutoRelay({ enabled: true })
})
afterEach(async () => {
await source.stop()
await dest.stop()
await rm(sourceDir, { recursive: true, force: true })
await rm(destDir, { recursive: true, force: true })
})
const sendTo = (port: number) => {
const transport = nodemailer.createTransport({ host: '127.0.0.1', port, secure: false })
return transport.sendMail({
from: 'a@example.com',
to: 'b@example.com',
subject: 'relay me',
text: 'hello',
})
}
it('records relayedAt and relayedTo on the stored email after an auto-relay', async () => {
await sendTo(sourcePort)
const stored = (await sourceStore.getAll())[0]!
expect(stored.relayedAt).toBeInstanceOf(Date)
expect(stored.relayedTo).toContain('b@example.com')
// The relay actually delivered it downstream.
expect(await destStore.getAll()).toHaveLength(1)
})
it('leaves relayedAt unset for an email that was never relayed', async () => {
await sendTo(destPort)
const stored = (await destStore.getAll())[0]!
expect(stored.relayedAt).toBeUndefined()
expect(stored.relayedTo).toBeUndefined()
})
it('restores relay status from disk on a fresh FileStorage-backed server', async () => {
// Use a disk-backed source so the relay status is persisted to a sidecar.
await source.stop()
const fileStore = new FileStorage({ mailDirectory: sourceDir })
await fileStore.initialize()
source = new SMTPServer({ storage: fileStore, mailDir: sourceDir, port: sourcePort, host: '127.0.0.1' })
await source.start()
source.setupRelay({ host: '127.0.0.1', port: destPort, secure: false })
source.setAutoRelay({ enabled: true })
await sendTo(sourcePort)
const id = (await fileStore.getAll())[0]!.id
expect((await fileStore.getById(id))!.relayedAt).toBeInstanceOf(Date)
// Simulate a restart: a brand-new store + server reading the same directory.
await source.stop()
const restoredStore = new FileStorage({ mailDirectory: sourceDir })
await restoredStore.initialize()
source = new SMTPServer({ storage: restoredStore, mailDir: sourceDir, port: sourcePort, host: '127.0.0.1' })
await source.loadMailsFromDirectory()
const restored = (await restoredStore.getById(id))!
expect(restored.relayedAt).toBeInstanceOf(Date)
expect(restored.relayedTo).toContain('b@example.com')
})
})