Models: - Convert Conversation and ChatMessage to SwiftData @Model classes with a one-to-many relationship and cascade delete. - Rename ChatMessage.id to clientID and drop Conversation.id in favor of jid (the string id would clash with PersistentIdentifier). - Keep MessageReaction as a Codable value stored in an array attribute. Persistence: - Add ArchiveStore, a per-account ModelContainer/ModelContext that replaces the JSON ChatArchive with load/save/erase. - Add ArchiveMetadataRecord for the durable MAM checkpoints, cursor, locally deleted message IDs and roster contact JIDs. - Add LegacyArchiveImporter to import the old JSON snapshot once and delete the file afterwards, preserving existing history. AppModel: - Replace ChatArchive with ArchiveStore and persist via context.save(); insert new models and delete the replaced object on upsert merges so SwiftData never keeps an orphaned duplicate. Tests: - Replace ChatArchiveTests with ArchiveStoreTests (store round-trip and legacy import) and drop the now-obsolete Codable round-trip assertions.
31 lines
1.1 KiB
Swift
31 lines
1.1 KiB
Swift
import XCTest
|
|
@testable import Luma
|
|
|
|
final class MessageReactionTests: XCTestCase {
|
|
func testReactionUpdateKeepsOneCopyOfEachEmoji() {
|
|
XCTAssertEqual(
|
|
MessageReactionPolicy.sanitized(["👍", " 👍 ", "❤️", "a", "not emoji"]),
|
|
["👍", "❤️"]
|
|
)
|
|
}
|
|
|
|
func testSummariesCountSendersAndMarkOwnReaction() {
|
|
let reactions = [
|
|
MessageReaction(senderJID: "me@example.org/device", emojis: ["👍", "❤️"]),
|
|
MessageReaction(senderJID: "you@example.org", emojis: ["👍"])
|
|
]
|
|
let summaries = MessageReactionPolicy.summaries(
|
|
reactions: reactions,
|
|
ownJID: "me@example.org"
|
|
)
|
|
XCTAssertEqual(
|
|
summaries.first(where: { $0.emoji == "👍" }),
|
|
MessageReactionSummary(emoji: "👍", count: 2, includesOwnReaction: true)
|
|
)
|
|
XCTAssertEqual(
|
|
summaries.first(where: { $0.emoji == "❤️" }),
|
|
MessageReactionSummary(emoji: "❤️", count: 1, includesOwnReaction: true)
|
|
)
|
|
}
|
|
}
|