// // Copyright Amazon.com Inc. or its affiliates. // All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // import XCTest @testable import AWSAPIPlugin @testable import Amplify #if os(watchOS) @testable import APIWatchApp #else @testable import APIHostApp #endif extension GraphQLModelBasedTests { /// Test paginated list query returns a List containing pagination functionality. This test also aggregates page /// results by appending to an in-memory Array, useful to backing UI components which. /// /// - Given: Two posts, and a query with the predicate for the two posts and a limit of 1 /// - When: /// - first query returns a List that provides Paginatable methods, and contains next page. /// - subsequent queries exhaust the results from the API to retrieve the remaining results /// - Then: /// - the in-memory Array is a populated with all expected items. func testPaginatedListFetch() async throws { var resultsArray: [Post] = [] let uuid1 = UUID().uuidString let uuid2 = UUID().uuidString let testMethodName = String("\(#function)".dropLast(2)) let title = testMethodName + "Title" let post1 = Post(id: uuid1, title: title, content: "content", createdAt: .now()) _ = try await Amplify.API.mutate(request: .create(post1)) let post2 = Post(id: uuid2, title: title, content: "content", createdAt: .now()) _ = try await Amplify.API.mutate(request: .create(post2)) let post = Post.keys let predicate = post.id == uuid1 || post.id == uuid2 var results: List<Post>? let response = try await Amplify.API.query(request: .list(Post.self, where: predicate, limit: 1)) guard case .success(let graphQLresponse) = response else { XCTFail("Missing successful response") return } results = graphQLresponse guard var subsequentResults = results else { XCTFail("Could not get first results") return } resultsArray.append(contentsOf: subsequentResults) while subsequentResults.hasNextPage() { let listResult = try await subsequentResults.getNextPage() subsequentResults = listResult resultsArray.append(contentsOf: subsequentResults) } XCTAssertEqual(resultsArray.count, 2) } /// Test paginated list query returns a List containing pagination functionality. /// /// - Given: Two posts, and a query with the predicate, exhausted `getNextPage` calls /// - When: /// - A `getNextPage` is made when `hasNextPage` returns false. /// - Then: /// - A validation error is returned func testPaginatedListFetchValidationError() async throws{ let uuid1 = UUID().uuidString let testMethodName = String("\(#function)".dropLast(2)) let title = testMethodName + "Title" let createdPost = Post(id: uuid1, title: title, content: "content", createdAt: .now()) _ = try await Amplify.API.mutate(request: .create(createdPost)) let post = Post.keys let predicate = post.id == uuid1 var results: List<Post>? let request: GraphQLRequest<List<Post>> = GraphQLRequest<Post>.list(Post.self, where: predicate) let response = try await Amplify.API.query(request: request) guard case .success(let graphQLResponse) = response else { XCTFail("Missing successful response") return } results = graphQLResponse guard var subsequentResults = results else { XCTFail("Could not get first results") return } while subsequentResults.hasNextPage() { let listResult = try await subsequentResults.getNextPage() subsequentResults = listResult } XCTAssertFalse(subsequentResults.hasNextPage()) do { let listResult = try await subsequentResults.getNextPage() XCTFail("Unexpected \(listResult)") } catch let coreError as CoreError { guard case .clientValidation = coreError else { XCTFail("Unexpected CoreError \(coreError)") return } } } /// This test shows the issue with retrieving comments by postId. The schema used to create `Post.swift` and /// `Comment.swift` provisions an AppSync API that does not provide a list query operation for comments by postId. /// /// - Given: A post with a comment, query for the post, and traverse to the comments /// - When: /// - `comments.fetch` is called /// - Then: /// - `CoreError` is returned func testFetchListOfCommentsFromPostFails() async throws { let uuid1 = UUID().uuidString let testMethodName = String("\(#function)".dropLast(2)) let title = testMethodName + "Title" let post = Post(id: uuid1, title: title, content: "content", createdAt: .now()) _ = try await Amplify.API.mutate(request: .create(post)) let comment = Comment(id: uuid1, content: "content", createdAt: .now(), post: post) _ = try await Amplify.API.mutate(request: .create(comment)) var results: Post? let response = try await Amplify.API.query(request: .get(Post.self, byId: post.id)) guard case .success(let graphQLResponse) = response else { XCTFail("Missing successful response") return } results = graphQLResponse guard let retrievedPost = results else { XCTFail("Could not get post") return } do { try await retrievedPost.comments?.fetch() XCTFail("Should have failed to fetch") } catch { XCTAssertNotNil(error) } } }