migrate persistence from JSON to SwiftData
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.
This commit is contained in:
1 parent
0317277d46
commit
cbb820a86e
30 files changed
+726
-665
No files matched your search
@@ -3,7 +3,7 @@ import XCTest
|
||||
@testable import Luma
|
||||
|
||||
final class GroupConversationTests: XCTestCase {
|
||||
func testGroupConversationRoundTrips() throws {
|
||||
func testGroupConversationProperties() {
|
||||
let conversation = Conversation(
|
||||
jid: "team@conference.example.org",
|
||||
displayName: "Команда",
|
||||
@@ -16,33 +16,11 @@ final class GroupConversationTests: XCTestCase {
|
||||
invitedBy: "bob@example.org"
|
||||
)
|
||||
|
||||
let decoded = try JSONDecoder().decode(
|
||||
Conversation.self,
|
||||
from: JSONEncoder().encode(conversation)
|
||||
)
|
||||
|
||||
XCTAssertTrue(decoded.isGroup)
|
||||
XCTAssertEqual(decoded.groupNickname, "Alice")
|
||||
XCTAssertEqual(decoded.occupantCount, 4)
|
||||
XCTAssertEqual(decoded.invitedBy, "bob@example.org")
|
||||
}
|
||||
|
||||
func testLegacyConversationDefaultsToDirect() throws {
|
||||
let conversation = Conversation(jid: "bob@example.org", displayName: "Bob")
|
||||
let encoded = try JSONEncoder().encode(conversation)
|
||||
var object = try XCTUnwrap(JSONSerialization.jsonObject(with: encoded) as? [String: Any])
|
||||
for key in ["kind", "groupNickname", "isGroupJoined", "shouldAutojoin", "occupantCount", "invitedBy"] {
|
||||
object.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
let decoded = try JSONDecoder().decode(
|
||||
Conversation.self,
|
||||
from: JSONSerialization.data(withJSONObject: object)
|
||||
)
|
||||
|
||||
XCTAssertFalse(decoded.isGroup)
|
||||
XCTAssertFalse(decoded.isGroupJoined)
|
||||
XCTAssertEqual(decoded.occupantCount, 0)
|
||||
XCTAssertTrue(conversation.isGroup)
|
||||
XCTAssertEqual(conversation.groupNickname, "Alice")
|
||||
XCTAssertEqual(conversation.occupantCount, 4)
|
||||
XCTAssertEqual(conversation.invitedBy, "bob@example.org")
|
||||
XCTAssertEqual(conversation.encryptionPreference, .disabled)
|
||||
}
|
||||
|
||||
func testNewGroupInheritsGlobalEncryptionByDefault() {
|
||||
@@ -52,5 +30,6 @@ final class GroupConversationTests: XCTestCase {
|
||||
)
|
||||
|
||||
XCTAssertEqual(conversation.encryptionPreference, .inheritGlobal)
|
||||
XCTAssertTrue(conversation.isGroup)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user