Skip to content

Commit d884477

Browse files
authored
Adding custom 'items' deserialization for List (#711)
1 parent 4cb4423 commit d884477

File tree

4 files changed

+118
-2
lines changed

4 files changed

+118
-2
lines changed

Amplify/Categories/DataStore/Model/Collection/List+Model.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ public class List<ModelType: Model>: Collection, Codable, ExpressibleByArrayLite
112112
let field = Element.schema.field(withName: associatedField)
113113
// TODO handle eager loaded associations with elements
114114
self.init([], associatedId: associatedId, associatedField: field)
115+
} else if case let .array(jsonArray) = list["items"] {
116+
let encoder = JSONEncoder()
117+
encoder.dateEncodingStrategy = ModelDateFormatting.encodingStrategy
118+
let decoder = JSONDecoder()
119+
decoder.dateDecodingStrategy = ModelDateFormatting.decodingStrategy
120+
let elements = try jsonArray.map { (jsonElement) -> Element in
121+
let serializedJSON = try encoder.encode(jsonElement)
122+
return try decoder.decode(Element.self, from: serializedJSON)
123+
}
124+
125+
self.init(elements)
115126
} else {
116127
self.init(Elements())
117128
}

AmplifyPlugins/API/AWSAPICategoryPluginFunctionalTests/AnyModelIntegrationTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class AnyModelIntegrationTests: XCTestCase {
8484
XCTFail("partial: \(model), \(errors)")
8585
case .transformationError(let rawResponse, let apiError):
8686
XCTFail("transformationError: \(rawResponse), \(apiError)")
87+
case .unknown(let errorDescription, let recoverySuggestion, _):
88+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
8789
}
8890
}
8991
return
@@ -148,6 +150,8 @@ class AnyModelIntegrationTests: XCTestCase {
148150
XCTFail("partial: \(model), \(errors)")
149151
case .transformationError(let rawResponse, let apiError):
150152
XCTFail("transformationError: \(rawResponse), \(apiError)")
153+
case .unknown(let errorDescription, let recoverySuggestion, _):
154+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
151155
}
152156
}
153157
return
@@ -205,6 +209,8 @@ class AnyModelIntegrationTests: XCTestCase {
205209
XCTFail("partial: \(model), \(errors)")
206210
case .transformationError(let rawResponse, let apiError):
207211
XCTFail("transformationError: \(rawResponse), \(apiError)")
212+
case .unknown(let errorDescription, let recoverySuggestion, _):
213+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
208214
}
209215
}
210216
return

AmplifyPlugins/API/AWSAPICategoryPluginFunctionalTests/GraphQLModelBased/GraphQLModelBasedTests.swift

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,93 @@ class GraphQLModelBasedTests: XCTestCase {
7373
wait(for: [completeInvoked], timeout: TestCommonConstants.networkTimeout)
7474
}
7575

