From 19e501dc4d32e1255de400343ddbb5b32496ca60 Mon Sep 17 00:00:00 2001 From: Di Wu Date: Fri, 1 Dec 2023 10:38:47 -0800 Subject: [PATCH] resolve comments --- ...atabaseAdapter+MutationEventIngester.swift | 2 - .../MutationEventExtensionsTests.swift | 404 ------------------ 2 files changed, 406 deletions(-) delete mode 100644 AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/Support/MutationEventExtensionsTests.swift diff --git a/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/MutationSync/AWSMutationDatabaseAdapter/AWSMutationDatabaseAdapter+MutationEventIngester.swift b/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/MutationSync/AWSMutationDatabaseAdapter/AWSMutationDatabaseAdapter+MutationEventIngester.swift index c5ba199356..528c4f9210 100644 --- a/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/MutationSync/AWSMutationDatabaseAdapter/AWSMutationDatabaseAdapter+MutationEventIngester.swift +++ b/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/MutationSync/AWSMutationDatabaseAdapter/AWSMutationDatabaseAdapter+MutationEventIngester.swift @@ -193,8 +193,6 @@ extension AWSMutationDatabaseAdapter: MutationEventIngester { } resolvedEvent.mutationType = updatedMutationType - resolvedEvent.version = candidate.version - return resolvedEvent } diff --git a/AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/Support/MutationEventExtensionsTests.swift b/AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/Support/MutationEventExtensionsTests.swift deleted file mode 100644 index 7938a953ff..0000000000 --- a/AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/Support/MutationEventExtensionsTests.swift +++ /dev/null @@ -1,404 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -import Foundation -import SQLite -import XCTest - -@testable import Amplify -@testable import AmplifyTestCommon -@testable import AWSDataStorePlugin -@testable import AWSPluginsCore - -// TODO: This flaky test has been disabled, tracking issue: https://github.com/aws-amplify/amplify-ios/issues/1831 -// swiftlint:disable type_body_length -class MutationEventExtensionsTest: BaseDataStoreTests { - - /// - Given: A pending mutation events queue with event containing `nil` version, a sent mutation - /// event model that matches the received mutation sync model. The received mutation sync has version 1. - /// - When: The sent model matches the received model and the first pending mutation event version is `nil`. - /// - Then: The pending mutation event version should be updated to the received model version of 1. - func testSentModelWithNilVersion_Reconciled() throws { - throw XCTSkip("TODO: fix this test") - let modelId = UUID().uuidString - let post = Post(id: modelId, title: "title", content: "content", createdAt: .now()) - let requestMutationEvent = try createMutationEvent(model: post, - mutationType: .create, - createdAt: .now(), - version: nil, - inProcess: true) - let pendingMutationEvent = try createMutationEvent(model: post, - mutationType: .update, - createdAt: .now().add(value: 1, to: .second), - version: nil) - let responseMutationSync = createMutationSync(model: post, version: 1) - - setUpPendingMutationQueue(post, [requestMutationEvent, pendingMutationEvent], pendingMutationEvent) - - let reconciledEvent = MutationEvent.reconcile(pendingMutationEvent: pendingMutationEvent, - with: requestMutationEvent, - responseMutationSync: responseMutationSync) - XCTAssertNotNil(reconciledEvent) - XCTAssertEqual(reconciledEvent?.version, responseMutationSync.syncMetadata.version) - - let queryAfterUpdatingVersionExpectation = expectation(description: "update mutation should be latest version") - let updatingVersionExpectation = expectation(description: "update latest mutation event with response version") - - // update the version of head of mutation event table for given model id to the version of `mutationSync` - MutationEvent.reconcilePendingMutationEventsVersion(sent: requestMutationEvent, - received: responseMutationSync, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success: - updatingVersionExpectation.fulfill() - } - } - wait(for: [updatingVersionExpectation], timeout: 1) - - // query for head of mutation event table for given model id and check if it has the updated version - MutationEvent.pendingMutationEvents(forModel: post, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let mutationEvents): - guard !mutationEvents.isEmpty, let head = mutationEvents.first else { - XCTFail("Failure while updating version") - return - } - XCTAssertEqual(head.version, responseMutationSync.syncMetadata.version) - XCTAssertEqual(head.mutationType, MutationEvent.MutationType.update.rawValue) - queryAfterUpdatingVersionExpectation.fulfill() - } - } - wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1) - } - - /// - Given: A pending mutation events queue with two events(update and delete) containing `nil` version, - /// a sent mutation event model that matches the received mutation sync model. The received mutation - /// sync has version 1. - /// - When: The sent model matches the received model, the first pending mutation event(update) version is `nil` and - /// the second pending mutation event(delete) version is `nil`. - /// - Then: The first pending mutation event(update) version should be updated to the received model version of 1 - /// and the second pending mutation event version(delete) should not be updated. - func testSentModelWithNilVersion_SecondPendingEventNotReconciled() throws { - throw XCTSkip("TODO: fix this test") - let modelId = UUID().uuidString - let post = Post(id: modelId, title: "title", content: "content", createdAt: .now()) - let requestMutationEvent = try createMutationEvent(model: post, - mutationType: .create, - createdAt: .now(), - version: nil, - inProcess: true) - let pendingUpdateMutationEvent = try createMutationEvent(model: post, - mutationType: .update, - createdAt: .now().add(value: 1, to: .second), - version: nil) - let pendingDeleteMutationEvent = try createMutationEvent(model: post, - mutationType: .delete, - createdAt: .now().add(value: 2, to: .second), - version: nil) - let responseMutationSync = createMutationSync(model: post, version: 1) - - setUpPendingMutationQueue(post, - [requestMutationEvent, pendingUpdateMutationEvent, pendingDeleteMutationEvent], - pendingUpdateMutationEvent) - - let reconciledEvent = MutationEvent.reconcile(pendingMutationEvent: pendingUpdateMutationEvent, - with: requestMutationEvent, - responseMutationSync: responseMutationSync) - XCTAssertNotNil(reconciledEvent) - XCTAssertEqual(reconciledEvent?.version, responseMutationSync.syncMetadata.version) - - let queryAfterUpdatingVersionExpectation = expectation(description: "update mutation should be latest version") - let updatingVersionExpectation = expectation(description: "update latest mutation event with response version") - - // update the version of head of mutation event table for given model id to the version of `mutationSync` - MutationEvent.reconcilePendingMutationEventsVersion(sent: requestMutationEvent, - received: responseMutationSync, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success: - updatingVersionExpectation.fulfill() - } - } - wait(for: [updatingVersionExpectation], timeout: 1) - - // query for head of mutation event table for given model id and check if it has the updated version - MutationEvent.pendingMutationEvents(forModel: post, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let mutationEvents): - guard !mutationEvents.isEmpty, let head = mutationEvents.first, let last = mutationEvents.last else { - XCTFail("Failure while updating version") - return - } - XCTAssertEqual(head.version, responseMutationSync.syncMetadata.version) - XCTAssertEqual(head.mutationType, MutationEvent.MutationType.update.rawValue) - XCTAssertEqual(last, pendingDeleteMutationEvent) - queryAfterUpdatingVersionExpectation.fulfill() - } - } - wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1) - } - - /// - Given: A pending mutation events queue with event containing version 2, a sent mutation event model - /// that matches the received mutation sync model having version 2. The received mutation sync has - /// version 1. - /// - When: The sent model matches the received model and the first pending mutation event version is 2. - /// - Then: The first pending mutation event version should NOT be updated. - func testSentModelVersionNewerThanResponseVersion_PendingEventNotReconciled() throws { - throw XCTSkip("TODO: fix this test") - let modelId = UUID().uuidString - let post1 = Post(id: modelId, title: "title1", content: "content1", createdAt: .now()) - let post2 = Post(id: modelId, title: "title2", content: "content2", createdAt: .now()) - let requestMutationEvent = try createMutationEvent(model: post1, - mutationType: .create, - createdAt: .now(), - version: 2, - inProcess: true) - let pendingMutationEvent = try createMutationEvent(model: post2, - mutationType: .update, - createdAt: .now().add(value: 1, to: .second), - version: 2) - let responseMutationSync = createMutationSync(model: post1, version: 1) - - setUpPendingMutationQueue(post1, [requestMutationEvent, pendingMutationEvent], pendingMutationEvent) - - let reconciledEvent = MutationEvent.reconcile(pendingMutationEvent: pendingMutationEvent, - with: requestMutationEvent, - responseMutationSync: responseMutationSync) - XCTAssertNil(reconciledEvent) - - let queryAfterUpdatingVersionExpectation = expectation(description: "update mutation should have version 2") - let updatingVersionExpectation = - expectation(description: "don't update latest mutation event with response version") - - MutationEvent.reconcilePendingMutationEventsVersion(sent: requestMutationEvent, - received: responseMutationSync, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success: - updatingVersionExpectation.fulfill() - } - } - wait(for: [updatingVersionExpectation], timeout: 1) - - // query for head of mutation event table for given model id and check if it has the correct version - MutationEvent.pendingMutationEvents(forModel: post1, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let mutationEvents): - guard !mutationEvents.isEmpty, let head = mutationEvents.first else { - XCTFail("Failure while updating version") - return - } - XCTAssertNotEqual(head.version, responseMutationSync.syncMetadata.version) - XCTAssertEqual(head, pendingMutationEvent) - queryAfterUpdatingVersionExpectation.fulfill() - } - } - wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1) - } - - /// - Given: A pending mutation events queue with event containing version 1, a sent mutation event model - /// that doesn't match the received mutation sync model having version 1. The received mutation - /// sync has version 2. - /// - When: The sent model doesn't match the received model and the first pending mutation event version is 1. - /// - Then: The first pending mutation event version should NOT be updated. - func testSentModelNotEqualToResponseModel_PendingEventNotReconciled() throws { - throw XCTSkip("TODO: fix this test") - let modelId = UUID().uuidString - let post1 = Post(id: modelId, title: "title1", content: "content1", createdAt: .now()) - let post2 = Post(id: modelId, title: "title2", content: "content2", createdAt: .now()) - let post3 = Post(id: modelId, title: "title3", content: "content3", createdAt: .now()) - let requestMutationEvent = try createMutationEvent(model: post1, - mutationType: .update, - createdAt: .now(), - version: 1, - inProcess: true) - let pendingMutationEvent = try createMutationEvent(model: post2, - mutationType: .update, - createdAt: .now().add(value: 1, to: .second), - version: 1) - let responseMutationSync = createMutationSync(model: post3, version: 2) - - setUpPendingMutationQueue(post1, [requestMutationEvent, pendingMutationEvent], pendingMutationEvent) - - let reconciledEvent = MutationEvent.reconcile(pendingMutationEvent: pendingMutationEvent, - with: requestMutationEvent, - responseMutationSync: responseMutationSync) - XCTAssertNil(reconciledEvent) - - let queryAfterUpdatingVersionExpectation = expectation(description: "update mutation should have version 1") - let updatingVersionExpectation = - expectation(description: "don't update latest mutation event with response version") - - MutationEvent.reconcilePendingMutationEventsVersion(sent: requestMutationEvent, - received: responseMutationSync, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success: - updatingVersionExpectation.fulfill() - } - } - wait(for: [updatingVersionExpectation], timeout: 1) - - // query for head of mutation event table for given model id and check if it has the correct version - MutationEvent.pendingMutationEvents(forModel: post1, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let mutationEvents): - guard !mutationEvents.isEmpty, let head = mutationEvents.first else { - XCTFail("Failure while updating version") - return - } - XCTAssertNotEqual(head.version, responseMutationSync.syncMetadata.version) - XCTAssertEqual(head, pendingMutationEvent) - queryAfterUpdatingVersionExpectation.fulfill() - } - } - wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1) - } - - /// - Given: A pending mutation events queue with event containing version 1, a sent mutation event model - /// that matches the received mutation sync model having version 1. The received mutation sync - /// has version 2. - /// - When: The sent model matches the received model and the first pending mutation event version is 1. - /// - Then: The first pending mutation event version should be updated to received mutation sync version i.e. 2. - func testPendingVersionReconciledSuccess() throws { - throw XCTSkip("TODO: fix this test") - let modelId = UUID().uuidString - let post1 = Post(id: modelId, title: "title1", content: "content1", createdAt: .now()) - let post2 = Post(id: modelId, title: "title2", content: "content2", createdAt: .now()) - let requestMutationEvent = try createMutationEvent(model: post1, - mutationType: .update, - createdAt: .now(), - version: 1, - inProcess: true) - let pendingMutationEvent = try createMutationEvent(model: post2, - mutationType: .update, - createdAt: .now().add(value: 1, to: .second), - version: 1) - let responseMutationSync = createMutationSync(model: post1, version: 2) - - setUpPendingMutationQueue(post1, [requestMutationEvent, pendingMutationEvent], pendingMutationEvent) - - let reconciledEvent = MutationEvent.reconcile(pendingMutationEvent: pendingMutationEvent, - with: requestMutationEvent, - responseMutationSync: responseMutationSync) - XCTAssertNotNil(reconciledEvent) - XCTAssertEqual(reconciledEvent?.version, responseMutationSync.syncMetadata.version) - - let queryAfterUpdatingVersionExpectation = expectation(description: "update mutation should have version 2") - let updatingVersionExpectation = expectation(description: "update latest mutation event with response version") - - MutationEvent.reconcilePendingMutationEventsVersion(sent: requestMutationEvent, - received: responseMutationSync, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success: - updatingVersionExpectation.fulfill() - } - } - wait(for: [updatingVersionExpectation], timeout: 1) - - // query for head of mutation event table for given model id and check if it has the correct version - MutationEvent.pendingMutationEvents(forModel: post1, - storageAdapter: storageAdapter) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let mutationEvents): - guard !mutationEvents.isEmpty, let head = mutationEvents.first else { - XCTFail("Failure while updating version") - return - } - XCTAssertEqual(head.version, responseMutationSync.syncMetadata.version) - XCTAssertEqual(head.mutationType, MutationEvent.MutationType.update.rawValue) - queryAfterUpdatingVersionExpectation.fulfill() - } - } - wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1) - } - - private func createMutationEvent(model: Model, - mutationType: MutationEvent.MutationType, - createdAt: Temporal.DateTime, - version: Int? = nil, - inProcess: Bool = false) throws -> MutationEvent { - return MutationEvent(id: UUID().uuidString, - modelId: model.identifier(schema: MutationEvent.schema).stringValue, - modelName: model.modelName, - json: try model.toJSON(), - mutationType: mutationType, - createdAt: createdAt, - version: version, - inProcess: inProcess) - } - - private func createMutationSync(model: Model, version: Int = 1) -> MutationSync { - let metadata = MutationSyncMetadata(modelId: model.identifier(schema: MutationEvent.schema).stringValue, - modelName: model.modelName, - deleted: false, - lastChangedAt: Int64(Date().timeIntervalSince1970), - version: version) - return MutationSync(model: AnyModel(model), syncMetadata: metadata) - } - - private func setUpPendingMutationQueue(_ model: Model, - _ mutationEvents: [MutationEvent], - _ expectedHeadOfQueue: MutationEvent) { - for mutationEvent in mutationEvents { - let mutationEventSaveExpectation = expectation(description: "save mutation event success") - storageAdapter.save(mutationEvent) { result in - guard case .success = result else { - XCTFail("Failed to save metadata") - return - } - mutationEventSaveExpectation.fulfill() - } - wait(for: [mutationEventSaveExpectation], timeout: 1) - } - - // verify the head of queue is expected - let headOfQueueExpectation = expectation(description: "head of mutation event queue is as expected") - MutationEvent.pendingMutationEvents( - forModel: model, - storageAdapter: storageAdapter - ) { result in - switch result { - case .failure(let error): - XCTFail("Error : \(error)") - case .success(let events): - guard !events.isEmpty, let head = events.first else { - XCTFail("Failure while fetching mutation events") - return - } - XCTAssertEqual(head, expectedHeadOfQueue) - headOfQueueExpectation.fulfill() - } - } - wait(for: [headOfQueueExpectation], timeout: 1) - } -}