Skip to content

Commit 796138d

Browse files
Add test and fix resolving included resources
Included resources were not resolved correctly. The issue was that https://github.com/joshdholtz/jsonapi-ios/blob/12b08a469a5ed3e27cd8b5872 11906ec3a495c75/Classes/JSONAPIResourceParser.m#L276-L276 was using the `Class` returned by `resourceType` as a key, however the key in the dictionary is in fact the `type` string returned by the descriptor. Furthermore the value was set using `set:withDictionary:` which fails because the included resource is already parsed by that point. I also added a test confirming the bug as well as the fix.
1 parent 12b08a4 commit 796138d

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

Classes/JSONAPIResourceParser.m

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -267,24 +267,31 @@ + (void)link:(NSObject <JSONAPIResource>*)resource withIncluded:(JSONAPI*)jsonAP
267267
// Loops through all keys to map to properties
268268
NSDictionary *properties = [descriptor properties];
269269
for (NSString *key in properties) {
270-
JSONAPIPropertyDescriptor *property = [properties objectForKey:key];
271-
if (property.resourceType) {
272-
id value = [resource valueForKey:key];
273-
if (value) {
274-
if ([value isKindOfClass:[NSArray class]]) {
275-
for (NSObject <JSONAPIResource> *element in value) {
276-
id include = included[property.resourceType][element.ID];
277-
if (include) {
278-
[self set:element withDictionary:include];
279-
}
280-
}
281-
} else {
282-
NSObject <JSONAPIResource> *attribute = value;
283-
id include = included[property.resourceType][attribute.ID];
284-
if (include) {
285-
[self set:attribute withDictionary:include];
286-
}
270+
JSONAPIPropertyDescriptor *propertyDescriptor = [properties objectForKey:key];
271+
id value = [resource valueForKey:key];
272+
id includedValue = included[[[propertyDescriptor.resourceType descriptor] type]];
273+
274+
// ordinary attribute
275+
if (propertyDescriptor.resourceType == nil) {
276+
continue;
277+
// has many
278+
} else if ([value isKindOfClass:[NSArray class]]) {
279+
NSMutableArray *matched = [value mutableCopy];
280+
[value enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
281+
NSObject <JSONAPIResource> *res = obj;
282+
id v = includedValue[res.ID];
283+
if (v != nil) {
284+
matched[idx] = v;
287285
}
286+
}];
287+
288+
[resource setValue:matched forKey:key];
289+
// has one
290+
} else if (value != nil) {
291+
NSObject <JSONAPIResource> *res = value;
292+
id v = includedValue[res.ID];
293+
if (v != nil) {
294+
[resource setValue:v forKey:key];
288295
}
289296
}
290297
}

Project/JSONAPITests/JSONAPITests.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ - (void)testDataPostAuthorAndComments {
7171
JSONAPI *jsonAPI = [JSONAPI jsonAPIWithDictionary:json];
7272

7373
PostResource *post = jsonAPI.resource;
74+
CommentResource *firstComment = post.comments.firstObject;
75+
7476
XCTAssertNotNil(post.author, @"Post's author should not be nil");
7577
XCTAssertNotNil(post.comments, @"Post's comments should not be nil");
7678
XCTAssertEqual(post.comments.count, 2, @"Post should contain 2 comments");
79+
XCTAssertEqualObjects(post.author.firstName, @"Dan", @"Post's author firstname should be 'Dan'");
80+
XCTAssertEqualObjects(firstComment.text, @"First!", @"Post's first comment should be 'First!'");
81+
XCTAssertEqualObjects(firstComment.author.firstName, @"Dan", @"Post's first comment author should be 'Dan'");
7782
}
7883

7984
- (void)testIncludedCommentIsLinked {

0 commit comments

Comments
 (0)