// // Copyright Amazon.com Inc. or its affiliates. // All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // import XCTest import AmplifyTestCommon @testable import Amplify @testable import AWSAPIPlugin class ModelMetadataTests: XCTestCase { override func setUp() { ModelRegistry.register(modelType: Comment4.self) ModelRegistry.register(modelType: Post4.self) } override class func tearDown() { ModelRegistry.reset() } func testShouldAddMetadataTrue() { let model: JSONValue = [ "id": "id", "__typename": "Post4" ] XCTAssertTrue(AppSyncModelMetadataUtils.shouldAddMetadata(toModel: model)) } func testShouldAddMetadataFalse_MissingTypename() { let model: JSONValue = [ "id": "id" ] XCTAssertFalse(AppSyncModelMetadataUtils.shouldAddMetadata(toModel: model)) } func testShouldAddMetadataFalse_InvalidTypeName() { let model: JSONValue = [ "__typename": "InvalidName" ] XCTAssertFalse(AppSyncModelMetadataUtils.shouldAddMetadata(toModel: model)) } func testAddMetadataToModelArraySuccess() { let jsonArray: [JSONValue] = [ [ "id": "postId", "title": JSONValue.init(stringLiteral: "title"), "__typename": "Post4" ], [ "id": "postId", "title": JSONValue.init(stringLiteral: "title"), "__typename": "Post4" ] ] let posts = AppSyncModelMetadataUtils.addMetadata(toModelArray: jsonArray, apiName: "apiName") XCTAssertEqual(posts.count, 2) for post in posts { guard case .object(let associationData) = post["comments"], case .array(let associatedFields) = associationData["appSyncAssociatedFields"], case .array(let associatedIdentifiers) = associationData["appSyncAssociatedIdentifiers"], case .string(let apiName) = associationData["apiName"] else { XCTFail("Missing association metadata for comments") return } XCTAssertEqual(associatedIdentifiers[0], "postId") XCTAssertEqual(associatedFields, ["post"]) XCTAssertEqual(apiName, "apiName") } } func testAddMetadataToModelSuccess() { let json: JSONValue = [ "id": "postId", "title": JSONValue.init(stringLiteral: "title"), "__typename": "Post4" ] let post = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") guard case .object(let associationData) = post["comments"], case .array(let associatedFields) = associationData["appSyncAssociatedFields"], case .array(let associatedIdentifiers) = associationData["appSyncAssociatedIdentifiers"], case .string(let apiName) = associationData["apiName"] else { XCTFail("Missing association metadata for comments") return } XCTAssertEqual(associatedIdentifiers[0], "postId") XCTAssertEqual(associatedFields, ["post"]) XCTAssertEqual(apiName, "apiName") } func testAddMetadataToModelNoOp_NotAnObject() { let json: JSONValue = "notAnObject" let result = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") XCTAssertEqual(result, "notAnObject") } func testAddMetadatToModelNoOp_MissingTypename() { let json: JSONValue = [ "id": "postId", "title": JSONValue.init(stringLiteral: "title") ] let post = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") guard case .object(let postObject) = post, case .string = postObject["id"], case .string = postObject["title"] else { XCTFail("Should have exactly the number of fields in original json object") return } XCTAssertEqual(postObject.count, 2) } func testAddMetadataToModelNoOp_MissingModelSchema() { let json: JSONValue = [ "id": "postId", "title": JSONValue.init(stringLiteral: "title"), "__typename": "InvalidModelName" ] let post = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") guard case .object(let postObject) = post, case .string = postObject["id"], case .string = postObject["title"], case .string = postObject["__typename"] else { XCTFail("Should have exactly the number of fields in original json object") return } XCTAssertEqual(postObject.count, 3) } func testAddMetadataNoOp_MissingId() { let json: JSONValue = [ "title": JSONValue.init(stringLiteral: "title"), "__typename": "Post4" ] let post = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") guard case .object(let postObject) = post, case .string = postObject["title"], case .string = postObject["__typename"] else { XCTFail("Should have exactly the number of fields in original json object") return } XCTAssertEqual(postObject.count, 2) } func testAddMetadataNoOp_NestedDataAtArrayAssociation() { let json: JSONValue = [ "id": "postId", "title": JSONValue.init(stringLiteral: "title"), "__typename": "Post4", "comments": [ "items": [ ["id": "commentId", "content": "content", "__typename": "Comment4"] ], "nextToken": "nextToken" ] ] let post = AppSyncModelMetadataUtils.addMetadata(toModel: json, apiName: "apiName") guard case .object(let associationData) = post["comments"], associationData["appSyncAssociatedField"] == nil, associationData["appSyncAssociatedIdentifiers"] == nil, associationData["apiName"] == nil else { XCTFail("Nested levels of data should not have metadata added") return } } }