FriendControllerNicknameReplayTests.swift (3664B)
1 import CloudKit 2 import CoreData 3 import Foundation 4 import Testing 5 6 @testable import Crossmate 7 8 @Suite("FriendController nickname replay", .serialized) 9 @MainActor 10 struct FriendControllerNicknameReplayTests { 11 @Test("Post-bootstrap replay applies an existing account nickname decision") 12 func replayAppliesExistingNicknameDecision() async throws { 13 let persistence = makeTestPersistence() 14 let ctx = persistence.viewContext 15 let friend = FriendEntity(context: ctx) 16 friend.authorID = "_bob" 17 friend.pairKey = FriendZone.pairKey("_alice", "_bob") 18 friend.friendZoneName = FriendZone.zoneName(pairKey: friend.pairKey!) 19 friend.friendZoneOwnerName = CKCurrentUserDefaultName 20 friend.databaseScope = 0 21 friend.createdAt = Date() 22 try ctx.save() 23 24 let fetchedZone = CKRecordZone.ID( 25 zoneName: RecordSerializer.accountZoneID.zoneName, 26 ownerName: "_alice" 27 ) 28 let decision = RecordSerializer.decisionRecord( 29 kind: RecordSerializer.nicknameDecisionKind, 30 key: "_bob", 31 payload: "Bobby", 32 zone: fetchedZone, 33 version: 1 34 ) 35 var requestedRecordID: CKRecord.ID? 36 let controller = FriendController( 37 container: CKContainer(identifier: "iCloud.net.inqk.crossmate.v3"), 38 persistence: persistence, 39 syncEngine: SyncEngine( 40 container: CKContainer(identifier: "iCloud.net.inqk.crossmate.v3"), 41 persistence: persistence 42 ), 43 fetchAccountDecisionRecord: { recordID in 44 requestedRecordID = recordID 45 return decision 46 } 47 ) 48 49 await controller.applyAccountNicknameDecisionIfPresent(for: "_bob") 50 51 #expect(requestedRecordID?.recordName == RecordSerializer.decisionRecordName( 52 kind: RecordSerializer.nicknameDecisionKind, 53 key: "_bob" 54 )) 55 #expect(requestedRecordID?.zoneID.zoneName == RecordSerializer.accountZoneID.zoneName) 56 #expect(friend.nickname == "Bobby") 57 #expect(friend.nicknameVersion == 1) 58 } 59 60 @Test("Post-bootstrap replay keeps a newer local nickname") 61 func replayKeepsNewerLocalNickname() async throws { 62 let persistence = makeTestPersistence() 63 let ctx = persistence.viewContext 64 let friend = FriendEntity(context: ctx) 65 friend.authorID = "_bob" 66 friend.pairKey = FriendZone.pairKey("_alice", "_bob") 67 friend.friendZoneName = FriendZone.zoneName(pairKey: friend.pairKey!) 68 friend.friendZoneOwnerName = CKCurrentUserDefaultName 69 friend.databaseScope = 0 70 friend.createdAt = Date() 71 friend.nickname = "Robert" 72 friend.nicknameVersion = 2 73 try ctx.save() 74 75 let decision = RecordSerializer.decisionRecord( 76 kind: RecordSerializer.nicknameDecisionKind, 77 key: "_bob", 78 payload: "Bobby", 79 zone: RecordSerializer.accountZoneID, 80 version: 1 81 ) 82 let controller = FriendController( 83 container: CKContainer(identifier: "iCloud.net.inqk.crossmate.v3"), 84 persistence: persistence, 85 syncEngine: SyncEngine( 86 container: CKContainer(identifier: "iCloud.net.inqk.crossmate.v3"), 87 persistence: persistence 88 ), 89 fetchAccountDecisionRecord: { _ in decision } 90 ) 91 92 await controller.applyAccountNicknameDecisionIfPresent(for: "_bob") 93 94 #expect(friend.nickname == "Robert") 95 #expect(friend.nicknameVersion == 2) 96 } 97 }