import Foundation import Testing @testable import MikeMail @MainActor struct MailWorkflowTests { @Test func searchScopesAndExpressions() { let mail = MailMessage(id: "1", sender: "anna@example.com", recipient: "", subject: "Rechnung 2026", date: Date(), body: "Betrag: 123,45 EUR", attachments: []) #expect(MailSearch(text: "123,45", subject: false, sender: false, body: true, regularExpression: false).matches(mail)) #expect(!MailSearch(text: "123,45", subject: true, sender: true, body: false, regularExpression: false).matches(mail)) #expect(MailSearch(text: #"Rechnung \d{4}$"#, subject: true, sender: false, body: false, regularExpression: true).matches(mail)) #expect(MailSearch(text: "^ANNA@", subject: false, sender: true, body: false, regularExpression: true).matches(mail)) let invalid = MailSearch(text: "[", subject: true, sender: true, body: true, regularExpression: true) #expect(invalid.error != nil) #expect(!invalid.matches(mail)) } @Test func dragSelectionAndMailboxNames() { let ids: Set = ["account:folder:1:2", "account:folder:1:9"] #expect(Set(MailDrag.decode(MailDrag.encode(ids))) == ids) #expect(MailDrag.decode("untrusted input").isEmpty) for name in ["Büro & Reisen", "日本語", "ASCII", "📨"] { #expect(IMAPClient.decodeMailbox(IMAPClient.encodeMailbox(name)) == name) } #expect(AttachmentList.safeName("../../file.txt") == "file.txt") #expect(AttachmentList.safeName(#"C:\temp\file.pdf"#) == "file.pdf") #expect(AttachmentList.safeName("..") == "Anhang") } @Test func unifiedFoldersAndAccountOrderSurviveReopen() async throws { let root = FileManager.default.temporaryDirectory.appending(path: UUID().uuidString) defer { try? FileManager.default.removeItem(at: root) } let archive = try MailArchive(root: root) let a = MailAccount(name: "A"), b = MailAccount(name: "B") let inboxA = MailFolder(accountID: a.id, path: "INBOX", name: "Posteingang") let inboxB = MailFolder(accountID: b.id, path: "INBOX", name: "Posteingang") let trash = MailFolder(accountID: a.id, path: "Deleted", name: "Gelöscht", specialUse: ["\\trash"]) try archive.saveConfiguration(ArchiveConfiguration(accounts: [a, b], folders: [a.id: [inboxA, trash], b.id: [inboxB]], recipients: [])) let raw = Data("Subject: Same\r\n\r\nBody".utf8) for folder in [inboxA, inboxB, trash] { try archive.store(raw: raw, folderID: folder.id, validity: "1", uid: "1", flags: []) } let store = MailStore(archive: archive) await store.load(folderID: "unified:inbox") #expect(store.messages.count == 2) #expect(Set(store.messages.map(\.id)).count == 2) await store.load(folderID: "unified:trash") #expect(store.messages.count == 1) #expect(store.selectionContainsTrash(store.messages.map(\.id))) store.reorderAccount(b.id, before: a.id) let reopened = try MailArchive(root: root) #expect(try reopened.configuration()?.accounts.map(\.id) == [b.id, a.id]) } }