Fix incorrect serialization of a single object inputted as an array. closes #1289

This commit is contained in:
Blake Watters
2013-03-20 10:39:14 -04:00
parent 407b879a52
commit 24c0a25519
2 changed files with 32 additions and 8 deletions

View File

@@ -85,7 +85,7 @@ static RKRequestDescriptor *RKRequestDescriptorFromArrayMatchingObject(NSArray *
@interface RKObjectParameters : NSObject
@property (nonatomic, strong) NSMutableDictionary *parameters;
- (void)addParameters:(NSDictionary *)serialization atRootKeyPath:(NSString *)rootKeyPath;
- (void)addParameters:(NSDictionary *)serialization atRootKeyPath:(NSString *)rootKeyPath inArray:(BOOL)inArray;
@end
@@ -100,7 +100,7 @@ static RKRequestDescriptor *RKRequestDescriptorFromArrayMatchingObject(NSArray *
return self;
}
- (void)addParameters:(NSDictionary *)parameters atRootKeyPath:(NSString *)rootKeyPath
- (void)addParameters:(NSDictionary *)parameters atRootKeyPath:(NSString *)rootKeyPath inArray:(BOOL)inArray
{
id rootKey = rootKeyPath ?: [NSNull null];
id nonNestedParameters = rootKeyPath ? [parameters objectForKey:rootKeyPath] : parameters;
@@ -115,7 +115,7 @@ static RKRequestDescriptor *RKRequestDescriptorFromArrayMatchingObject(NSArray *
[NSException raise:NSInvalidArgumentException format:@"Unexpected argument of type '%@': expected an NSDictionary or NSArray.", [value class]];
}
} else {
[self.parameters setObject:nonNestedParameters forKey:rootKey];
[self.parameters setObject:(inArray ? @[ nonNestedParameters ] : nonNestedParameters) forKey:rootKey];
}
}
@@ -394,16 +394,18 @@ static NSString *RKMIMETypeFromAFHTTPClientParameterEncoding(AFHTTPClientParamet
{
NSArray *objectsToParameterize = ([object isKindOfClass:[NSArray class]] || object == nil) ? object : @[ object ];
RKObjectParameters *objectParameters = [RKObjectParameters new];
for (id object in objectsToParameterize) {
RKRequestDescriptor *requestDescriptor = RKRequestDescriptorFromArrayMatchingObject(self.requestDescriptors, object);
for (id objectToParameterize in objectsToParameterize) {
RKRequestDescriptor *requestDescriptor = RKRequestDescriptorFromArrayMatchingObject(self.requestDescriptors, objectToParameterize);
if ((method != RKRequestMethodGET && method != RKRequestMethodDELETE) && requestDescriptor) {
NSError *error = nil;
NSDictionary *parametersForObject = [RKObjectParameterization parametersWithObject:object requestDescriptor:requestDescriptor error:&error];
NSDictionary *parametersForObject = [RKObjectParameterization parametersWithObject:objectToParameterize requestDescriptor:requestDescriptor error:&error];
if (error) {
RKLogError(@"Object parameterization failed while building %@ request for object '%@': %@", RKStringFromRequestMethod(method), object, error);
RKLogError(@"Object parameterization failed while building %@ request for object '%@': %@", RKStringFromRequestMethod(method), objectToParameterize, error);
return nil;
}
[objectParameters addParameters:parametersForObject atRootKeyPath:requestDescriptor.rootKeyPath];
// Ensure that a single object inputted as an array is emitted as an array when serialized
BOOL inArray = ([object isKindOfClass:[NSArray class]] && [object count] == 1);
[objectParameters addParameters:parametersForObject atRootKeyPath:requestDescriptor.rootKeyPath inArray:inArray];
}
}
id requestParameters = [objectParameters requestParameters];

View File

@@ -785,6 +785,28 @@
expect(array).to.equal(expected);
}
- (void)testPostingAnArrayWithSingleObjectGeneratesAnArray
{
RKObjectMapping *firstRequestMapping = [RKObjectMapping requestMapping];
[firstRequestMapping addAttributeMappingsFromArray:@[ @"name", @"emailAddress" ]];
RKRequestDescriptor *firstRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:firstRequestMapping objectClass:[RKTestUser class] rootKeyPath:@"whatever"];
RKTestUser *user = [RKTestUser new];
user.name = @"Blake";
user.emailAddress = @"blake@restkit.org";
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager addRequestDescriptor:firstRequestDescriptor];
NSArray *arrayOfObjects = @[ user ];
NSURLRequest *request = [objectManager requestWithObject:arrayOfObjects method:RKRequestMethodPOST path:@"/path" parameters:nil];
NSArray *array = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
NSDictionary *expected = @{ @"whatever": @[ @{ @"name": @"Blake", @"emailAddress": @"blake@restkit.org" } ] };
expect(array).to.equal(expected);
}
- (void)testPostingNilObjectWithExtraParameters
{
RKObjectMapping *firstRequestMapping = [RKObjectMapping requestMapping];