Files

91 lines
3.0 KiB
Swift

import Testing
import GRDB
@testable import MailStore
@testable import Models
@Suite("MailStore Search & Queries")
struct SearchTests {
func makeStore() throws -> MailStore {
try MailStore(dbWriter: DatabaseSetup.openInMemoryDatabase())
}
func seedData(_ store: MailStore) throws {
try store.insertAccount(AccountRecord(
id: "acc1", name: "Personal", email: "me@example.com",
imapHost: "imap.example.com", imapPort: 993
))
try store.upsertMailbox(MailboxRecord(
id: "mb1", accountId: "acc1", name: "INBOX", uidValidity: 1, uidNext: 100
))
try store.insertMessages([
MessageRecord(
id: "m1", accountId: "acc1", mailboxId: "mb1", uid: 1,
messageId: "msg001@example.com", inReplyTo: nil, refs: nil,
subject: "Quarterly planning meeting", fromAddress: "alice@example.com",
fromName: "Alice Johnson", toAddresses: nil, ccAddresses: nil,
date: "2024-03-08T10:00:00Z", snippet: "Let's discuss Q2 goals",
bodyText: "Let's discuss Q2 goals and roadmap priorities.", bodyHtml: nil,
isRead: false, isFlagged: false, size: 1024
),
MessageRecord(
id: "m2", accountId: "acc1", mailboxId: "mb1", uid: 2,
messageId: "msg002@example.com", inReplyTo: nil, refs: nil,
subject: "Invoice #4521", fromAddress: "billing@vendor.com",
fromName: "Billing Dept", toAddresses: nil, ccAddresses: nil,
date: "2024-03-07T09:00:00Z", snippet: "Please find attached",
bodyText: "Your invoice for March is attached.", bodyHtml: nil,
isRead: true, isFlagged: false, size: 2048
),
])
}
@Test("FTS5 search finds messages by subject")
func searchBySubject() throws {
let store = try makeStore()
try seedData(store)
let results = try store.search(query: "quarterly")
#expect(results.count == 1)
#expect(results[0].id == "m1")
}
@Test("FTS5 search finds messages by body text")
func searchByBody() throws {
let store = try makeStore()
try seedData(store)
let results = try store.search(query: "roadmap")
#expect(results.count == 1)
#expect(results[0].id == "m1")
}
@Test("FTS5 search finds messages by sender name")
func searchBySender() throws {
let store = try makeStore()
try seedData(store)
let results = try store.search(query: "alice")
#expect(results.count == 1)
#expect(results[0].fromName == "Alice Johnson")
}
@Test("FTS5 search returns empty for no matches")
func searchNoMatch() throws {
let store = try makeStore()
try seedData(store)
let results = try store.search(query: "nonexistent")
#expect(results.isEmpty)
}
@Test("thread summaries include unread count and senders")
func threadSummaries() throws {
let store = try makeStore()
try seedData(store)
let reconstructor = ThreadReconstructor(store: store)
let messages = try store.messages(mailboxId: "mb1")
try reconstructor.processMessages(messages)
let summaries = try store.threadSummaries(accountId: "acc1")
#expect(summaries.count == 2)
// First thread (most recent) should be "Quarterly planning meeting"
#expect(summaries[0].subject == "Quarterly planning meeting")
#expect(summaries[0].unreadCount == 1)
}
}