diff --git a/packages/amplify_datastore/example/ios/Runner.xcodeproj/project.pbxproj b/packages/amplify_datastore/example/ios/Runner.xcodeproj/project.pbxproj index d33215b43b..1141635967 100644 --- a/packages/amplify_datastore/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/amplify_datastore/example/ios/Runner.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ 4B4F4F622982D1E100204FE6 /* 1_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B4F4F482982D1E000204FE6 /* 1_result.json */; }; 4B4F4F632982D1E100204FE6 /* instance_without_predicate.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B4F4F4A2982D1E000204FE6 /* instance_without_predicate.json */; }; 600B4A792BED53E4007AA1EA /* GraphQLResponse+DecodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 600B4A782BED53E4007AA1EA /* GraphQLResponse+DecodeTests.swift */; }; + 60A82D5C2BF52FCC003065FC /* GraphQLRequestExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60A82D5B2BF52FCC003065FC /* GraphQLRequestExtensionTests.swift */; }; + 60A82D5E2BF5348F003065FC /* PublisherExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60A82D5D2BF5348F003065FC /* PublisherExtensionTests.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -120,6 +122,8 @@ 4B4F4F4A2982D1E000204FE6 /* instance_without_predicate.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = instance_without_predicate.json; sourceTree = ""; }; 513D66DA8B182E3FFDF8750D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 600B4A782BED53E4007AA1EA /* GraphQLResponse+DecodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GraphQLResponse+DecodeTests.swift"; sourceTree = ""; }; + 60A82D5B2BF52FCC003065FC /* GraphQLRequestExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLRequestExtensionTests.swift; sourceTree = ""; }; + 60A82D5D2BF5348F003065FC /* PublisherExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublisherExtensionTests.swift; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7A205B25C076AD0D2D0AEBA9 /* Pods-unit_tests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-unit_tests.profile.xcconfig"; path = "Target Support Files/Pods-unit_tests/Pods-unit_tests.profile.xcconfig"; sourceTree = ""; }; @@ -174,6 +178,8 @@ 4B4F4F162982D0C400204FE6 /* unit_tests-Bridging-Header.h */, 119A9D2529F997A6008BD2A8 /* NativeAuthPluginTests.swift */, 600B4A782BED53E4007AA1EA /* GraphQLResponse+DecodeTests.swift */, + 60A82D5B2BF52FCC003065FC /* GraphQLRequestExtensionTests.swift */, + 60A82D5D2BF5348F003065FC /* PublisherExtensionTests.swift */, ); path = unit_tests; sourceTree = ""; @@ -580,9 +586,11 @@ 4B4F4F282982D0CB00204FE6 /* DataStorePluginUnitTests.swift in Sources */, 119A9D2629F997A6008BD2A8 /* NativeAuthPluginTests.swift in Sources */, 600B4A792BED53E4007AA1EA /* GraphQLResponse+DecodeTests.swift in Sources */, + 60A82D5E2BF5348F003065FC /* PublisherExtensionTests.swift in Sources */, 4B4F4F272982D0CB00204FE6 /* QuerySortBuilderUnitTests.swift in Sources */, 4B4F4F202982D0CB00204FE6 /* DataStoreHubEventStreamHandlerTests.swift in Sources */, 4B4F4F242982D0CB00204FE6 /* GetJsonFromFileUtil.swift in Sources */, + 60A82D5C2BF52FCC003065FC /* GraphQLRequestExtensionTests.swift in Sources */, 4B4F4F222982D0CB00204FE6 /* AmplifySerializedModelUnitTests.swift in Sources */, 4B4F4F252982D0CB00204FE6 /* QueryPredicateBuilderUnitTests.swift in Sources */, 4B4F4F212982D0CB00204FE6 /* ModelSchemaEquatableExtensions.swift in Sources */, diff --git a/packages/amplify_datastore/example/ios/unit_tests/GraphQLRequestExtensionTests.swift b/packages/amplify_datastore/example/ios/unit_tests/GraphQLRequestExtensionTests.swift new file mode 100644 index 0000000000..1231d15bdc --- /dev/null +++ b/packages/amplify_datastore/example/ios/unit_tests/GraphQLRequestExtensionTests.swift @@ -0,0 +1,60 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + + +import XCTest +@testable import amplify_datastore + +class GraphQLRequestExtensionTests: XCTestCase { + func testToNativeGraphQLRequest_withCorrectData_convertToNativeGraphQLRequestSuccessfully() { + + let graphQLRequest = GraphQLRequest( + apiName: UUID().uuidString, + document: UUID().uuidString, + variables: [UUID().uuidString: UUID().uuidString], + responseType: MutationEvent.self + ) + + let nativeGrqphQLRquest = graphQLRequest.toNativeGraphQLRequest() + XCTAssertEqual(graphQLRequest.apiName, nativeGrqphQLRquest.apiName) + XCTAssertEqual(graphQLRequest.document, nativeGrqphQLRquest.document) + XCTAssertEqual(String(describing: graphQLRequest.responseType), nativeGrqphQLRquest.responseType) + let graphQLVariablesJson = """ + {"\(graphQLRequest.variables!.keys.first!)":"\(graphQLRequest.variables!.values.first!)"} + """ + XCTAssertEqual(graphQLVariablesJson, nativeGrqphQLRquest.variablesJson) + } + + func testToNativeGraphQLRequest_withNilVariables_convertToNativeGraphQLRequestWithEmptyVariablesJsonObject() { + let graphQLRequest = GraphQLRequest( + apiName: UUID().uuidString, + document: UUID().uuidString, + variables: nil, + responseType: MutationEvent.self + ) + + let nativeGrqphQLRquest = graphQLRequest.toNativeGraphQLRequest() + XCTAssertEqual(graphQLRequest.apiName, nativeGrqphQLRquest.apiName) + XCTAssertEqual(graphQLRequest.document, nativeGrqphQLRquest.document) + XCTAssertEqual(String(describing: graphQLRequest.responseType), nativeGrqphQLRquest.responseType) + let graphQLVariablesJson = "{}" + XCTAssertEqual(graphQLVariablesJson, nativeGrqphQLRquest.variablesJson) + } + + func testToNativeGraphQLRequest_withEmptyVariables_convertToNativeGraphQLRequestWithEmptyVariablesJsonObject() { + let graphQLRequest = GraphQLRequest( + apiName: UUID().uuidString, + document: UUID().uuidString, + variables: [:], + responseType: MutationEvent.self + ) + + let nativeGrqphQLRquest = graphQLRequest.toNativeGraphQLRequest() + XCTAssertEqual(graphQLRequest.apiName, nativeGrqphQLRquest.apiName) + XCTAssertEqual(graphQLRequest.document, nativeGrqphQLRquest.document) + XCTAssertEqual(String(describing: graphQLRequest.responseType), nativeGrqphQLRquest.responseType) + let graphQLVariablesJson = "{}" + XCTAssertEqual(graphQLVariablesJson, nativeGrqphQLRquest.variablesJson) + } + +} diff --git a/packages/amplify_datastore/example/ios/unit_tests/PublisherExtensionTests.swift b/packages/amplify_datastore/example/ios/unit_tests/PublisherExtensionTests.swift new file mode 100644 index 0000000000..6f9b4bd76f --- /dev/null +++ b/packages/amplify_datastore/example/ios/unit_tests/PublisherExtensionTests.swift @@ -0,0 +1,105 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + + +import XCTest +import Combine +@testable import amplify_datastore + +class PublisherExtensionTests: XCTestCase { + func testToAmplifyAsyncThrowingSequence_createAsyncSequenceCorrect() async throws { + let subject = PassthroughSubject() + let (sequence, cancellable) = subject.eraseToAnyPublisher().toAmplifyAsyncThrowingSequence() + + let expectation1 = expectation(description: "element 1 received") + let expectation2 = expectation(description: "element 2 received") + let expectation3 = expectation(description: "element 3 received") + Task { + for try await element in sequence { + switch element { + case 1: expectation1.fulfill() + case 2: expectation2.fulfill() + case 3: expectation3.fulfill() + default: break + } + } + } + + Task { + subject.send(1) + subject.send(2) + subject.send(3) + subject.send(completion: .finished) + } + + await fulfillment(of: [expectation1, expectation2, expectation3], timeout: 1) + } + + func testToAmplifyAsyncThrowingSequence_withThrowingError_createAsyncSequenceCorrect() async throws { + let subject = PassthroughSubject() + let (sequence, cancellable) = subject.eraseToAnyPublisher().toAmplifyAsyncThrowingSequence() + + let expectation1 = expectation(description: "element 1 received") + let expectation2 = expectation(description: "element 2 received") + let expectation3 = expectation(description: "element 3 received") + expectation3.isInverted = true + Task { + do { + for try await element in sequence { + switch element { + case 1: expectation1.fulfill() + case 2: expectation2.fulfill() + case 3: expectation3.fulfill() + default: break + } + } + } catch { + XCTAssertTrue(error is TestError) + } + } + + subject.send(1) + subject.send(2) + subject.send(completion: .failure(.error)) + await fulfillment(of: [expectation1, expectation2, expectation3], timeout: 1) + } + + func testToAmplifyAsyncThrowingSequence_withCancelling_createAsyncSequenceCorrect() async throws { + let subject = PassthroughSubject() + let (sequence, cancellable) = subject.eraseToAnyPublisher().toAmplifyAsyncThrowingSequence() + + let expectation1 = expectation(description: "element 1 received") + let expectation2 = expectation(description: "element 2 received") + let expectation3 = expectation(description: "element 3 received") + expectation3.isInverted = true + let expectation4 = expectation(description: "element 4 received") + expectation4.isInverted = true + Task { + for try await element in sequence { + switch element { + case 1: expectation1.fulfill() + case 2: expectation2.fulfill() + case 3: expectation3.fulfill() + case 4: expectation4.fulfill() + default: break + } + } + } + + subject.send(1) + subject.send(2) + cancellable.cancel() + subject.send(3) + subject.send(4) + await fulfillment(of: [ + expectation1, + expectation2, + expectation3, + expectation4 + ], timeout: 1) + } +} + +fileprivate enum TestError: Error { + case error +}