Skip to content

Commit dd1a3c8

Browse files
author
Julian Krumow
committed
Fix bugs in resource serialization.
- parsing related resources lead to a crash - timestamps in test fixtures did not match parser string for RFC3339DateFormatter
1 parent 118d65e commit dd1a3c8

File tree

4 files changed

+52
-41
lines changed

4 files changed

+52
-41
lines changed

Classes/JSONAPI.m

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -171,32 +171,38 @@ - (void)inflateWithDictionary:(NSDictionary*)dictionary {
171171

172172
- (void)inflateWithResource:(NSObject <JSONAPIResource> *)resource
173173
{
174-
NSMutableArray *resourceArray = [[NSMutableArray alloc] init];
175-
[resourceArray addObject:resource];
176-
_resources = resourceArray;
174+
_resources = @[resource];
177175

178-
NSMutableDictionary *newDictionary = [[NSMutableDictionary alloc] init];
176+
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
177+
dictionary[@"data"] = [JSONAPIResourceParser dictionaryFor:resource];
179178

180-
newDictionary[@"data"] = [JSONAPIResourceParser dictionaryFor:resource];
181-
182-
NSArray *included = [JSONAPIResourceParser relatedResourcesFor:resource];
183-
if (included.count) {
184-
newDictionary[@"included"] = included;
185-
186-
NSMutableDictionary *includedResources = [[NSMutableDictionary alloc] init];
187-
for (NSObject <JSONAPIResource> *linked in included) {
188-
189-
JSONAPIResourceDescriptor *desc = [[linked class] descriptor];
190-
191-
NSMutableDictionary *typeDict = includedResources[desc.type] ?: @{}.mutableCopy;
192-
typeDict[linked.ID] = resource;
193-
194-
includedResources[desc.type] = typeDict;
195-
}
196-
_includedResources = includedResources;
179+
NSArray *relatedResources = [JSONAPIResourceParser relatedResourcesFor:resource];
180+
if (relatedResources.count) {
181+
_includedResources = [self mapIncludedResources:relatedResources forResource:resource];
182+
dictionary[@"included"] = [self parseRelatedResources:relatedResources];
197183
}
198-
199-
_dictionary = newDictionary;
184+
_dictionary = dictionary;
185+
}
186+
187+
- (NSDictionary *)mapIncludedResources:(NSArray *)relatedResources forResource:(NSObject <JSONAPIResource> *)resource
188+
{
189+
NSMutableDictionary *includedResources = [NSMutableDictionary new];
190+
for (NSObject <JSONAPIResource> *linked in relatedResources) {
191+
JSONAPIResourceDescriptor *desc = [[linked class] descriptor];
192+
NSMutableDictionary *typeDict = includedResources[desc.type] ?: @{}.mutableCopy;
193+
typeDict[linked.ID] = resource;
194+
includedResources[desc.type] = typeDict;
195+
}
196+
return includedResources;
197+
}
198+
199+
- (NSArray *)parseRelatedResources:(NSArray *)relatedResources
200+
{
201+
NSMutableArray *parsedResources = [NSMutableArray new];
202+
for (NSObject <JSONAPIResource> *linked in relatedResources) {
203+
[parsedResources addObject:[JSONAPIResourceParser dictionaryFor:linked]];
204+
}
205+
return parsedResources;
200206
}
201207

202208
@end

Classes/JSONAPIResourceParser.m

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,20 +338,15 @@ + (NSArray*)relatedResourcesFor:(NSObject <JSONAPIResource>*)resource {
338338
NSDictionary *properties = [descriptor properties];
339339
for (NSString *key in properties) {
340340
JSONAPIPropertyDescriptor *property = [properties objectForKey:key];
341-
342341
if (property.resourceType) {
343-
id value = [self valueForKey:key];
342+
id value = [resource valueForKey:key];
344343
if ([value isKindOfClass:[NSArray class]]) {
345-
for (NSObject <JSONAPIResource> *element in value) {
346-
[related addObject:[JSONAPIResourceParser dictionaryFor:element]];
347-
}
344+
[related addObjectsFromArray:value];
348345
} else {
349-
NSObject <JSONAPIResource> *attribute = value;
350-
[related addObject:[JSONAPIResourceParser dictionaryFor:attribute]];
346+
[related addObject:value];
351347
}
352348
}
353349
}
354-
355350
return related;
356351
}
357352

Project/JSONAPITests/JSONAPITests.m

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import "JSONAPIResourceDescriptor.h"
1313
#import "JSONAPIErrorResource.h"
1414
#import "JSONAPIResourceParser.h"
15+
#import "NSDateFormatter+JSONAPIDateFormatter.h"
1516

1617
#import "CommentResource.h"
1718
#import "PeopleResource.h"
@@ -68,7 +69,8 @@ - (void)testDataArticles {
6869
XCTAssertTrue([article.selfLink isEqualToString:@"http://example.com/articles/1"], @"Article selfLink should be 'http://example.com/articles/1'");
6970
XCTAssertEqualObjects(article.title, @"JSON API paints my bikeshed!", @"Article title should be 'JSON API paints my bikeshed!'");
7071

71-
NSArray *dateStrings = @[@"2015-09-01T12:15:00Z",@"2015-08-01T06:15:00Z"];
72+
NSArray *dateStrings = @[[[NSDateFormatter RFC3339DateFormatter] dateFromString:@"2015-09-01T12:15:00.000Z"],
73+
[[NSDateFormatter RFC3339DateFormatter] dateFromString:@"2015-08-01T06:15:00.000Z"]];
7274
XCTAssertEqualObjects(article.versions, dateStrings, @"Article versions should contain an array of date strings");
7375
}
7476

@@ -182,13 +184,21 @@ - (void)testSerializeComplex {
182184
}
183185

184186
- (void)testCreate {
185-
PeopleResource *newAuthor = [[PeopleResource alloc] init];
186-
187-
newAuthor.firstName = @"Karl";
188-
newAuthor.lastName = @"Armstrong";
189-
190-
JSONAPI *jsonAPI = [JSONAPI jsonAPIWithResource:newAuthor];
191-
XCTAssertEqualObjects([jsonAPI dictionary][@"data"][@"type"], @"people", @"Did not create person!");
187+
NSDictionary *json = [self mainExampleJSON];
188+
JSONAPI *jsonAPI = [JSONAPI jsonAPIWithDictionary:json];
189+
190+
ArticleResource *article = jsonAPI.resource;
191+
192+
jsonAPI = [JSONAPI jsonAPIWithResource:article];
193+
NSDictionary *dictionary = [jsonAPI dictionary];
194+
XCTAssertEqualObjects(dictionary[@"data"][@"type"], @"articles", @"Did not create article!");
195+
XCTAssertEqualObjects(dictionary[@"data"][@"attributes"][@"title"], @"JSON API paints my bikeshed!", @"Did not parse title!");
196+
XCTAssertEqual([dictionary[@"data"][@"relationships"][@"comments"][@"data"] count], 2, @"Did not parse relationships!");
197+
XCTAssertEqual([dictionary[@"included"] count], 3, @"Did not parse included resources!");
198+
XCTAssertEqualObjects(dictionary[@"included"][0][@"type"], @"people", @"Did not parse included people object!");
199+
XCTAssertEqualObjects(dictionary[@"included"][0][@"id"], @"9", @"Did not parse ID!");
200+
XCTAssertEqualObjects(dictionary[@"included"][1][@"type"], @"comments", @"Did not parse included comments object!");
201+
XCTAssertEqualObjects(dictionary[@"included"][1][@"relationships"][@"author"][@"data"][@"type"], @"people", @"Did not parse included comments author!");
192202
}
193203

194204
#pragma mark - Generic relationships tests

Project/JSONAPITests/main_example.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"attributes": {
1414
"title": "JSON API paints my bikeshed!",
1515
"versions": [
16-
"2015-09-01T12:15:00Z",
17-
"2015-08-01T06:15:00Z"
16+
"2015-09-01T12:15:00.000Z",
17+
"2015-08-01T06:15:00.000Z"
1818
]
1919
},
2020
"relationships": {

0 commit comments

Comments
 (0)