Files
RestKit/Specs/ObjectMapping/RKObjectLoaderSpec.m
Blake Watters 2d281e60d3 Investigated issues surrounding inability to change HTTP AUTH credentials thoroughly. fixes #250, #237, #127
These issues has been open for some time. I have added thorough unit test coverage
for scenarios of mutating the HTTP AUTH credentials on the RKClient and on individual
RKRequest instances. Everything seems to work fine.

Also added RKAuthenticationExample to RKCatalog for testing. Needs to be updated with
support for using OAuth.
2011-09-27 23:59:06 -04:00

524 lines
24 KiB
Objective-C

//
// RKObjectLoaderSpec.m
// RestKit
//
// Created by Blake Watters on 4/27/11.
// Copyright 2011 Two Toasters
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "RKSpecEnvironment.h"
#import "RKObjectMappingProvider.h"
#import "RKErrorMessage.h"
#import "RKJSONParserJSONKit.h"
// Models
#import "RKObjectLoaderSpecResultModel.h"
@interface RKSpecComplexUser : NSObject {
NSNumber* _userID;
NSString* _firstname;
NSString* _lastname;
NSString* _email;
NSString* _phone;
}
@property (nonatomic, retain) NSNumber* userID;
@property (nonatomic, retain) NSString* firstname;
@property (nonatomic, retain) NSString* lastname;
@property (nonatomic, retain) NSString* email;
@property (nonatomic, retain) NSString* phone;
@end
@implementation RKSpecComplexUser
@synthesize userID = _userID;
@synthesize firstname = _firstname;
@synthesize lastname = _lastname;
@synthesize phone = _phone;
@synthesize email = _email;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"id", @"userID",
@"firstname", @"firstname",
@"lastname", @"lastname",
@"email", @"email",
@"phone", @"phone",
nil];
}
- (void)willSendWithObjectLoader:(RKObjectLoader *)objectLoader {
NSLog(@"RKSpecComplexUser willSendWithObjectLoader: INVOKED!!");
return;
}
@end
@interface RKSpecResponseLoaderWithWillMapData : RKSpecResponseLoader {
id _mappableData;
}
@property (nonatomic, readonly) id mappableData;
@end
@implementation RKSpecResponseLoaderWithWillMapData
@synthesize mappableData = _mappableData;
- (void)dealloc {
[_mappableData release];
[super dealloc];
}
- (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData {
[*mappableData setValue:@"monkey!" forKey:@"newKey"];
_mappableData = [*mappableData retain];
}
@end
/////////////////////////////////////////////////////////////////////////////
@interface RKObjectLoaderSpec : RKSpec {
}
@end
@implementation RKObjectLoaderSpec
- (RKObjectMappingProvider*)providerForComplexUser {
RKObjectMappingProvider* provider = [[RKObjectMappingProvider new] autorelease];
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[userMapping addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@"firstname" toKeyPath:@"firstname"]];
[provider setMapping:userMapping forKeyPath:@"data.STUser"];
return provider;
}
- (RKObjectMappingProvider*)errorMappingProvider {
RKObjectMappingProvider* provider = [[RKObjectMappingProvider new] autorelease];
RKObjectMapping* errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
[errorMapping addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@"" toKeyPath:@"errorMessage"]];
[provider setMapping:errorMapping forKeyPath:@"error"];
[provider setMapping:errorMapping forKeyPath:@"errors"];
return provider;
}
- (void)itShouldHandleTheErrorCaseAppropriately {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [objectManager objectLoaderWithResourcePath:@"/errors.json" delegate:responseLoader];
objectLoader.method = RKRequestMethodGET;
[objectManager setMappingProvider:[self errorMappingProvider]];
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
[expectThat(responseLoader.failureError) shouldNot:be(nil)];
[expectThat([responseLoader.failureError localizedDescription]) should:be(@"error1, error2")];
NSArray* objects = [[responseLoader.failureError userInfo] objectForKey:RKObjectMapperErrorObjectsKey];
RKErrorMessage* error1 = [objects objectAtIndex:0];
RKErrorMessage* error2 = [objects lastObject];
[expectThat(error1.errorMessage) should:be(@"error1")];
[expectThat(error2.errorMessage) should:be(@"error2")];
}
- (void)itShouldNotCrashWhenLoadingAnErrorResponseWithAnUnmappableMIMEType {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecStubNetworkAvailability(YES);
RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader];
[objectManager loadObjectsAtResourcePath:@"/404" delegate:loader];
[loader waitForResponse];
assertThatBool(loader.unknownResponse, is(equalToBool(YES)));
}
#pragma mark - Complex JSON
- (void)itShouldLoadAComplexUserObjectWithTargetObject {
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [objectManager objectLoaderWithResourcePath:@"/JSON/ComplexNestedUser.json" delegate:responseLoader];
NSString *authString = [NSString stringWithFormat:@"TRUEREST username=%@&password=%@&apikey=123456&class=iphone", @"username", @"password"];
[objectLoader.URLRequest addValue:authString forHTTPHeaderField:@"Authorization"];
objectLoader.method = RKRequestMethodGET;
objectLoader.targetObject = user;
[objectManager setMappingProvider:[self providerForComplexUser]];
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
NSLog(@"Response: %@", responseLoader.objects);
[expectThat(user.firstname) should:be(@"Diego")];
}
- (void)itShouldLoadAComplexUserObjectWithoutTargetObject {
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [objectManager objectLoaderWithResourcePath:@"/JSON/ComplexNestedUser.json" delegate:responseLoader];
objectLoader.method = RKRequestMethodGET;
[objectManager setMappingProvider:[self providerForComplexUser]];
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
[expectThat([responseLoader.objects count]) should:be(1)];
RKSpecComplexUser* user = [responseLoader.objects lastObject];
[expectThat(user.firstname) should:be(@"Diego")];
}
- (void)itShouldLoadAComplexUserObjectUsingRegisteredKeyPath {
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [objectManager objectLoaderWithResourcePath:@"/JSON/ComplexNestedUser.json" delegate:responseLoader];
objectLoader.method = RKRequestMethodGET;
[objectManager setMappingProvider:[self providerForComplexUser]];
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
[expectThat([responseLoader.objects count]) should:be(1)];
RKSpecComplexUser* user = [responseLoader.objects lastObject];
[expectThat(user.firstname) should:be(@"Diego")];
}
#pragma mark - willSendWithObjectLoader:
- (void)itShouldInvokeWillSendWithObjectLoaderOnSend {
// RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[objectManager setMappingProvider:[self providerForComplexUser]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
id mockObject = [OCMockObject partialMockForObject:user];
// Explicitly init so we don't get a managed object loader...
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [[RKObjectLoader alloc] initWithResourcePath:@"/" objectManager:objectManager delegate:responseLoader];
objectLoader.sourceObject = mockObject;
[[mockObject expect] willSendWithObjectLoader:objectLoader];
[objectLoader send];
[responseLoader waitForResponse];
[mockObject verify];
}
- (void)itShouldInvokeWillSendWithObjectLoaderOnSendAsynchronously {
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
[objectManager setMappingProvider:[self providerForComplexUser]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
id mockObject = [OCMockObject partialMockForObject:user];
// Explicitly init so we don't get a managed object loader...
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [[RKObjectLoader alloc] initWithResourcePath:@"/" objectManager:objectManager delegate:responseLoader];
objectLoader.sourceObject = mockObject;
[[mockObject expect] willSendWithObjectLoader:objectLoader];
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
[mockObject verify];
}
- (void)itShouldInvokeWillSendWithObjectLoaderOnSendSynchronously {
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
[objectManager setMappingProvider:[self providerForComplexUser]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
id mockObject = [OCMockObject partialMockForObject:user];
// Explicitly init so we don't get a managed object loader...
RKObjectLoader* objectLoader = [[RKObjectLoader alloc] initWithResourcePath:@"/" objectManager:objectManager delegate:nil];
objectLoader.sourceObject = mockObject;
[[mockObject expect] willSendWithObjectLoader:objectLoader];
[objectLoader sendSynchronously];
[mockObject verify];
}
- (void)itShouldLoadResultsNestedAtAKeyPath {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKObjectMapping* objectMapping = [RKObjectMapping mappingForClass:[RKObjectLoaderSpecResultModel class]];
[objectMapping mapKeyPath:@"id" toAttribute:@"ID"];
[objectMapping mapKeyPath:@"ends_at" toAttribute:@"endsAt"];
[objectMapping mapKeyPath:@"photo_url" toAttribute:@"photoURL"];
[objectManager.mappingProvider setMapping:objectMapping forKeyPath:@"results"];
RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader];
[objectManager loadObjectsAtResourcePath:@"/JSON/ArrayOfResults.json" delegate:loader];
[loader waitForResponse];
assertThat([loader objects], hasCountOf(2));
assertThat([[[loader objects] objectAtIndex:0] ID], is(equalToInt(226)));
assertThat([[[loader objects] objectAtIndex:0] photoURL], is(equalTo(@"1308262872.jpg")));
assertThat([[[loader objects] objectAtIndex:1] ID], is(equalToInt(235)));
assertThat([[[loader objects] objectAtIndex:1] photoURL], is(equalTo(@"1308634984.jpg")));
}
- (void)itShouldAllowMutationOfTheParsedDataInWillMapData {
RKSpecResponseLoaderWithWillMapData* loader = (RKSpecResponseLoaderWithWillMapData*)[RKSpecResponseLoaderWithWillMapData responseLoader];
RKObjectManager* manager = RKSpecNewObjectManager();
RKSpecStubNetworkAvailability(YES);
[manager loadObjectsAtResourcePath:@"/JSON/humans/1.json" delegate:loader];
[loader waitForResponse];
assertThat([loader.mappableData valueForKey:@"newKey"], is(equalTo(@"monkey!")));
}
- (void)itShouldAllowYouToPostAnObjectAndHandleAnEmpty204Response {
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[mapping mapAttributes:@"firstname", @"lastname", @"email", nil];
RKObjectMapping* serializationMapping = [mapping inverseMapping];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[objectManager.router routeClass:[RKSpecComplexUser class] toResourcePath:@"/204"];
[objectManager.mappingProvider setSerializationMapping:serializationMapping forClass:[RKSpecComplexUser class]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* loader = [objectManager objectLoaderForObject:user method:RKRequestMethodPOST delegate:responseLoader];
loader.objectMapping = mapping;
[loader send];
[responseLoader waitForResponse];
assertThatBool([responseLoader success], is(equalToBool(YES)));
assertThat(user.email, is(equalTo(@"blake@restkit.org")));
}
- (void)itShouldAllowYouToPOSTAnObjectAndMapBackNonNestedContent {
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[mapping mapAttributes:@"firstname", @"lastname", @"email", nil];
RKObjectMapping* serializationMapping = [mapping inverseMapping];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[objectManager.router routeClass:[RKSpecComplexUser class] toResourcePath:@"/notNestedUser"];
[objectManager.mappingProvider setSerializationMapping:serializationMapping forClass:[RKSpecComplexUser class]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* loader = [objectManager objectLoaderForObject:user method:RKRequestMethodPOST delegate:responseLoader];
loader.objectMapping = mapping;
[loader send];
[responseLoader waitForResponse];
assertThatBool([responseLoader success], is(equalToBool(YES)));
assertThat(user.email, is(equalTo(@"changed")));
}
- (void)itShouldMapContentWithoutAMIMEType {
// TODO: Not sure that this is even worth it. Unable to get the Sinatra server to produce such a response
return;
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[mapping mapAttributes:@"firstname", @"lastname", @"email", nil];
RKObjectMapping* serializationMapping = [mapping inverseMapping];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[[RKParserRegistry sharedRegistry] setParserClass:[RKJSONParserJSONKit class] forMIMEType:@"text/html"];
[objectManager.router routeClass:[RKSpecComplexUser class] toResourcePath:@"/noMIME"];
[objectManager.mappingProvider setSerializationMapping:serializationMapping forClass:[RKSpecComplexUser class]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* loader = [objectManager objectLoaderForObject:user method:RKRequestMethodPOST delegate:responseLoader];
loader.objectMapping = mapping;
[loader send];
[responseLoader waitForResponse];
assertThatBool([responseLoader success], is(equalToBool(YES)));
assertThat(user.email, is(equalTo(@"changed")));
}
- (void)itShouldAllowYouToPOSTAnObjectOfOneTypeAndGetBackAnother {
RKObjectMapping* sourceMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[sourceMapping mapAttributes:@"firstname", @"lastname", @"email", nil];
RKObjectMapping* serializationMapping = [sourceMapping inverseMapping];
RKObjectMapping* targetMapping = [RKObjectMapping mappingForClass:[RKObjectLoaderSpecResultModel class]];
[targetMapping mapAttributes:@"ID", nil];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[objectManager.router routeClass:[RKSpecComplexUser class] toResourcePath:@"/notNestedUser"];
[objectManager.mappingProvider setSerializationMapping:serializationMapping forClass:[RKSpecComplexUser class]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* loader = [objectManager objectLoaderForObject:user method:RKRequestMethodPOST delegate:responseLoader];
loader.sourceObject = user;
loader.targetObject = nil;
loader.objectMapping = targetMapping;
[loader send];
[responseLoader waitForResponse];
assertThatBool([responseLoader success], is(equalToBool(YES)));
// Our original object should not have changed
assertThat(user.email, is(equalTo(@"blake@restkit.org")));
// And we should have a new one
RKObjectLoaderSpecResultModel* newObject = [[responseLoader objects] lastObject];
assertThat(newObject, is(instanceOf([RKObjectLoaderSpecResultModel class])));
assertThat(newObject.ID, is(equalToInt(31337)));
}
// TODO: Should live in a different file...
- (void)itShouldAllowYouToPOSTAnObjectAndMapBackNonNestedContentViapostObject {
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[mapping mapAttributes:@"firstname", @"lastname", @"email", nil];
RKObjectMapping* serializationMapping = [mapping inverseMapping];
RKObjectManager* objectManager = RKSpecNewObjectManager();
[objectManager.router routeClass:[RKSpecComplexUser class] toResourcePath:@"/notNestedUser"];
[objectManager.mappingProvider setSerializationMapping:serializationMapping forClass:[RKSpecComplexUser class]];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
// NOTE: The postObject: should infer the target object from sourceObject and the mapping class
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
[objectManager postObject:user mapResponseWith:mapping delegate:responseLoader];
[responseLoader waitForResponse];
assertThatBool([responseLoader success], is(equalToBool(YES)));
assertThat(user.email, is(equalTo(@"changed")));
}
- (void)itShouldRespectTheRootKeyPathWhenConstructingATemporaryObjectMappingProvider {
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
userMapping.rootKeyPath = @"data.STUser";
[userMapping mapAttributes:@"firstname", nil];
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:RKSpecGetBaseURL()];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [objectManager objectLoaderWithResourcePath:@"/JSON/ComplexNestedUser.json" delegate:responseLoader];
objectLoader.objectMapping = userMapping;
objectLoader.method = RKRequestMethodGET;
objectLoader.targetObject = user;
[objectLoader sendAsynchronously];
[responseLoader waitForResponse];
NSLog(@"Response: %@", responseLoader.objects);
[expectThat(user.firstname) should:be(@"Diego")];
}
- (void)itShouldReturnSuccessWhenTheStatusCodeIs200AndTheResponseBodyIsEmpty {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
userMapping.rootKeyPath = @"data.STUser";
[userMapping mapAttributes:@"firstname", nil];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [RKObjectLoader loaderWithResourcePath:@"/humans/1234" objectManager:objectManager delegate:responseLoader];
objectLoader.method = RKRequestMethodDELETE;
objectLoader.objectMapping = userMapping;
objectLoader.targetObject = user;
[objectLoader send];
[responseLoader waitForResponse];
assertThatBool(responseLoader.success, is(equalToBool(YES)));
}
- (void)itShouldInvokeTheDelegateWithTheTargetObjectWhenTheStatusCodeIs200AndTheResponseBodyIsEmpty {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecComplexUser* user = [[RKSpecComplexUser new] autorelease];
user.firstname = @"Blake";
user.lastname = @"Watters";
user.email = @"blake@restkit.org";
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
userMapping.rootKeyPath = @"data.STUser";
[userMapping mapAttributes:@"firstname", nil];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
RKObjectLoader* objectLoader = [RKObjectLoader loaderWithResourcePath:@"/humans/1234" objectManager:objectManager delegate:responseLoader];
objectLoader.method = RKRequestMethodDELETE;
objectLoader.objectMapping = userMapping;
objectLoader.targetObject = user;
[objectLoader send];
[responseLoader waitForResponse];
assertThat(responseLoader.objects, hasItem(user));
}
- (void)itShouldConsiderTheLoadOfEmptyObjectsWithoutAnyMappableAttributesAsSuccess {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKSpecComplexUser class]];
[userMapping mapAttributes:@"firstname", nil];
[objectManager.mappingProvider setMapping:userMapping forKeyPath:@"firstUser"];
[objectManager.mappingProvider setMapping:userMapping forKeyPath:@"secondUser"];
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
[objectManager loadObjectsAtResourcePath:@"/users/empty" delegate:responseLoader];
[responseLoader waitForResponse];
assertThatBool(responseLoader.success, is(equalToBool(YES)));
}
- (void)itShouldInvokeTheDelegateOnSuccessIfTheResponseIsAnEmptyArray {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
responseLoader.timeout = 20;
[objectManager loadObjectsAtResourcePath:@"/empty/array" delegate:responseLoader];
[responseLoader waitForResponse];
assertThat(responseLoader.objects, isNot(nilValue()));
assertThatBool([responseLoader.objects isKindOfClass:[NSArray class]], is(equalToBool(YES)));
assertThat(responseLoader.objects, is(empty()));
}
- (void)itShouldInvokeTheDelegateOnSuccessIfTheResponseIsAnEmptyDictionary {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
responseLoader.timeout = 20;
[objectManager loadObjectsAtResourcePath:@"/empty/dictionary" delegate:responseLoader];
[responseLoader waitForResponse];
assertThat(responseLoader.objects, isNot(nilValue()));
assertThatBool([responseLoader.objects isKindOfClass:[NSArray class]], is(equalToBool(YES)));
assertThat(responseLoader.objects, is(empty()));
}
- (void)itShouldInvokeTheDelegateOnSuccessIfTheResponseIsAnEmptyString {
RKObjectManager* objectManager = RKSpecNewObjectManager();
RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader];
responseLoader.timeout = 20;
[objectManager loadObjectsAtResourcePath:@"/empty/string" delegate:responseLoader];
[responseLoader waitForResponse];
assertThat(responseLoader.objects, isNot(nilValue()));
assertThatBool([responseLoader.objects isKindOfClass:[NSArray class]], is(equalToBool(YES)));
assertThat(responseLoader.objects, is(empty()));
}
@end