in AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginIntegrationTests/DataStoreConsecutiveUpdatesTests.swift [374:486]
func testSaveThenMultipleUpdate() throws {
try startAmplifyAndWaitForSync()
let newPost = Post(title: "MyPost",
content: "This is my post.",
createdAt: .now(),
rating: 3,
status: .published)
var updatedPost = newPost
let updatedPostDefaultTitle = "MyUpdatedPost"
let updateCount = 10
let saveSyncReceived = expectation(description: "Received create mutation event on subscription for Post")
let updateSyncReceived = expectation(description: "Received update mutation event on subscription for Post")
let hubListener = Amplify.Hub.listen(
to: .dataStore,
eventName: HubPayload.EventName.DataStore.syncReceived) { payload in
guard let mutationEvent = payload.data as? MutationEvent else {
XCTFail("Can't cast payload as mutation event")
return
}
guard let post = try? mutationEvent.decodeModel() as? Post, post.id == newPost.id else {
return
}
if mutationEvent.mutationType == GraphQLMutationType.create.rawValue {
XCTAssertEqual(post, newPost)
XCTAssertEqual(mutationEvent.version, 1)
saveSyncReceived.fulfill()
return
}
if mutationEvent.mutationType == GraphQLMutationType.update.rawValue {
if post.title == updatedPostDefaultTitle + String(updateCount) {
updateSyncReceived.fulfill()
return
}
}
}
guard try HubListenerTestUtilities.waitForListener(with: hubListener, timeout: 5.0) else {
XCTFail("Listener not registered for hub")
return
}
let saveCompleted = expectation(description: "Save is completed")
Amplify.DataStore.save(newPost) { result in
switch result {
case .success:
saveCompleted.fulfill()
case .failure(let error):
XCTFail("Error: \(error)")
}
}
wait(for: [saveCompleted, saveSyncReceived], timeout: networkTimeout)
for index in 1 ... updateCount {
updatedPost.title = updatedPostDefaultTitle + String(index)
let saveExpectation = expectation(description: "Save \(index) is successful")
Amplify.DataStore.save(updatedPost) { result in
switch result {
case .success:
saveExpectation.fulfill()
case .failure(let error):
XCTFail("Error: \(error)")
}
}
wait(for: [saveExpectation], timeout: networkTimeout)
}
wait(for: [updateSyncReceived], timeout: networkTimeout)
// query the updated post in eventual consistent state
guard let queryResultAfterSync = queryPost(byId: updatedPost.id) else {
XCTFail("Post should be available after update and sync")
return
}
XCTAssertEqual(queryResultAfterSync, updatedPost)
let queryRequest =
GraphQLRequest<MutationSyncResult?>.query(modelName: updatedPost.modelName, byId: updatedPost.id)
let apiQuerySuccess = expectation(description: "API query is successful")
Amplify.API.query(request: queryRequest) { result in
switch result {
case .success(let mutationSyncResult):
switch mutationSyncResult {
case .success(let data):
guard let post = data else {
XCTFail("Failed to get data")
return
}
XCTAssertEqual(post.model["title"] as? String, updatedPost.title)
XCTAssertEqual(post.model["content"] as? String, updatedPost.content)
XCTAssertEqual(post.model["rating"] as? Double, updatedPost.rating)
// version can be anything between 3 to 11 depending on how many
// pending mutations are overwritten in pending mutation queue
// while the first update mutation is being processed
XCTAssertTrue(post.syncMetadata.version >= 3 && post.syncMetadata.version <= 11)
apiQuerySuccess.fulfill()
case .failure(let error):
XCTFail("Error: \(error)")
}
case .failure(let error):
XCTFail("Error: \(error)")
}
}
wait(for: [apiQuerySuccess], timeout: networkTimeout)
}