macsync/@packages/imail/Tests/IMailSyncTests/SenderTests.swift

90 lines
2.9 KiB
Swift

import Foundation
import MacSyncShared
import Testing
@testable import IMailSync
@MainActor
final class FakeMailApplier: MailSendApplying {
private(set) var sent: [MailSendPayload] = []
var result: SendQueueApplyResult = .sent
func send(_ payload: MailSendPayload) async -> SendQueueApplyResult {
sent.append(payload)
return result
}
}
@Suite("MailSender dispatch")
@MainActor
struct MailSenderTests {
private func makeItem(action: String, payload: MailSendPayload) -> PendingMailSend {
PendingMailSend(id: "item-1", action: action, payload: payload, createdAt: "2026-05-13T00:00:00Z")
}
@Test("FakeApplier records the payload and returns .sent")
func dispatchSent() async {
let fake = FakeMailApplier()
fake.result = .sent
let payload = MailSendPayload(
to: "alice@example.com",
subject: "Hello",
body: "Hi"
)
let result = await fake.send(payload)
guard case .sent = result else {
Issue.record("expected .sent, got \(result)")
return
}
#expect(fake.sent.count == 1)
#expect(fake.sent.first?.to == "alice@example.com")
#expect(fake.sent.first?.subject == "Hello")
}
@Test("Failed sends surface a reason")
func dispatchFailed() async {
let fake = FakeMailApplier()
fake.result = .failed(reason: "Mail.app unavailable")
let result = await fake.send(MailSendPayload(to: "x@example.com", subject: "s", body: "b"))
guard case .failed(let reason) = result else {
Issue.record("expected .failed")
return
}
#expect(reason == "Mail.app unavailable")
}
@Test("PendingMailSend decodes from JSON")
func decodePending() throws {
let json = """
{
"id": "abc-123",
"action": "send_mail",
"createdAt": "2026-05-13T00:00:00Z",
"payload": {
"to": "alice@example.com",
"cc": ["c@example.com"],
"subject": "Hi",
"body": "Body",
"isHtml": false
}
}
""".data(using: .utf8)!
let item = try JSONDecoder().decode(PendingMailSend.self, from: json)
#expect(item.id == "abc-123")
#expect(item.action == "send_mail")
#expect(item.payload.to == "alice@example.com")
#expect(item.payload.cc == ["c@example.com"])
#expect(item.payload.isHtml == false)
}
@Test("MailSendPayload tolerates omitted optionals")
func decodeMinimal() throws {
let json = """
{ "to": "a@example.com", "subject": "s", "body": "b" }
""".data(using: .utf8)!
let payload = try JSONDecoder().decode(MailSendPayload.self, from: json)
#expect(payload.to == "a@example.com")
#expect(payload.cc == nil)
#expect(payload.bcc == nil)
#expect(payload.isHtml == nil)
}
}