// // RKTestHelpers.m // RestKit // // Created by Blake Watters on 10/2/12. // Copyright (c) 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 "RKTestHelpers.h" #import "RKObjectManager.h" #import "RKRoute.h" #import "RKPathUtilities.h" #import "RKLog.h" #import "SOCKit.h" @interface SOCPattern (RKTestHelpers) @property (nonatomic, strong, readonly) NSArray* parameters; @end @implementation SOCPattern (RKTestHelpers) - (NSArray *)parameters { return _parameters; } @end @implementation RKTestHelpers + (RKRoute *)stubRouteForClass:(Class)objectClass method:(RKRequestMethod)method withPathPattern:(NSString *)pathPattern onObjectManager:(RKObjectManager *)nilOrObjectManager { RKObjectManager *objectManager = nilOrObjectManager ?: [RKObjectManager sharedManager]; RKRoute *route = [objectManager.router.routeSet routeForClass:objectClass method:method]; NSAssert(route, @"Expected to retrieve a route, but got nil"); [objectManager.router.routeSet removeRoute:route]; RKRoute *stubbedRoute = [RKRoute routeWithClass:objectClass pathPattern:pathPattern method:method]; [objectManager.router.routeSet addRoute:stubbedRoute]; return stubbedRoute; } + (RKRoute *)stubRouteNamed:(NSString *)routeName withPathPattern:(NSString *)pathPattern onObjectManager:(RKObjectManager *)nilOrObjectManager { RKObjectManager *objectManager = nilOrObjectManager ?: [RKObjectManager sharedManager]; RKRoute *route = [[RKObjectManager sharedManager].router.routeSet routeForName:routeName]; NSAssert(route, @"Expected to retrieve a route, but got nil"); [[RKObjectManager sharedManager].router.routeSet removeRoute:route]; RKRoute *stubbedRoute = [RKRoute routeWithName:routeName pathPattern:pathPattern method:route.method]; [[RKObjectManager sharedManager].router.routeSet addRoute:stubbedRoute]; [self copyFetchRequestBlocksMatchingPathPattern:route.pathPattern toBlocksMatchingRelativeString:pathPattern onObjectManager:objectManager]; return stubbedRoute; } + (RKRoute *)stubRouteForRelationship:(NSString *)relationshipName ofClass:(Class)objectClass pathPattern:(NSString *)pathPattern onObjectManager:(RKObjectManager *)nilOrObjectManager { RKObjectManager *objectManager = nilOrObjectManager ?: [RKObjectManager sharedManager]; RKRoute *route = [objectManager.router.routeSet routeForRelationship:relationshipName ofClass:objectClass method:RKRequestMethodGET]; NSAssert(route, @"Expected to retrieve a route, but got nil"); [objectManager.router.routeSet removeRoute:route]; RKRoute *stubbedRoute = [RKRoute routeWithRelationshipName:relationshipName objectClass:objectClass pathPattern:pathPattern method:RKRequestMethodGET]; [objectManager.router.routeSet addRoute:stubbedRoute]; [self copyFetchRequestBlocksMatchingPathPattern:route.pathPattern toBlocksMatchingRelativeString:pathPattern onObjectManager:objectManager]; return stubbedRoute; } + (void)copyFetchRequestBlocksMatchingPathPattern:(NSString *)pathPattern toBlocksMatchingRelativeString:(NSString *)relativeString onObjectManager:(RKObjectManager *)nilOrObjectManager { RKObjectManager *objectManager = nilOrObjectManager ?: [RKObjectManager sharedManager]; // Extract the dynamic portions of the path pattern to construct a set of parameters SOCPattern *pattern = [SOCPattern patternWithString:pathPattern]; NSArray *parameterNames = [pattern.parameters valueForKey:@"string"]; NSMutableDictionary *stubbedParameters = [NSMutableDictionary dictionaryWithCapacity:[parameterNames count]]; for (NSString *parameter in parameterNames) { [stubbedParameters setValue:@"value" forKey:parameter]; } NSString *stubbedPathPattern = [pattern stringFromObject:stubbedParameters]; NSURL *URL = [NSURL URLWithString:stubbedPathPattern relativeToURL:objectManager.HTTPClient.baseURL]; NSAssert(URL, @"Failed to build URL from path pattern '%@' relative to base URL '%@'", pathPattern, objectManager.HTTPClient.baseURL); for (RKFetchRequestBlock block in objectManager.fetchRequestBlocks) { NSFetchRequest *fetchRequest = block(URL); if (fetchRequest) { // Add a new block that matches our stubbed path [[RKObjectManager sharedManager] addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) { // TODO: Note that relativeString does not work because NSURLRequest drops the relative parent of the URL // if ([[URL relativeString] isEqualToString:relativeString]) { if ([[URL path] isEqualToString:relativeString]) { return fetchRequest; } return nil; }]; break; } } } + (void)disableCaching { NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; [NSURLCache setSharedURLCache:sharedCache]; } + (NSCachedURLResponse *)cacheResponseForRequest:(NSURLRequest *)request withResponseData:(NSData *)responseData { NSParameterAssert(request); NSParameterAssert(responseData); NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[request URL] statusCode:200 HTTPVersion:@"1.1" headerFields:nil]; NSAssert(response, @"Failed to build cached response"); NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:responseData]; [[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:request]; // Verify that we can get the cached response back NSCachedURLResponse *storedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request]; NSAssert(storedResponse, @"Expected to retrieve cached response for request '%@', instead got nil.", request); return cachedResponse; } + (NSCachedURLResponse *)cacheResponseForURL:(NSURL *)URL HTTPMethod:(NSString *)HTTPMethod headers:(NSDictionary *)requestHeaders withData:(NSData *)responseData { NSParameterAssert(URL); NSParameterAssert(HTTPMethod); NSParameterAssert(responseData); NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; request.HTTPMethod = HTTPMethod; [request setAllHTTPHeaderFields:requestHeaders]; return [self cacheResponseForRequest:request withResponseData:responseData]; } @end