76+
/// Test custom GraphQLRequest with nested list deserializes to generated Post Model
77+
///
78+
/// - Given: A post containing a single comment
79+
/// - When:
80+
/// - Query for the post with nested selection set containing list of comments
81+
/// - Then:
82+
/// - The resulting post object contains the list of comments
83+
///
84+
func testCustomQueryPostWithComments() {
85+
let uuid = UUID().uuidString
86+
let testMethodName = String("\(#function)".dropLast(2))
87+
let title = testMethodName + "Title"
88+
guard let post = createPost(id: uuid, title: title) else {
89+
XCTFail("Failed to set up test")
90+
return
91+
}
92+
guard createComment(content: "content", post: post) != nil else {
93+
XCTFail("Failed to create comment with post")
94+
return
95+
}
96+
97+
let completeInvoked = expectation(description: "request completed")
98+
let document = """
99+
query getPost($id: ID!) {
100+
getPost(id: $id){
101+
id
102+
title
103+
content
104+
createdAt
105+
updatedAt
106+
draft
107+
rating
108+
status
109+
comments {
110+
items {
111+
id
112+
content
113+
createdAt
114+
updatedAt
115+
post {
116+
id
117+
title
118+
content
119+
createdAt
120+
updatedAt
121+
draft
122+
rating
123+
status
124+
}
125+
}
126+
nextToken
127+
}
128+
}
129+
}
130+
"""
131+
let graphQLRequest = GraphQLRequest(document: document,
132+
variables: ["id": uuid],
133+
responseType: Post?.self,
134+
decodePath: "getPost")
135+
_ = Amplify.API.query(request: graphQLRequest) { event in
136+
switch event {
137+
case .success(let graphQLResponse):
138+
guard case let .success(data) = graphQLResponse else {
139+
XCTFail("Missing successful response")
140+
return
141+
}
142+
guard let resultPost = data else {
143+
XCTFail("Missing post from querySingle")
144+
return
145+
}
146+
147+
XCTAssertEqual(resultPost.id, post.id)
148+
XCTAssertEqual(resultPost.title, title)
149+
guard let comments = resultPost.comments else {
150+
XCTFail("Missing comments from post")
151+
return
152+
}
153+
XCTAssertEqual(comments.count, 1)
154+
completeInvoked.fulfill()
155+
case .failure(let error):
156+
XCTFail("Unexpected .failed event: \(error)")
157+
}
158+
}
159+
160+
wait(for: [completeInvoked], timeout: TestCommonConstants.networkTimeout)
161+
}
162+
76163
func testListQueryWithModel() {
77164
let uuid = UUID().uuidString
78165
let testMethodName = String("\(#function)".dropLast(2))
@@ -185,8 +272,8 @@ class GraphQLModelBasedTests: XCTestCase {
185272

186273
let completeInvoked = expectation(description: "request completed")
187274
let comment = Comment(content: "commentContent",
188-
createdAt: .now(),
189-
post: createdPost)
275+
createdAt: .now(),
276+
post: createdPost)
190277
_ = Amplify.API.mutate(request: .create(comment)) { event in
191278
switch event {
192279
case .success(let data):

AmplifyPlugins/API/AWSAPICategoryPluginFunctionalTests/GraphQLSyncBased/GraphQLSyncBasedTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class GraphQLSyncBasedTests: XCTestCase {
8181
XCTFail("partial: \(String(describing: model)), \(errors)")
8282
case .transformationError(let rawResponse, let apiError):
8383
XCTFail("transformationError: \(rawResponse), \(apiError)")
84+
case .unknown(let errorDescription, let recoverySuggestion, _):
85+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
8486
}
8587
}
8688
return
@@ -137,6 +139,8 @@ class GraphQLSyncBasedTests: XCTestCase {
137139
XCTFail("partial: \(String(describing: model)), \(errors)")
138140
case .transformationError(let rawResponse, let apiError):
139141
XCTFail("transformationError: \(rawResponse), \(apiError)")
142+
case .unknown(let errorDescription, let recoverySuggestion, _):
143+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
140144
}
141145
}
142146
return
@@ -208,6 +212,8 @@ class GraphQLSyncBasedTests: XCTestCase {
208212
XCTFail("partial: \(model), \(errors)")
209213
case .transformationError(let rawResponse, let apiError):
210214
XCTFail("transformationError: \(rawResponse), \(apiError)")
215+
case .unknown(let errorDescription, let recoverySuggestion, _):
216+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
211217
}
212218
}
213219
return
@@ -287,6 +293,8 @@ class GraphQLSyncBasedTests: XCTestCase {
287293
XCTFail("partial: \(model), \(errors)")
288294
case .transformationError(let rawResponse, let apiError):
289295
XCTFail("transformationError: \(rawResponse), \(apiError)")
296+
case .unknown(let errorDescription, let recoverySuggestion, _):
297+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
290298
}
291299
}
292300

@@ -381,6 +389,8 @@ class GraphQLSyncBasedTests: XCTestCase {
381389
XCTFail("partial: \(model), \(errors)")
382390
case .transformationError(let rawResponse, let apiError):
383391
XCTFail("transformationError: \(rawResponse), \(apiError)")
392+
case .unknown(let errorDescription, let recoverySuggestion, _):
393+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
384394
}
385395
}
386396

@@ -444,6 +454,8 @@ class GraphQLSyncBasedTests: XCTestCase {
444454
XCTFail("partial: \(model), \(errors)")
445455
case .transformationError(let rawResponse, let apiError):
446456
XCTFail("transformationError: \(rawResponse), \(apiError)")
457+
case .unknown(let errorDescription, let recoverySuggestion, _):
458+
XCTFail("UnknownError: \(errorDescription), \(recoverySuggestion)")
447459
}
448460
}
449461
return

0 commit comments

Comments
 (0)