Skip to content

Commit 0bffc7b

Browse files
committed
fix: DefaultModelProvider return nil from not loaded state (#2746)
1 parent 23b4bb8 commit 0bffc7b

17 files changed

+960
-282
lines changed

Amplify/Categories/DataStore/Model/Lazy/DefaultModelProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public struct DefaultModelProvider<Element: Model>: ModelProvider {
2424
public func load() async throws -> Element? {
2525
switch loadedState {
2626
case .notLoaded:
27-
throw CoreError.clientValidation("DefaultModelProvider does not provide loading capabilities", "")
27+
return nil
2828
case .loaded(let model):
2929
return model
3030
}

AmplifyPlugins/API/Tests/APIHostApp/APIHostApp.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
21698CC02889D5A9004BD994 /* CwlPreconditionTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 21698CBF2889D5A9004BD994 /* CwlPreconditionTesting */; };
8383
21698CC92889D75F004BD994 /* SocialNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21698CC42889D75F004BD994 /* SocialNote.swift */; };
8484
21698CCB2889D75F004BD994 /* GraphQLAuthDirectiveIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21698CC62889D75F004BD994 /* GraphQLAuthDirectiveIntegrationTests.swift */; };
85+
2170971329915C1500FD7EB2 /* GraphQLLazyLoadCompositePKChildTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2170971229915C1500FD7EB2 /* GraphQLLazyLoadCompositePKChildTests.swift */; };
86+
2170971529915C9F00FD7EB2 /* GraphQLLazyLoadCompositePKImplicitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2170971429915C9F00FD7EB2 /* GraphQLLazyLoadCompositePKImplicitTests.swift */; };
87+
2170971729915CCC00FD7EB2 /* GraphQLLazyLoadCompositePKStrangeExplicitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2170971629915CCC00FD7EB2 /* GraphQLLazyLoadCompositePKStrangeExplicitTests.swift */; };
88+
2170971929915CEC00FD7EB2 /* GraphQLLazyLoadCompositePKChildSansTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2170971829915CEC00FD7EB2 /* GraphQLLazyLoadCompositePKChildSansTests.swift */; };
8589
218D0193291AE3750068D133 /* Post4V2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218D018F291AE3750068D133 /* Post4V2.swift */; };
8690
218D0194291AE3750068D133 /* Comment4V2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218D0190291AE3750068D133 /* Comment4V2.swift */; };
8791
218D0195291AE3750068D133 /* Comment4V2+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218D0191291AE3750068D133 /* Comment4V2+Schema.swift */; };
@@ -404,6 +408,10 @@
404408
21698CC32889D75F004BD994 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
405409
21698CC42889D75F004BD994 /* SocialNote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocialNote.swift; sourceTree = "<group>"; };
406410
21698CC62889D75F004BD994 /* GraphQLAuthDirectiveIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphQLAuthDirectiveIntegrationTests.swift; sourceTree = "<group>"; };
411+
2170971229915C1500FD7EB2 /* GraphQLLazyLoadCompositePKChildTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLLazyLoadCompositePKChildTests.swift; sourceTree = "<group>"; };
412+
2170971429915C9F00FD7EB2 /* GraphQLLazyLoadCompositePKImplicitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLLazyLoadCompositePKImplicitTests.swift; sourceTree = "<group>"; };
413+
2170971629915CCC00FD7EB2 /* GraphQLLazyLoadCompositePKStrangeExplicitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLLazyLoadCompositePKStrangeExplicitTests.swift; sourceTree = "<group>"; };
414+
2170971829915CEC00FD7EB2 /* GraphQLLazyLoadCompositePKChildSansTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLLazyLoadCompositePKChildSansTests.swift; sourceTree = "<group>"; };
407415
218D018F291AE3750068D133 /* Post4V2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Post4V2.swift; sourceTree = "<group>"; };
408416
218D0190291AE3750068D133 /* Comment4V2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment4V2.swift; sourceTree = "<group>"; };
409417
218D0191291AE3750068D133 /* Comment4V2+Schema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Comment4V2+Schema.swift"; sourceTree = "<group>"; };
@@ -1054,6 +1062,10 @@
10541062
isa = PBXGroup;
10551063
children = (
10561064
21FA8EFA295C9647009F6A07 /* GraphQLLazyLoadCompositePKTests.swift */,
1065+
2170971229915C1500FD7EB2 /* GraphQLLazyLoadCompositePKChildTests.swift */,
1066+
2170971429915C9F00FD7EB2 /* GraphQLLazyLoadCompositePKImplicitTests.swift */,
1067+
2170971629915CCC00FD7EB2 /* GraphQLLazyLoadCompositePKStrangeExplicitTests.swift */,
1068+
2170971829915CEC00FD7EB2 /* GraphQLLazyLoadCompositePKChildSansTests.swift */,
10571069
21908A58291D762B005021F7 /* ChildSansBelongsTo.swift */,
10581070
21908A53291D762B005021F7 /* ChildSansBelongsTo+Schema.swift */,
10591071
21908A5B291D762B005021F7 /* CompositePKChild.swift */,
@@ -1869,6 +1881,7 @@
18691881
21908A20291D75E4005021F7 /* Project2.swift in Sources */,
18701882
219089F4291D75C3005021F7 /* Comment8V2.swift in Sources */,
18711883
21908A60291D762B005021F7 /* DefaultPKChild.swift in Sources */,
1884+
2170971929915CEC00FD7EB2 /* GraphQLLazyLoadCompositePKChildSansTests.swift in Sources */,
18721885
219089F8291D75C3005021F7 /* MyCustomModel8.swift in Sources */,
18731886
21908A2A291D75EB005021F7 /* Comment4.swift in Sources */,
18741887
21908A19291D75DD005021F7 /* Team1.swift in Sources */,
@@ -1921,6 +1934,7 @@
19211934
21EA888228F9BCD90000BA75 /* TestConfigHelper.swift in Sources */,
19221935
21AB5C4029819A4000CCA482 /* ListIntContainer.swift in Sources */,
19231936
21908A0E291D75D6005021F7 /* TagWithCompositeKey+Schema.swift in Sources */,
1937+
2170971329915C1500FD7EB2 /* GraphQLLazyLoadCompositePKChildTests.swift in Sources */,
19241938
21908A6B291D762B005021F7 /* CompositePKParent+Schema.swift in Sources */,
19251939
21BC111F2971ADA4000E189E /* User14.swift in Sources */,
19261940
21BC111E2971ADA4000E189E /* User14+Schema.swift in Sources */,
@@ -1949,10 +1963,12 @@
19491963
21BC11202971ADA4000E189E /* Comment14+Schema.swift in Sources */,
19501964
21BC11212971ADA4000E189E /* Post14+Schema.swift in Sources */,
19511965
21908A21291D75E4005021F7 /* GraphQLLazyLoadProjectTeam2Tests.swift in Sources */,
1966+
2170971529915C9F00FD7EB2 /* GraphQLLazyLoadCompositePKImplicitTests.swift in Sources */,
19521967
219089FE291D75CE005021F7 /* GraphQLLazyLoadPostCommentWithCompositeKeyTests.swift in Sources */,
19531968
21908A76291D7631005021F7 /* GraphQLLazyLoadPostComment8Tests.swift in Sources */,
19541969
21908A23291D75E4005021F7 /* Project2+Schema.swift in Sources */,
19551970
21908A49291D7608005021F7 /* GraphQLLazyLoadPostComment7Tests.swift in Sources */,
1971+
2170971729915CCC00FD7EB2 /* GraphQLLazyLoadCompositePKStrangeExplicitTests.swift in Sources */,
19561972
21908A2D291D75EB005021F7 /* Post4+Schema.swift in Sources */,
19571973
218D0196291AE3750068D133 /* Post4V2+Schema.swift in Sources */,
19581974
21AB5C3E29819A4000CCA482 /* NestedTypeTestModel.swift in Sources */,

AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginLazyLoadTests/LL12/CompositePK/CompositePKParent+Schema.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extension CompositePKParent {
3434
.hasMany(compositePKParent.children, is: .optional, ofType: CompositePKChild.self, associatedWith: CompositePKChild.keys.parent),
3535
.hasMany(compositePKParent.implicitChildren, is: .optional, ofType: ImplicitChild.self, associatedWith: ImplicitChild.keys.parent),
3636
.hasMany(compositePKParent.strangeChildren, is: .optional, ofType: StrangeExplicitChild.self, associatedWith: StrangeExplicitChild.keys.parent),
37-
.hasMany(compositePKParent.childrenSansBelongsTo, is: .optional, ofType: ChildSansBelongsTo.self, associatedWith: ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToCustomId),
37+
.hasMany(compositePKParent.childrenSansBelongsTo, is: .optional, ofType: ChildSansBelongsTo.self, associatedFields: [ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToCustomId, ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToContent]),
3838
.field(compositePKParent.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime),
3939
.field(compositePKParent.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime)
4040
)
@@ -80,4 +80,4 @@ extension ModelPath where ModelType == CompositePKParent {
8080
public var updatedAt: FieldPath<Temporal.DateTime> {
8181
datetime("updatedAt")
8282
}
83-
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
import Combine
10+
import XCTest
11+
12+
@testable import Amplify
13+
import AWSPluginsCore
14+
15+
extension GraphQLLazyLoadCompositePKTests {
16+
17+
// MARK: - CompositePKParent / ChildSansBelongsTo
18+
19+
func initChildSansBelongsTo(with parent: CompositePKParent) -> ChildSansBelongsTo {
20+
ChildSansBelongsTo(
21+
childId: UUID().uuidString,
22+
content: "content",
23+
compositePKParentChildrenSansBelongsToCustomId: parent.customId,
24+
compositePKParentChildrenSansBelongsToContent: parent.content)
25+
}
26+
27+
func testSaveChildSansBelongsTo() async throws {
28+
await setup(withModels: CompositePKModels())
29+
30+
let parent = initParent()
31+
let savedParent = try await mutate(.create(parent))
32+
let child = initChildSansBelongsTo(with: savedParent)
33+
try await mutate(.create(child))
34+
}
35+
36+
func testUpdateChildSansBelongsTo() async throws {
37+
await setup(withModels: CompositePKModels())
38+
let parent = initParent()
39+
let savedParent = try await mutate(.create(parent))
40+
let child = initChildSansBelongsTo(with: parent)
41+
var savedChild = try await mutate(.create(child))
42+
XCTAssertEqual(savedChild.compositePKParentChildrenSansBelongsToCustomId, savedParent.customId)
43+
XCTAssertEqual(savedChild.compositePKParentChildrenSansBelongsToContent, savedParent.content)
44+
45+
// update the child to a new parent
46+
let newParent = initParent()
47+
let savedNewParent = try await mutate(.create(newParent))
48+
savedChild.compositePKParentChildrenSansBelongsToCustomId = savedNewParent.customId
49+
savedChild.compositePKParentChildrenSansBelongsToContent = savedNewParent.content
50+
let updatedChild = try await mutate(.update(savedChild))
51+
XCTAssertEqual(updatedChild.compositePKParentChildrenSansBelongsToCustomId, savedNewParent.customId)
52+
XCTAssertEqual(updatedChild.compositePKParentChildrenSansBelongsToContent, savedNewParent.content)
53+
}
54+
55+
func testDeleteChildSansBelongsTo() async throws {
56+
await setup(withModels: CompositePKModels())
57+
let parent = initParent()
58+
let savedParent = try await mutate(.create(parent))
59+
let child = initChildSansBelongsTo(with: parent)
60+
let savedChild = try await mutate(.create(child))
61+
62+
try await mutate(.delete(savedChild))
63+
try await assertModelDoesNotExist(savedChild)
64+
65+
try await mutate(.delete(savedParent))
66+
try await assertModelDoesNotExist(savedParent)
67+
}
68+
69+
func testGetChildSansBelongsTo() async throws {
70+
await setup(withModels: CompositePKModels())
71+
let parent = initParent()
72+
let savedParent = try await mutate(.create(parent))
73+
let child = initChildSansBelongsTo(with: parent)
74+
let savedChild = try await mutate(.create(child))
75+
76+
// query parent and load the children
77+
let queriedParent = try await query(.get(CompositePKParent.self,
78+
byIdentifier: .identifier(customId: savedParent.customId,
79+
content: savedParent.content)))!
80+
81+
assertList(queriedParent.childrenSansBelongsTo!, state: .isNotLoaded(associatedIdentifiers: [queriedParent.customId,
82+
queriedParent.content],
83+
associatedFields: ["compositePKParentChildrenSansBelongsToCustomId", "compositePKParentChildrenSansBelongsToContent"]))
84+
try await queriedParent.childrenSansBelongsTo?.fetch()
85+
assertList(queriedParent.childrenSansBelongsTo!, state: .isLoaded(count: 1))
86+
87+
// query children and verify the parent - ChildSansBelongsTo
88+
let queriedChildSansBelongsTo = try await query(.get(ChildSansBelongsTo.self,
89+
byIdentifier: .identifier(childId: savedChild.childId,
90+
content: savedChild.content)))!
91+
XCTAssertEqual(queriedChildSansBelongsTo.compositePKParentChildrenSansBelongsToCustomId, savedParent.customId)
92+
XCTAssertEqual(queriedChildSansBelongsTo.compositePKParentChildrenSansBelongsToContent, savedParent.content)
93+
}
94+
95+
func testListChildSansBelongsTo() async throws {
96+
await setup(withModels: CompositePKModels())
97+
let parent = initParent()
98+
let savedParent = try await mutate(.create(parent))
99+
let child = initChildSansBelongsTo(with: savedParent)
100+
try await mutate(.create(child))
101+
102+
var queriedChild = try await listQuery(.list(ChildSansBelongsTo.self,
103+
where: ChildSansBelongsTo.keys.childId == child.childId && ChildSansBelongsTo.keys.content == child.content))
104+
while queriedChild.hasNextPage() {
105+
queriedChild = try await queriedChild.getNextPage()
106+
}
107+
assertList(queriedChild, state: .isLoaded(count: 1))
108+
}
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
import Combine
10+
import XCTest
11+
12+
@testable import Amplify
13+
import AWSPluginsCore
14+
15+
extension GraphQLLazyLoadCompositePKTests {
16+
17+
// MARK: - CompositePKParent / CompositePKChild
18+
19+
func initChild(with parent: CompositePKParent? = nil) -> CompositePKChild {
20+
CompositePKChild(childId: UUID().uuidString, content: "content", parent: parent)
21+
}
22+
23+
func testSaveCompositePKChild() async throws {
24+
await setup(withModels: CompositePKModels())
25+
26+
let parent = initParent()
27+
let savedParent = try await mutate(.create(parent))
28+
let child = initChild(with: savedParent)
29+
try await mutate(.create(child))
30+
}
31+
32+
func testUpdateCompositePKChild() async throws {
33+
await setup(withModels: CompositePKModels())
34+
let parent = initParent()
35+
let savedParent = try await mutate(.create(parent))
36+
let child = initChild(with: parent)
37+
var savedChild = try await mutate(.create(child))
38+
let loadedParent = try await savedChild.parent
39+
XCTAssertEqual(loadedParent?.identifier, savedParent.identifier)
40+
41+
// update the child to a new parent
42+
let newParent = initParent()
43+
let savedNewParent = try await mutate(.create(newParent))
44+
savedChild.setParent(savedNewParent)
45+
let updatedChild = try await mutate(.update(savedChild))
46+
let loadedNewParent = try await updatedChild.parent
47+
XCTAssertEqual(loadedNewParent?.identifier, savedNewParent.identifier)
48+
}
49+
50+
func testUpdateFromNoParentCompositePKChild() async throws {
51+
await setup(withModels: CompositePKModels())
52+
let parent = initParent()
53+
let savedParent = try await mutate(.create(parent))
54+
55+
let childWithoutParent = initChild()
56+
var savedChild = try await mutate(.create(childWithoutParent))
57+
let nilParent = try await savedChild.parent
58+
XCTAssertNil(nilParent)
59+
60+
// update the child to a parent
61+
savedChild.setParent(savedParent)
62+
let savedChildWithParent = try await mutate(.update(savedChild))
63+
let loadedParent = try await savedChildWithParent.parent
64+
XCTAssertEqual(loadedParent?.identifier, savedParent.identifier)
65+
}
66+
67+
func testDeleteCompositePKChild() async throws {
68+
await setup(withModels: CompositePKModels())
69+
let parent = initParent()
70+
let savedParent = try await mutate(.create(parent))
71+
let child = initChild(with: parent)
72+
let savedChild = try await mutate(.create(child))
73+
74+
try await mutate(.delete(savedParent))
75+
try await assertModelDoesNotExist(savedParent)
76+
try await mutate(.delete(savedChild))
77+
try await assertModelDoesNotExist(savedChild)
78+
}
79+
80+
func testGetCompositePKChild() async throws {
81+
await setup(withModels: CompositePKModels())
82+
83+
let parent = initParent()
84+
let savedParent = try await mutate(.create(parent))
85+
let child = initChild(with: parent)
86+
let savedCompositePKChild = try await mutate(.create(child))
87+
88+
// query parent and load the children
89+
let queriedParent = try await query(.get(CompositePKParent.self,
90+
byIdentifier: .identifier(customId: savedParent.customId,
91+
content: savedParent.content)))!
92+
assertList(queriedParent.children!, state: .isNotLoaded(associatedIdentifiers: [queriedParent.customId,
93+
queriedParent.content],
94+
associatedFields: ["parent"]))
95+
try await queriedParent.children?.fetch()
96+
assertList(queriedParent.children!, state: .isLoaded(count: 1))
97+
98+
// query child and load the parent - CompositePKChild
99+
let queriedCompositePKChild = try await query(.get(CompositePKChild.self,
100+
byIdentifier: .identifier(childId: savedCompositePKChild.childId,
101+
content: savedCompositePKChild.content)))!
102+
assertLazyReference(queriedCompositePKChild._parent,
103+
state: .notLoaded(identifiers: [.init(name: "customId", value: savedParent.customId),
104+
.init(name: "content", value: savedParent.content)]))
105+
let loadedParent = try await queriedCompositePKChild.parent
106+
assertLazyReference(queriedCompositePKChild._parent,
107+
state: .loaded(model: loadedParent))
108+
}
109+
110+
func testListCompositePKChild() async throws {
111+
await setup(withModels: CompositePKModels())
112+
let parent = initParent()
113+
let savedParent = try await mutate(.create(parent))
114+
let child = initChild(with: savedParent)
115+
try await mutate(.create(child))
116+
117+
var queriedChild = try await listQuery(.list(CompositePKChild.self,
118+
where: CompositePKChild.keys.childId == child.childId))
119+
while queriedChild.hasNextPage() {
120+
queriedChild = try await queriedChild.getNextPage()
121+
}
122+
assertList(queriedChild, state: .isLoaded(count: 1))
123+
}
124+
}

0 commit comments

Comments
 (0)