Files
RestKit/Tests/Logic/ObjectMapping/RKObjectManagerTest.m
2012-10-28 20:22:53 -04:00

683 lines
37 KiB
Objective-C

//
// RKObjectManagerTest.m
// RestKit
//
// Created by Blake Watters on 1/14/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// 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 "RKTestEnvironment.h"
#import "RKObjectManager.h"
#import "RKManagedObjectStore.h"
#import "RKEntityMapping.h"
#import "RKHuman.h"
#import "RKCat.h"
#import "RKObjectMapperTestModel.h"
@interface RKTestAFHTTPClient : AFHTTPClient
@end
@implementation RKTestAFHTTPClient
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
{
NSMutableURLRequest *request = [super requestWithMethod:method path:path parameters:parameters];
[request setAllHTTPHeaderFields:@{@"test": @"value", @"Accept": @"text/html"}];
return request;
}
@end
@interface RKTestHTTPRequestOperation : RKHTTPRequestOperation
@end
@implementation RKTestHTTPRequestOperation : RKHTTPRequestOperation
@end
@interface RKObjectManagerTest : RKTestCase
@property (nonatomic, strong) RKObjectManager *objectManager;
@property (nonatomic, strong) RKRoute *humanGETRoute;
@property (nonatomic, strong) RKRoute *humanPOSTRoute;
@property (nonatomic, strong) RKRoute *humanDELETERoute;
@property (nonatomic, strong) RKRoute *humanCatsRoute;
@property (nonatomic, strong) RKRoute *humansCollectionRoute;
@end
@implementation RKObjectManagerTest
- (void)setUp
{
[RKTestFactory setUp];
self.objectManager = [RKTestFactory objectManager];
self.objectManager.managedObjectStore = [RKTestFactory managedObjectStore];
[RKObjectManager setSharedManager:self.objectManager];
NSError *error;
[self.objectManager.managedObjectStore resetPersistentStores:&error];
RKEntityMapping *humanMapping = [RKEntityMapping mappingForEntityForName:@"RKHuman" inManagedObjectStore:_objectManager.managedObjectStore];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"name" toKeyPath:@"name"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"nick-name" toKeyPath:@"nickName"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"birthday" toKeyPath:@"birthday"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"sex" toKeyPath:@"sex"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"age" toKeyPath:@"age"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"created-at" toKeyPath:@"createdAt"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"updated-at" toKeyPath:@"updatedAt"]];
[humanMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"id" toKeyPath:@"railsID"]];
RKEntityMapping *catMapping = [RKEntityMapping mappingForEntityForName:@"RKCat" inManagedObjectStore:_objectManager.managedObjectStore];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"name" toKeyPath:@"name"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"nick-name" toKeyPath:@"nickName"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"birthday" toKeyPath:@"birthday"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"sex" toKeyPath:@"sex"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"age" toKeyPath:@"age"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"created-at" toKeyPath:@"createdAt"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"updated-at" toKeyPath:@"updatedAt"]];
[catMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"id" toKeyPath:@"railsID"]];
[catMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"cats" toKeyPath:@"cats" withMapping:catMapping]];
[self.objectManager addResponseDescriptorsFromArray:@[
[RKResponseDescriptor responseDescriptorWithMapping:humanMapping pathPattern:nil keyPath:@"human" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)],
[RKResponseDescriptor responseDescriptorWithMapping:humanMapping pathPattern:nil keyPath:@"humans" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]
]];
RKObjectMapping *humanSerialization = [RKObjectMapping requestMapping];
[humanSerialization addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"name" toKeyPath:@"name"]];
[self.objectManager addRequestDescriptor:[RKRequestDescriptor requestDescriptorWithMapping:humanSerialization objectClass:[RKHuman class] rootKeyPath:@"human"]];
self.humanPOSTRoute = [RKRoute routeWithClass:[RKHuman class] pathPattern:@"/humans" method:RKRequestMethodPOST];
self.humanGETRoute = [RKRoute routeWithClass:[RKHuman class] pathPattern:@"/humans/:railsID" method:RKRequestMethodGET];
self.humanDELETERoute = [RKRoute routeWithClass:[RKHuman class] pathPattern:@"/humans/:railsID" method:RKRequestMethodDELETE];
self.humanCatsRoute = [RKRoute routeWithRelationshipName:@"cats" objectClass:[RKHuman class] pathPattern:@"/humans/:railsID/cats" method:RKRequestMethodGET];
self.humansCollectionRoute = [RKRoute routeWithName:@"humans" pathPattern:@"/humans" method:RKRequestMethodGET];
[self.objectManager.router.routeSet addRoute:self.humanPOSTRoute];
[self.objectManager.router.routeSet addRoute:self.humanGETRoute];
[self.objectManager.router.routeSet addRoute:self.humanDELETERoute];
[self.objectManager.router.routeSet addRoute:self.humanCatsRoute];
[self.objectManager.router.routeSet addRoute:self.humansCollectionRoute];
}
- (void)tearDown
{
[RKTestFactory tearDown];
}
- (void)testInitializationWithBaseURLSetsDefaultAcceptHeaderValueToJSON
{
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
expect([manager defaultHeaders][@"Accept"]).to.equal(RKMIMETypeJSON);
}
- (void)testInitializationWithBaseURLSetsRequestSerializationMIMETypeToFormURLEncoded
{
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
expect(manager.requestSerializationMIMEType).to.equal(RKMIMETypeFormURLEncoded);
}
- (void)testInitializationWithAFHTTPClientSetsNilAcceptHeaderValue
{
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
[client setDefaultHeader:@"Accept" value:@"this/that"];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:client];
expect([manager defaultHeaders][@"Accept"]).to.equal(@"this/that");
}
- (void)testDefersToAFHTTPClientParameterEncodingWhenInitializedWithAFHTTPClient
{
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
client.parameterEncoding = AFJSONParameterEncoding;
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:client];
expect([manager requestSerializationMIMEType]).to.equal(RKMIMETypeJSON);
}
- (void)testDefaultsToFormURLEncodingForUnsupportedParameterEncodings
{
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
client.parameterEncoding = AFPropertyListParameterEncoding;
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:client];
expect([manager requestSerializationMIMEType]).to.equal(RKMIMETypeFormURLEncoded);
}
// TODO: Move to Core Data specific spec file...
- (void)testShouldUpdateACoreDataBackedTargetObject
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
RKManagedObjectRequestOperation *operation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodPOST path:nil parameters:nil];
[operation start];
[operation waitUntilFinished];
expect(operation.mappingResult).notTo.beNil();
expect([operation.mappingResult array]).notTo.beEmpty();
RKHuman *human = (RKHuman *)[[operation.mappingResult array] objectAtIndex:0];
expect(human.objectID).to.equal(temporaryHuman.objectID);
expect(human.railsID).to.equal(1);
}
- (void)testShouldNotPersistTemporaryEntityToPersistentStoreOnError
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[mapping addAttributeMappingsFromArray:@[@"name"]];
RKManagedObjectRequestOperation *operation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodPOST path:@"/humans/fail" parameters:nil];
[operation start];
[operation waitUntilFinished];
expect([temporaryHuman isNew]).to.equal(YES);
}
- (void)testThatFailedObjectRequestOperationDoesNotSaveObjectToPersistentStore
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[mapping addAttributeMappingsFromArray:@[@"name"]];
expect([temporaryHuman isNew]).to.equal(YES);
RKManagedObjectRequestOperation *operation = [self.objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodPOST path:@"/humans/fail" parameters:nil];
[operation start];
[operation waitUntilFinished];
expect([temporaryHuman isNew]).to.equal(YES);
}
- (void)testShouldDeleteACoreDataBackedTargetObjectOnSuccessfulDeleteReturning200
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
temporaryHuman.railsID = @1;
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[mapping addAttributeMappingsFromArray:@[@"name"]];
// Save it to ensure the object is persisted before we delete it
[self.objectManager.managedObjectStore.persistentStoreManagedObjectContext save:nil];
RKManagedObjectRequestOperation *operation = [self.objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodDELETE path:nil parameters:nil];
[operation start];
[operation waitUntilFinished];
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"RKHuman"];
NSArray *humans = [_objectManager.managedObjectStore.persistentStoreManagedObjectContext executeFetchRequest:fetchRequest error:&error];
expect(error).to.beNil();
expect(humans).to.haveCountOf(0);
}
- (void)testShouldDeleteACoreDataBackedTargetObjectOnSuccessfulDeleteReturning204
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
temporaryHuman.railsID = @204;
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[mapping addAttributeMappingsFromArray:@[@"name"]];
// Save it to ensure the object is persisted before we delete it
[self.objectManager.managedObjectStore.persistentStoreManagedObjectContext save:nil];
RKManagedObjectRequestOperation *operation = [self.objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodDELETE path:nil parameters:nil];
[operation start];
[operation waitUntilFinished];
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"RKHuman"];
NSArray *humans = [_objectManager.managedObjectStore.persistentStoreManagedObjectContext executeFetchRequest:fetchRequest error:&error];
expect(error).to.beNil();
expect(humans).to.haveCountOf(0);
}
- (void)testCancellationByExactMethodAndPath
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/object_manager/cancel" relativeToURL:self.objectManager.HTTPClient.baseURL]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:self.objectManager.responseDescriptors];
[_objectManager enqueueObjectRequestOperation:operation];
[_objectManager cancelAllObjectRequestOperationsWithMethod:RKRequestMethodGET matchingPathPattern:@"/object_manager/cancel"];
expect([operation isCancelled]).to.equal(YES);
}
- (void)testCancellationByPathMatch
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/object_manager/1234/cancel" relativeToURL:self.objectManager.HTTPClient.baseURL]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:self.objectManager.responseDescriptors];
[_objectManager enqueueObjectRequestOperation:operation];
[_objectManager cancelAllObjectRequestOperationsWithMethod:RKRequestMethodGET matchingPathPattern:@"/object_manager/:objectID/cancel"];
expect([operation isCancelled]).to.equal(YES);
}
- (void)testCancellationFailsForMismatchedMethod
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/object_manager/cancel" relativeToURL:self.objectManager.HTTPClient.baseURL]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:self.objectManager.responseDescriptors];
[_objectManager enqueueObjectRequestOperation:operation];
[_objectManager cancelAllObjectRequestOperationsWithMethod:RKRequestMethodPOST matchingPathPattern:@"/object_manager/cancel"];
expect([operation isCancelled]).to.equal(NO);
}
- (void)testCancellationFailsForMismatchedPath
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/object_manager/cancel" relativeToURL:self.objectManager.HTTPClient.baseURL]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:self.objectManager.responseDescriptors];
[_objectManager enqueueObjectRequestOperation:operation];
[_objectManager cancelAllObjectRequestOperationsWithMethod:RKRequestMethodGET matchingPathPattern:@"/wrong"];
expect([operation isCancelled]).to.equal(NO);
}
- (void)testCancellationByPathMatchForBaseURLWithPath
{
self.objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://localhost:4567/object_manager/"]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:4567/object_manager/1234/cancel"]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:self.objectManager.responseDescriptors];
[_objectManager enqueueObjectRequestOperation:operation];
[_objectManager cancelAllObjectRequestOperationsWithMethod:RKRequestMethodGET matchingPathPattern:@":objectID/cancel"];
expect([operation isCancelled]).to.equal(YES);
}
- (void)testShouldProperlyFireABatchOfOperations
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
temporaryHuman.name = @"My Name";
RKManagedObjectRequestOperation *successfulGETOperation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodGET path:nil parameters:nil];
RKManagedObjectRequestOperation *successfulPOSTOperation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodPOST path:nil parameters:nil];
RKManagedObjectRequestOperation *failedPOSTOperation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodPOST path:@"/humans/fail" parameters:nil];
__block NSUInteger progressCallbackCount = 0;
__block NSUInteger completionBlockOperationCount = 0;
[_objectManager enqueueBatchOfObjectRequestOperations:@[successfulGETOperation, successfulPOSTOperation, failedPOSTOperation] progress:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
progressCallbackCount++;
} completion:^(NSArray *operations) {
completionBlockOperationCount = operations.count;
}];
expect(_objectManager.operationQueue).notTo.beNil();
[_objectManager.operationQueue waitUntilAllOperationsAreFinished];
// Spin the run loop to allow completion blocks to fire after operations have completed
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.02]];
expect(progressCallbackCount).to.equal(3);
expect(completionBlockOperationCount).to.equal(3);
}
- (void)testShouldProperlyFireABatchOfOperationsFromRoute
{
NSManagedObjectContext *managedObjectContext = [[RKTestFactory managedObjectStore] persistentStoreManagedObjectContext];
RKHuman *dan = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
dan.name = @"Dan";
RKHuman *blake = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
blake.name = @"Blake";
RKHuman *jeff = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext withProperties:nil];
jeff.name = @"Jeff";
__block NSUInteger progressCallbackCount = 0;
__block NSUInteger completionBlockOperationCount = 0;
[_objectManager enqueueBatchOfObjectRequestOperationsWithRoute:self.humanPOSTRoute objects:@[dan, blake, jeff] progress:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
progressCallbackCount++;
} completion:^(NSArray *operations) {
completionBlockOperationCount = operations.count;
}];
expect(_objectManager.operationQueue).notTo.beNil();
[_objectManager.operationQueue waitUntilAllOperationsAreFinished];
// Spin the run loop to allow completion blocks to fire after operations have completed
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
expect(progressCallbackCount).to.equal(3);
expect(completionBlockOperationCount).to.equal(3);
}
- (void)testThatObjectParametersAreNotSentDuringGetObject
{
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:nil withProperties:nil];
temporaryHuman.name = @"My Name";
temporaryHuman.railsID = @204;
RKManagedObjectRequestOperation *operation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodGET path:nil parameters:@{@"this": @"that"}];
expect([operation.HTTPRequestOperation.request.URL absoluteString]).to.equal(@"http://127.0.0.1:4567/humans/204?this=that");
}
- (void)testThatObjectParametersAreNotSentDuringDeleteObject
{
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:nil withProperties:nil];
temporaryHuman.name = @"My Name";
temporaryHuman.railsID = @204;
RKManagedObjectRequestOperation *operation = [_objectManager appropriateObjectRequestOperationWithObject:temporaryHuman method:RKRequestMethodDELETE path:nil parameters:@{@"this": @"that"}];
expect([operation.HTTPRequestOperation.request.URL absoluteString]).to.equal(@"http://127.0.0.1:4567/humans/204?this=that");
}
- (void)testInitializationOfObjectRequestOperationProducesCorrectURLRequest
{
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:nil withProperties:nil];
NSURLRequest *request = [_objectManager requestWithObject:temporaryHuman method:RKRequestMethodPATCH path:@"/the/path" parameters:@{@"key": @"value"}];
expect([request.URL absoluteString]).to.equal(@"http://127.0.0.1:4567/the/path");
expect(request.HTTPMethod).to.equal(@"PATCH");
expect(request.HTTPBody).notTo.beNil();
NSString *string = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
expect(string).to.equal(@"key=value");
}
- (void)testAFHTTPClientCanModifyRequestsBuiltByObjectManager
{
RKTestAFHTTPClient *testClient = [[RKTestAFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://test.com"]];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:testClient];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:nil withProperties:nil];
NSURLRequest *request = [manager requestWithObject:temporaryHuman method:RKRequestMethodPATCH path:@"/the/path" parameters:@{@"key": @"value"}];
expect([request.URL absoluteString]).to.equal(@"http://test.com/the/path");
expect(request.HTTPMethod).to.equal(@"PATCH");
expect([request allHTTPHeaderFields][@"test"]).to.equal(@"value");
expect([request allHTTPHeaderFields][@"Accept"]).to.equal(@"text/html");
}
- (void)testDefaultAcceptHeaderOfObjectManagerOverridesValueOfHTTPClient
{
RKTestAFHTTPClient *testClient = [[RKTestAFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://test.com"]];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:testClient];
[manager setAcceptHeaderWithMIMEType:@"application/json"];
RKHuman *temporaryHuman = [RKTestFactory insertManagedObjectForEntityForName:@"RKHuman" inManagedObjectContext:nil withProperties:nil];
NSURLRequest *request = [manager requestWithObject:temporaryHuman method:RKRequestMethodPATCH path:@"/the/path" parameters:@{@"key": @"value"}];
expect([request.URL absoluteString]).to.equal(@"http://test.com/the/path");
expect(request.HTTPMethod).to.equal(@"PATCH");
expect([request allHTTPHeaderFields][@"test"]).to.equal(@"value");
expect([request allHTTPHeaderFields][@"Accept"]).to.equal(@"application/json");
}
- (void)testRegistrationOfHTTPRequestOperationClass
{
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
[manager setHTTPOperationClass:[RKTestHTTPRequestOperation class]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/test" relativeToURL:manager.baseURL]];
RKObjectRequestOperation *operation = [manager objectRequestOperationWithRequest:request success:nil failure:nil];
expect(operation.HTTPRequestOperation).to.beKindOf([RKTestHTTPRequestOperation class]);
}
- (void)testSettingNilHTTPRequestOperationClassRestoresDefaultHTTPOperationClass
{
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
[manager setHTTPOperationClass:[RKTestHTTPRequestOperation class]];
[manager setHTTPOperationClass:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/test" relativeToURL:manager.baseURL]];
RKObjectRequestOperation *operation = [manager objectRequestOperationWithRequest:request success:nil failure:nil];
expect(operation.HTTPRequestOperation).to.beKindOf([RKHTTPRequestOperation class]);
}
- (void)testThatManagedObjectRequestOperationsDefaultToSavingToPersistentStore
{
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/whatever" relativeToURL:manager.baseURL]];
RKManagedObjectRequestOperation *operation = [manager managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectContext success:nil failure:nil];
expect(operation.savesToPersistentStore).to.equal(YES);
}
- (void)testShouldLoadAHuman
{
__block RKObjectRequestOperation *requestOperation = nil;
[self.objectManager getObjectsAtPath:@"/JSON/humans/1.json" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
requestOperation = operation;
} failure:nil];
dispatch_async(dispatch_get_main_queue(), ^{
expect(requestOperation.error).to.beNil();
expect([requestOperation.mappingResult array]).notTo.beEmpty();
RKHuman *blake = (RKHuman *)[requestOperation.mappingResult array][0];
expect(blake.name).to.equal(@"Blake Watters");
});
}
- (void)testShouldLoadAllHumans
{
__block RKObjectRequestOperation *requestOperation = nil;
[_objectManager getObjectsAtPath:@"/JSON/humans/all.json" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
requestOperation = operation;
} failure:nil];
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *humans = [requestOperation.mappingResult array];
expect(humans).to.haveCountOf(2);
expect(humans[0]).to.beInstanceOf([RKHuman class]);
});
}
//- (void)testShouldHandleConnectionFailures
//{
// NSString *localBaseURL = [NSString stringWithFormat:@"http://127.0.0.1:3001"];
// RKObjectManager *modelManager = [RKObjectManager managerWithBaseURLString:localBaseURL];
// modelManager.client.requestQueue.suspended = NO;
// RKTestResponseLoader *loader = [RKTestResponseLoader responseLoader];
// [modelManager loadObjectsAtResourcePath:@"/JSON/humans/1" delegate:loader];
// [loader waitForResponse];
// assertThatBool(loader.wasSuccessful, is(equalToBool(NO)));
//}
//
//- (void)testShouldPOSTAnObject
//{
// RKObjectManager *manager = [RKTestFactory objectManager];
// [manager.router.routeSet addRoute:[RKRoute routeWithClass:[RKObjectMapperTestModel class] pathPattern:@"/humans" method:RKRequestMethodPOST]];
//
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// mapping.rootKeyPath = @"human";
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [manager.mappingProvider setMapping:mapping forKeyPath:@"human"];
// [manager.mappingProvider setSerializationMapping:mapping forClass:[RKObjectMapperTestModel class]];
//
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
//
// RKTestResponseLoader *loader = [RKTestResponseLoader responseLoader];
// [manager postObject:human delegate:loader];
// [loader waitForResponse];
//
// // NOTE: The /humans endpoint returns a canned response, we are testing the plumbing
// // of the object manager here.
// assertThat(human.name, is(equalTo(@"My Name")));
//}
//
//- (void)testShouldNotSetAContentBodyOnAGET
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[RKObjectMapperTestModel class] pathPattern:@"/humans/1" method:RKRequestMethodAny]];
//
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [objectManager.mappingProvider registerMapping:mapping withRootKeyPath:@"human"];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// __block RKObjectLoader *objectLoader = nil;
// [objectManager getObject:human usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;
// objectLoader = loader;
// }];
// [responseLoader waitForResponse];
// RKLogCritical(@"%@", [objectLoader.URLRequest allHTTPHeaderFields]);
// assertThat([objectLoader.URLRequest valueForHTTPHeaderField:@"Content-Length"], is(equalTo(@"0")));
//}
//
//- (void)testShouldNotSetAContentBodyOnADELETE
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[RKObjectMapperTestModel class] pathPattern:@"/humans/1" method:RKRequestMethodAny]];
//
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [objectManager.mappingProvider registerMapping:mapping withRootKeyPath:@"human"];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// __block RKObjectLoader *objectLoader = nil;
// [objectManager deleteObject:human usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;
// objectLoader = loader;
// }];
// [responseLoader waitForResponse];
// RKLogCritical(@"%@", [objectLoader.URLRequest allHTTPHeaderFields]);
// assertThat([objectLoader.URLRequest valueForHTTPHeaderField:@"Content-Length"], is(equalTo(@"0")));
//}
//
//#pragma mark - Block Helpers
//
//- (void)testShouldLetYouLoadObjectsWithABlock
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [objectManager.mappingProvider registerMapping:mapping withRootKeyPath:@"human"];
//
// RKTestResponseLoader *responseLoader = [[RKTestResponseLoader responseLoader] retain];
// [objectManager loadObjectsAtResourcePath:@"/JSON/humans/1.json" usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;
// loader.objectMapping = mapping;
// }];
// [responseLoader waitForResponse];
// assertThatBool(responseLoader.wasSuccessful, is(equalToBool(YES)));
// assertThat(responseLoader.objects, hasCountOf(1));
//}
//
//- (void)testShouldAllowYouToOverrideTheRoutedResourcePath
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[RKObjectMapperTestModel class] pathPattern:@"/humans/2" method:RKRequestMethodAny]];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [objectManager.mappingProvider registerMapping:mapping withRootKeyPath:@"human"];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// [objectManager deleteObject:human usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;
// loader.resourcePath = @"/humans/1";
// }];
// responseLoader.timeout = 50;
// [responseLoader waitForResponse];
// assertThat(responseLoader.response.request.resourcePath, is(equalTo(@"/humans/1")));
//}
//
//- (void)testShouldAllowYouToUseObjectHelpersWithoutRouting
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
// [objectManager.mappingProvider registerMapping:mapping withRootKeyPath:@"human"];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// [objectManager sendObject:human toResourcePath:@"/humans/1" usingBlock:^(RKObjectLoader *loader) {
// loader.method = RKRequestMethodDELETE;
// loader.delegate = responseLoader;
// loader.resourcePath = @"/humans/1";
// }];
// [responseLoader waitForResponse];
// assertThat(responseLoader.response.request.resourcePath, is(equalTo(@"/humans/1")));
//}
//
//- (void)testShouldAllowYouToSkipTheMappingProvider
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// mapping.rootKeyPath = @"human";
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// [objectManager sendObject:human toResourcePath:@"/humans/1" usingBlock:^(RKObjectLoader *loader) {
// loader.method = RKRequestMethodDELETE;
// loader.delegate = responseLoader;
// loader.objectMapping = mapping;
// }];
// [responseLoader waitForResponse];
// assertThatBool(responseLoader.wasSuccessful, is(equalToBool(YES)));
// assertThat(responseLoader.response.request.resourcePath, is(equalTo(@"/humans/1")));
//}
//
//- (void)testShouldLetYouOverloadTheParamsOnAnObjectLoaderRequest
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// mapping.rootKeyPath = @"human";
// [mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
//
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
// RKObjectMapperTestModel *human = [[RKObjectMapperTestModel new] autorelease];
// human.name = @"Blake Watters";
// human.age = [NSNumber numberWithInt:28];
// NSDictionary *myParams = [NSDictionary dictionaryWithObject:@"bar" forKey:@"foo"];
// __block RKObjectLoader *objectLoader = nil;
// [objectManager sendObject:human toResourcePath:@"/humans/1" usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;
// loader.method = RKRequestMethodPOST;
// loader.objectMapping = mapping;
// loader.params = myParams;
// objectLoader = loader;
// }];
// [responseLoader waitForResponse];
// assertThat(objectLoader.params, is(equalTo(myParams)));
//}
//
//- (void)testInitializationOfObjectLoaderViaManagerConfiguresSerializationMIMEType
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// objectManager.serializationMIMEType = RKMIMETypeJSON;
// RKObjectLoader *loader = [objectManager loaderWithResourcePath:@"/test"];
// assertThat(loader.serializationMIMEType, isNot(nilValue()));
// assertThat(loader.serializationMIMEType, is(equalTo(RKMIMETypeJSON)));
//}
//
//- (void)testInitializationOfRoutedPathViaSendObjectMethodUsingBlock
//{
// RKObjectManager *objectManager = [RKTestFactory objectManager];
// RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
// mapping.rootKeyPath = @"human";
// [objectManager.mappingProvider registerObjectMapping:mapping withRootKeyPath:@"human"];
// [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[RKObjectMapperTestModel class] pathPattern:@"/human/1" method:RKRequestMethodAny]];
// objectManager.serializationMIMEType = RKMIMETypeJSON;
// RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
//
// RKObjectMapperTestModel *object = [RKObjectMapperTestModel new];
// [objectManager putObject:object usingBlock:^(RKObjectLoader *loader) {
// loader.delegate = responseLoader;sss
// }];
// [responseLoader waitForResponse];
//}
//
@end