Skip to content

Commit

Permalink
fix broken unit test cases of API and DataStore
Browse files Browse the repository at this point in the history
  • Loading branch information
5d committed Apr 26, 2024
1 parent 1a20c33 commit 2d1c410
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AWSRESTOperationTests: OperationTestBase {
await fulfillment(of: [listenerWasInvoked], timeout: 3)
}

func testGetFailsWithBadAPIName() throws {
func testGetFailsWithBadAPIName() async throws {
let sentData = Data([0x00, 0x01, 0x02, 0x03])
try setUpPluginForSingleResponse(sending: sentData, for: .rest)

Expand All @@ -69,14 +69,13 @@ class AWSRESTOperationTests: OperationTestBase {
receivedFailure.fulfill()
}
}

waitForExpectations(timeout: 1.00)
await fulfillment(of: [receivedSuccess, receivedFailure], timeout: 1)
}

/// - Given: A configured plugin
/// - When: I invoke `APICategory.get(apiName:path:listener:)`
/// - Then: The listener is invoked with the successful value
func testGetReturnsValue() throws {
func testGetReturnsValue() async throws {
let sentData = Data([0x00, 0x01, 0x02, 0x03])
try setUpPluginForSingleResponse(sending: sentData, for: .rest)

Expand All @@ -92,10 +91,10 @@ class AWSRESTOperationTests: OperationTestBase {
callbackInvoked.fulfill()
}

wait(for: [callbackInvoked], timeout: 1.0)
await fulfillment(of: [callbackInvoked], timeout: 1.0)
}

func testRESTOperation_withCustomHeader_shouldOverrideDefaultAmplifyHeaders() throws {
func testRESTOperation_withCustomHeader_shouldOverrideDefaultAmplifyHeaders() async throws {
let expectedHeaderValue = "text/plain"
let sentData = Data([0x00, 0x01, 0x02, 0x03])
try setUpPluginForSingleResponse(sending: sentData, for: .rest)
Expand All @@ -117,7 +116,7 @@ class AWSRESTOperationTests: OperationTestBase {
}
callbackInvoked.fulfill()
}
wait(for: [callbackInvoked, validated], timeout: 1.0)
await fulfillment(of: [callbackInvoked, validated], timeout: 1.0)
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,67 +24,57 @@ class OutgoingMutationQueueTests: SyncEngineTestBase {

await tryOrFail {
try setUpStorageAdapter()
try setUpDataStore(mutationQueue: OutgoingMutationQueue(storageAdapter: storageAdapter,
dataStoreConfiguration: .testDefault(),
authModeStrategy: AWSDefaultAuthModeStrategy()))
}

let post = Post(title: "Post title",
content: "Post content",
createdAt: .now())

apiPlugin.responders[.mutateRequestResponse] = MutateRequestResponder { request in
let anyModel = try! post.eraseToAnyModel()
let remoteSyncMetadata = MutationSyncMetadata(modelId: post.id,
modelName: Post.modelName,
deleted: false,
lastChangedAt: Date().unixSeconds,
version: 2)
let remoteMutationSync = MutationSync(model: anyModel, syncMetadata: remoteSyncMetadata)
return .success(remoteMutationSync)
try setUpDataStore(
mutationQueue: OutgoingMutationQueue(
storageAdapter: storageAdapter,
dataStoreConfiguration: .testDefault(),
authModeStrategy: AWSDefaultAuthModeStrategy()
)
)
}

let post = Post(title: "Post title", content: "Post content", createdAt: .now())
let outboxStatusReceivedCurrentCount = AtomicValue(initialValue: 0)
let outboxStatusOnStart = expectation(description: "On DataStore start, outboxStatus received")
let outboxStatusOnMutationEnqueued = expectation(description: "Mutation enqueued, outboxStatus received")
let outboxMutationEnqueued = expectation(description: "Mutation enqueued, outboxMutationEnqueued received")

let outboxStatusFilter = HubFilters.forEventName(HubPayload.EventName.DataStore.outboxStatus)
let outboxMutationEnqueuedFilter = HubFilters.forEventName(HubPayload.EventName.DataStore.outboxMutationEnqueued)
let filters = HubFilters.any(filters: outboxStatusFilter, outboxMutationEnqueuedFilter)
let hubListener = Amplify.Hub.listen(to: .dataStore, isIncluded: filters) { payload in
if payload.eventName == HubPayload.EventName.DataStore.outboxStatus {
_ = outboxStatusReceivedCurrentCount.increment(by: 1)
guard let outboxStatusEvent = payload.data as? OutboxStatusEvent else {
XCTFail("Failed to cast payload data as OutboxStatusEvent")
return
}
let hubListener0 = Amplify.Hub.listen(to: .dataStore, eventName: HubPayload.EventName.DataStore.outboxStatus) { payload in
defer { _ = outboxStatusReceivedCurrentCount.increment(by: 1) }
guard let outboxStatusEvent = payload.data as? OutboxStatusEvent else {
XCTFail("Failed to cast payload data as OutboxStatusEvent")
return
}

switch outboxStatusReceivedCurrentCount.get() {
case 1:
XCTAssertTrue(outboxStatusEvent.isEmpty)
outboxStatusOnStart.fulfill()
case 2:
XCTAssertFalse(outboxStatusEvent.isEmpty)
outboxStatusOnMutationEnqueued.fulfill()
case 3:
XCTAssertTrue(outboxStatusEvent.isEmpty)
default:
XCTFail("Should not trigger outbox status event")
}
switch outboxStatusReceivedCurrentCount.get() {
case 0:
XCTAssertTrue(outboxStatusEvent.isEmpty)
outboxStatusOnStart.fulfill()
case 1:
XCTAssertFalse(outboxStatusEvent.isEmpty)
outboxStatusOnMutationEnqueued.fulfill()
case 2:
XCTAssertTrue(outboxStatusEvent.isEmpty)
default:
XCTFail("Should not trigger outbox status event")
}
}

if payload.eventName == HubPayload.EventName.DataStore.outboxMutationEnqueued {
guard let outboxStatusEvent = payload.data as? OutboxMutationEvent else {
XCTFail("Failed to cast payload data as OutboxMutationEvent")
return
}
XCTAssertEqual(outboxStatusEvent.modelName, "Post")
outboxMutationEnqueued.fulfill()
let hubListener1 = Amplify.Hub.listen(to: .dataStore, eventName: HubPayload.EventName.DataStore.outboxMutationEnqueued) { payload in
guard let outboxStatusEvent = payload.data as? OutboxMutationEvent else {
XCTFail("Failed to cast payload data as OutboxMutationEvent")
return
}
XCTAssertEqual(outboxStatusEvent.modelName, "Post")
outboxMutationEnqueued.fulfill()
}

guard try await HubListenerTestUtilities.waitForListener(with: hubListener, timeout: 5.0) else {
guard try await HubListenerTestUtilities.waitForListener(with: hubListener0, timeout: 5.0) else {
XCTFail("Listener not registered for hub")
return
}

guard try await HubListenerTestUtilities.waitForListener(with: hubListener1, timeout: 5.0) else {
XCTFail("Listener not registered for hub")
return
}
Expand All @@ -96,25 +86,39 @@ class OutgoingMutationQueueTests: SyncEngineTestBase {
}
}

apiPlugin.responders[.mutateRequestResponse] = MutateRequestResponder { request in
let anyModel = try! post.eraseToAnyModel()
let remoteSyncMetadata = MutationSyncMetadata(
modelId: post.id,
modelName: Post.modelName,
deleted: false,
lastChangedAt: Date().unixSeconds,
version: 2
)
let remoteMutationSync = MutationSync(model: anyModel, syncMetadata: remoteSyncMetadata)
return .success(remoteMutationSync)
}

try await startAmplifyAndWaitForSync()

let saveSuccess = expectation(description: "save success")
Task {
_ = try await Amplify.DataStore.save(post)
saveSuccess.fulfill()
}
await fulfillment(of: [saveSuccess], timeout: 1.0)

await fulfillment(
of: [
saveSuccess,
outboxStatusOnStart,
outboxStatusOnMutationEnqueued,
outboxMutationEnqueued,
createMutationSent
],
timeout: 5.0
)
Amplify.Hub.removeListener(hubListener)
Amplify.Hub.removeListener(hubListener0)
Amplify.Hub.removeListener(hubListener1)
}

/// - Given: A sync-configured DataStore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
/// 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 {
func testSentModelWithNilVersion_Reconciled() async throws {
let modelId = UUID().uuidString
let post = Post(id: modelId, title: "title", content: "content", createdAt: .now())
let requestMutationEvent = try createMutationEvent(model: post,
Expand Down Expand Up @@ -57,7 +57,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
updatingVersionExpectation.fulfill()
}
}
wait(for: [updatingVersionExpectation], timeout: 1)
await fulfillment(of: [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,
Expand All @@ -75,7 +75,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
queryAfterUpdatingVersionExpectation.fulfill()
}
}
wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1)
await fulfillment(of: [queryAfterUpdatingVersionExpectation], timeout: 1)
}

/// - Given: A pending mutation events queue with two events(update and delete) containing `nil` version,
Expand All @@ -85,7 +85,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
/// 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 {
func testSentModelWithNilVersion_SecondPendingEventNotReconciled() async throws {
let modelId = UUID().uuidString
let post = Post(id: modelId, title: "title", content: "content", createdAt: .now())
let requestMutationEvent = try createMutationEvent(model: post,
Expand Down Expand Up @@ -127,7 +127,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
updatingVersionExpectation.fulfill()
}
}
wait(for: [updatingVersionExpectation], timeout: 1)
await fulfillment(of: [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,
Expand All @@ -146,15 +146,15 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
queryAfterUpdatingVersionExpectation.fulfill()
}
}
wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1)
await fulfillment(of: [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 {
func testSentModelVersionNewerThanResponseVersion_PendingEventNotReconciled() async throws {
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())
Expand Down Expand Up @@ -190,7 +190,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
updatingVersionExpectation.fulfill()
}
}
wait(for: [updatingVersionExpectation], timeout: 1)
await fulfillment(of: [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,
Expand All @@ -208,15 +208,15 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
queryAfterUpdatingVersionExpectation.fulfill()
}
}
wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1)
await fulfillment(of: [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 {
func testSentModelNotEqualToResponseModel_PendingEventNotReconciled() async throws {
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())
Expand Down Expand Up @@ -253,7 +253,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
updatingVersionExpectation.fulfill()
}
}
wait(for: [updatingVersionExpectation], timeout: 1)
await fulfillment(of: [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,
Expand All @@ -271,15 +271,15 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
queryAfterUpdatingVersionExpectation.fulfill()
}
}
wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1)
await fulfillment(of: [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 {
func testPendingVersionReconciledSuccess() async throws {
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())
Expand Down Expand Up @@ -315,7 +315,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
updatingVersionExpectation.fulfill()
}
}
wait(for: [updatingVersionExpectation], timeout: 1)
await fulfillment(of: [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,
Expand All @@ -333,7 +333,7 @@ class MutationEventExtensionsTest: BaseDataStoreTests {
queryAfterUpdatingVersionExpectation.fulfill()
}
}
wait(for: [queryAfterUpdatingVersionExpectation], timeout: 1)
await fulfillment(of: [queryAfterUpdatingVersionExpectation], timeout: 1)
}

private func createMutationEvent(model: Model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ class SyncEngineTestBase: XCTestCase {
authPlugin = MockAuthCategoryPlugin()
try Amplify.add(plugin: apiPlugin)
try Amplify.add(plugin: authPlugin)
Amplify.Logging.logLevel = .verbose
}

override func tearDown() async throws {
Expand Down

0 comments on commit 2d1c410

Please sign in to comment.