@@ -91,11 +91,12 @@ struct IntegrationTests {
9191 }
9292
9393 #if swift(>=6.2)
94- @Test ( " Two apps perform a simple sync " )
95- func simpleTwoAppSync ( ) async throws {
94+ @Test ( " Two apps merge updates into a registered object " )
95+ func twoAppsMergeUpdateIntoRegisteredObject ( ) async throws {
9696 let container = TestModelBuilder . createContainer ( author: " App1 " )
9797 let app1Context = container. newBackgroundContext ( )
9898 let app2Context = container. newBackgroundContext ( )
99+ app2Context. retainsRegisteredObjects = true
99100 let app1Handler = TestAppDataHandler (
100101 container: container,
101102 context: app1Context,
@@ -105,10 +106,8 @@ struct IntegrationTests {
105106 context: app2Context,
106107 viewName: " App2Handler " )
107108
108- try await app1Handler. createPerson ( name: " Alice " , age: 30 , author: " App1 " )
109-
110109 let userDefaults = TestModelBuilder . createTestUserDefaults ( )
111- let uniqueString = " TestKit.SimpleTwoApp . \( UUID ( ) . uuidString) . "
110+ let uniqueString = " TestKit.RegisteredUpdate . \( UUID ( ) . uuidString) . "
112111 let kit = PersistentHistoryTrackingKit (
113112 container: container,
114113 contexts: [ app2Context] ,
@@ -119,15 +118,57 @@ struct IntegrationTests {
119118 logLevel: 0 ,
120119 autoStart: false )
121120
121+ let idURL = try await app1Handler. createPerson ( name: " Alice " , age: 30 , author: " App1 " )
122+
123+ try await app2Handler. withContext { ctx in
124+ guard
125+ let coordinator = ctx. persistentStoreCoordinator,
126+ let objectID = coordinator. managedObjectID ( forURIRepresentation: idURL)
127+ else {
128+ Issue . record ( " Failed to resolve object ID for registered-object merge test " )
129+ return
130+ }
131+
132+ let object = try ctx. existingObject ( with: objectID)
133+ #expect( object. value ( forKey: " age " ) as? Int32 == 30 )
134+ }
135+
136+ try await app1Handler. updatePeople (
137+ [ PersonUpdate ( matchName: " Alice " , newAge: 31 ) ] ,
138+ author: " App1 " )
139+
140+ try await app2Handler. withContext { ctx in
141+ guard
142+ let coordinator = ctx. persistentStoreCoordinator,
143+ let objectID = coordinator. managedObjectID ( forURIRepresentation: idURL) ,
144+ let object = ctx. registeredObject ( for: objectID)
145+ else {
146+ Issue . record ( " Expected App2 context to have a registered object before merge " )
147+ return
148+ }
149+
150+ #expect( object. value ( forKey: " age " ) as? Int32 == 30 )
151+ }
152+
122153 try await kit. transactionProcessor. processNewTransactions (
123154 from: [ " App1 " , " App2 " ] ,
124155 after: nil ,
125156 currentAuthor: " App2 " ,
126157 cleanBeforeTimestamp: nil )
127158
128- let summaries = try await app2Handler. personSummaries ( )
129- #expect( summaries. count == 1 )
130- #expect( summaries. first? . 0 == " Alice " )
159+ try await app2Handler. withContext { ctx in
160+ guard
161+ let coordinator = ctx. persistentStoreCoordinator,
162+ let objectID = coordinator. managedObjectID ( forURIRepresentation: idURL) ,
163+ let object = ctx. registeredObject ( for: objectID)
164+ else {
165+ Issue . record ( " Expected App2 context to keep the object registered after merge " )
166+ return
167+ }
168+
169+ #expect( object. value ( forKey: " name " ) as? String == " Alice " )
170+ #expect( object. value ( forKey: " age " ) as? Int32 == 31 )
171+ }
131172 }
132173
133174 @Test ( " Manual cleaner integration test " )
0 commit comments