252 lines
9.5 KiB
Swift
252 lines
9.5 KiB
Swift
//
|
|
// Copyright Amazon.com Inc. or its affiliates.
|
|
// All Rights Reserved.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
import XCTest
|
|
@testable import AWSAPIPlugin
|
|
@testable import Amplify
|
|
@testable import APIHostApp
|
|
|
|
/*
|
|
(HasMany) A Post that can have many comments
|
|
```
|
|
type Post3 @model {
|
|
id: ID!
|
|
title: String!
|
|
comments: [Comment3] @connection(keyName: "byPost3", fields: ["id"])
|
|
}
|
|
|
|
type Comment3 @model
|
|
@key(name: "byPost3", fields: ["postID", "content"]) {
|
|
id: ID!
|
|
postID: ID!
|
|
content: String!
|
|
}
|
|
```
|
|
See https://docs.amplify.aws/cli/graphql-transformer/connection for more details
|
|
*/
|
|
extension GraphQLConnectionScenario3Tests {
|
|
|
|
func testGetPostThenIterateComments() async throws {
|
|
guard let post = try await createPost(title: "title"),
|
|
try await createComment(postID: post.id, content: "content") != nil,
|
|
try await createComment(postID: post.id, content: "content") != nil else {
|
|
XCTFail("Could not create post and two comments")
|
|
return
|
|
}
|
|
|
|
var results: List<Comment3>?
|
|
let result = try await Amplify.API.query(request: .get(Post3.self, byId: post.id))
|
|
switch result {
|
|
case .success(let queriedPostOptional):
|
|
guard let queriedPost = queriedPostOptional else {
|
|
XCTFail("Could not get post")
|
|
return
|
|
}
|
|
XCTAssertEqual(queriedPost.id, post.id)
|
|
results = queriedPost.comments
|
|
case .failure(let response):
|
|
XCTFail("Failed with: \(response)")
|
|
}
|
|
guard var comments = results else {
|
|
XCTFail("Could not get comments")
|
|
return
|
|
}
|
|
var resultsArray: [Comment3] = []
|
|
try await comments.fetch()
|
|
for comment in comments {
|
|
resultsArray.append(comment)
|
|
}
|
|
while comments.hasNextPage() {
|
|
let listResult = try await comments.getNextPage()
|
|
comments = listResult
|
|
resultsArray.append(contentsOf: comments)
|
|
}
|
|
XCTAssertEqual(resultsArray.count, 2)
|
|
}
|
|
|
|
func testGetPostThenFetchComments() async throws {
|
|
guard let post = try await createPost(title: "title"),
|
|
try await createComment(postID: post.id, content: "content") != nil,
|
|
try await createComment(postID: post.id, content: "content") != nil else {
|
|
XCTFail("Could not create post and two comments")
|
|
return
|
|
}
|
|
|
|
var results: List<Comment3>?
|
|
let result = try await Amplify.API.query(request: .get(Post3.self, byId: post.id))
|
|
switch result {
|
|
case .success(let queriedPostOptional):
|
|
guard let queriedPost = queriedPostOptional else {
|
|
XCTFail("Could not get post")
|
|
return
|
|
}
|
|
XCTAssertEqual(queriedPost.id, post.id)
|
|
results = queriedPost.comments
|
|
case .failure(let response):
|
|
XCTFail("Failed with: \(response)")
|
|
}
|
|
guard var comments = results else {
|
|
XCTFail("Could not get comments")
|
|
return
|
|
}
|
|
var resultsArray: [Comment3] = []
|
|
try await comments.fetch()
|
|
resultsArray.append(contentsOf: comments)
|
|
while comments.hasNextPage() {
|
|
let listResult = try await comments.getNextPage()
|
|
comments = listResult
|
|
resultsArray.append(contentsOf: comments)
|
|
}
|
|
XCTAssertEqual(resultsArray.count, 2)
|
|
}
|
|
|
|
// Create a post and list the posts
|
|
func testListPost() async throws {
|
|
guard try await createPost(title: "title") != nil else {
|
|
XCTFail("Failed to ensure at least one Post to be retrieved on the listQuery")
|
|
return
|
|
}
|
|
|
|
let graphQLResponse = try await Amplify.API.query(request: .list(Post3.self))
|
|
guard case let .success(posts) = graphQLResponse else {
|
|
XCTFail("Missing successful response")
|
|
return
|
|
}
|
|
XCTAssertTrue(!posts.isEmpty)
|
|
}
|
|
|
|
func testListPostWithPredicate() async throws {
|
|
let uuid = UUID().uuidString
|
|
let testMethodName = String("\(#function)".dropLast(2))
|
|
let uniqueTitle = testMethodName + uuid + "Title"
|
|
guard try await createPost(id: uuid, title: uniqueTitle) != nil else {
|
|
XCTFail("Failed to ensure at least one Post to be retrieved on the listQuery")
|
|
return
|
|
}
|
|
|
|
let post = Post3.keys
|
|
let predicate = post.id == uuid && post.title == uniqueTitle
|
|
let graphQLResponse = try await Amplify.API.query(request: .list(Post3.self, where: predicate))
|
|
guard case let .success(posts) = graphQLResponse else {
|
|
XCTFail("Missing successful response")
|
|
return
|
|
}
|
|
XCTAssertEqual(posts.count, 1)
|
|
guard let singlePost = posts.first else {
|
|
XCTFail("Should only have a single post with the unique title")
|
|
return
|
|
}
|
|
XCTAssertEqual(singlePost.id, uuid)
|
|
XCTAssertEqual(singlePost.title, uniqueTitle)
|
|
}
|
|
|
|
// Create a post and a comment with that post
|
|
// list the comments by postId
|
|
func testListCommentsByPostID() async throws {
|
|
guard let post = try await createPost(title: "title") else {
|
|
XCTFail("Could not create post")
|
|
return
|
|
}
|
|
guard try await createComment(postID: post.id, content: "content") != nil else {
|
|
XCTFail("Could not create comment")
|
|
return
|
|
}
|
|
let predicate = Comment3.keys.postID.eq(post.id)
|
|
let result = try await Amplify.API.query(request: .list(Comment3.self, where: predicate))
|
|
switch result {
|
|
case .success(let comments):
|
|
XCTAssertEqual(comments.count, 1)
|
|
case .failure(let response):
|
|
XCTFail("Failed with: \(response)")
|
|
}
|
|
}
|
|
|
|
/// 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 comments for the same post, and a query with the predicate for comments by postID with 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 exactly two comments.
|
|
func testPaginatedListCommentsByPostID() async throws {
|
|
guard let post = try await createPost(title: "title") else {
|
|
XCTFail("Could not create post")
|
|
return
|
|
}
|
|
guard try await createComment(postID: post.id, content: "content") != nil else {
|
|
XCTFail("Could not create comment")
|
|
return
|
|
}
|
|
guard try await createComment(postID: post.id, content: "content") != nil else {
|
|
XCTFail("Could not create comment")
|
|
return
|
|
}
|
|
var results: List<Comment3>?
|
|
let predicate = Comment3.keys.postID.eq(post.id)
|
|
let result = try await Amplify.API.query(request: .list(Comment3.self, where: predicate, limit: 1))
|
|
switch result {
|
|
case .success(let comments):
|
|
results = comments
|
|
case .failure(let response):
|
|
XCTFail("Failed with: \(response)")
|
|
}
|
|
guard var subsequentResults = results else {
|
|
XCTFail("Could not get first results")
|
|
return
|
|
}
|
|
var resultsArray: [Comment3] = []
|
|
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. 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, exhausted `fetch` calls
|
|
/// - When:
|
|
/// - A `fetch` is made when `hasNextPage` returns false.
|
|
/// - Then:
|
|
/// - A validation error is returned
|
|
func testPaginatedListFetchValidationError() async throws {
|
|
let uuid1 = UUID().uuidString
|
|
guard try await createPost(id: uuid1, title: "title") != nil else {
|
|
XCTFail("Failed to create post")
|
|
return
|
|
}
|
|
let post = Post3.keys
|
|
let predicate = post.id == uuid1
|
|
let request: GraphQLRequest<List<Post3>> = GraphQLRequest<Post3>.list(Post3.self, where: predicate)
|
|
let response = try await Amplify.API.query(request: request)
|
|
guard case let .success(graphQLResponse) = response else {
|
|
XCTFail("Missing successful response")
|
|
return
|
|
}
|
|
var subsequentResults = graphQLResponse
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|