| // |
| // CRSessionControllerDelegateTests.m |
| // Courier |
| // |
| // Created by absmith on 1/13/15. |
| // Copyright (c) 2014 Andrew B. Smith ( http://github.com/drewsmits ). All rights reserved. |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a copy |
| // of this software and associated documentation files (the "Software"), to deal |
| // in the Software without restriction, including without limitation the rights |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
| // of the Software, and to permit persons to whom the Software is furnished to do so, |
| // subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included |
| // in all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| // |
| // |
| |
| #import <UIKit/UIKit.h> |
| #import <XCTest/XCTest.h> |
| #import "CRTestCase.h" |
| |
| #import "CRSessionController.h" |
| #import "CRAsyncTestHelpers.h" |
| |
| #import <OHHTTPStubs/OHHTTPStubs.h> |
| #import <OCMock/OCMock.h> |
| |
| static NSString * const kTestRedirectURL = @"http://www.redirect.com"; |
| |
| @interface CRSessionController (Private) |
| |
| @property (nonatomic, readonly) NSOperationQueue *serialQueue; |
| |
| - (id <NSURLSessionTaskDelegate>)NSURLSessionTaskDelegateForTask:(NSURLSessionTask *)task; |
| |
| - (void)addTask:(NSURLSessionTask *)task |
| withToken:(NSString *)token |
| toGroup:(NSString *)group; |
| |
| - (void)removeTaskWithToken:(NSString *)token; |
| |
| @end |
| |
| @interface CRSessionControllerDelegateTests : CRTestCase |
| @property (nonatomic, strong) CRSessionController *sessionController; |
| @end |
| |
| @implementation CRSessionControllerDelegateTests |
| |
| - (void)setUp |
| { |
| [super setUp]; |
| |
| _sessionController = [CRSessionController sessionControllerWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; |
| |
| [OHHTTPStubs removeAllStubs]; |
| |
| [[NSURLSessionConfiguration ephemeralSessionConfiguration].URLCache removeAllCachedResponses]; |
| } |
| |
| - (void)tearDown |
| { |
| [OHHTTPStubs removeAllStubs]; |
| [super tearDown]; |
| } |
| |
| - (void)testAddDelegate |
| { |
| NSURLSessionDataTask *task = OCMClassMock([NSURLSessionDataTask class]); |
| id mockDelegate = OCMProtocolMock(@protocol(NSURLSessionTaskDelegate)); |
| [_sessionController addNSURLSessionTaskDelegate:mockDelegate |
| forTask:task]; |
| |
| id shouldBeDelegate = [_sessionController NSURLSessionTaskDelegateForTask:task]; |
| |
| XCTAssertEqualObjects(shouldBeDelegate, |
| mockDelegate, |
| @"Session controller should return the correct delegate"); |
| } |
| |
| - (void)testRemoveDelegate |
| { |
| NSURLSessionDataTask *task = OCMClassMock([NSURLSessionDataTask class]); |
| id mockDelegate = OCMProtocolMock(@protocol(NSURLSessionTaskDelegate)); |
| [_sessionController addNSURLSessionTaskDelegate:mockDelegate |
| forTask:task]; |
| |
| [_sessionController removeNSURLSessionTaskDelegate:mockDelegate]; |
| id delegate = [_sessionController NSURLSessionTaskDelegateForTask:task]; |
| |
| XCTAssertNil(delegate); |
| } |
| |
| - (void)testRemoveTaskWithDelegate |
| { |
| // Add task first |
| NSURLSessionTask *task = [NSURLSessionTask new]; |
| [_sessionController addTask:task |
| withToken:@"blah" |
| toGroup:@"blah"]; |
| |
| id mockDelegate = OCMProtocolMock(@protocol(NSURLSessionTaskDelegate)); |
| [_sessionController addNSURLSessionTaskDelegate:mockDelegate |
| forTask:task]; |
| |
| [_sessionController removeTaskWithToken:@"blah"]; |
| [_sessionController.serialQueue waitUntilAllOperationsAreFinished]; |
| id delegate = [_sessionController NSURLSessionTaskDelegateForTask:task]; |
| |
| XCTAssertNil(delegate); |
| } |
| |
| - (void)testRedirectResponseDelegate |
| { |
| // |
| // Stub redirect responses |
| // |
| [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { |
| return [request.URL.absoluteString isEqualToString:kTestRedirectURL]; |
| } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { |
| return [OHHTTPStubsResponse responseWithData:[@"dummyData" dataUsingEncoding:NSUTF8StringEncoding] |
| statusCode:301 |
| headers:@{@"Location" : @"http://www.nest.com"}]; |
| }]; |
| |
| XCTestExpectation *expectation = [self expectationWithDescription:@"taskFinished"]; |
| |
| NSURLRequest *redirectRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:kTestRedirectURL]]; |
| NSURLSessionDataTask *task = [_sessionController dataTaskForRequest:redirectRequest |
| completionHandler:^(NSData *data, |
| NSURLResponse *response, |
| BOOL cachedResponse, |
| NSError *error) { |
| [expectation fulfill]; |
| }]; |
| |
| // |
| // Add delegate and expect the redirect is invoked |
| // |
| id mockDelegate = OCMProtocolMock(@protocol(NSURLSessionTaskDelegate)); |
| |
| // forward redirect to self. This lets the redirect complete. |
| OCMStub([mockDelegate URLSession:OCMOCK_ANY |
| task:OCMOCK_ANY |
| willPerformHTTPRedirection:OCMOCK_ANY |
| newRequest:OCMOCK_ANY |
| completionHandler:OCMOCK_ANY]).andCall(self, |
| @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)); |
| |
| // forward auth challenge to self. This lets the redirect complete. |
| OCMStub([mockDelegate URLSession:OCMOCK_ANY |
| task:OCMOCK_ANY |
| didReceiveChallenge:OCMOCK_ANY |
| completionHandler:OCMOCK_ANY]).andCall(self, |
| @selector(URLSession:task:didReceiveChallenge:completionHandler:)); |
| |
| [_sessionController addNSURLSessionTaskDelegate:mockDelegate |
| forTask:task]; |
| [task resume]; |
| |
| [self waitForExpectationsWithTimeout:1.0 |
| handler:nil]; |
| |
| // |
| // Verify that the delegate gets called. |
| // |
| OCMVerify([mockDelegate URLSession:OCMOCK_ANY |
| task:OCMOCK_ANY |
| willPerformHTTPRedirection:OCMOCK_ANY |
| newRequest:OCMOCK_ANY |
| completionHandler:OCMOCK_ANY]); |
| } |
| |
| - (void)URLSession:(NSURLSession *)session |
| task:(NSURLSessionTask *)task |
| willPerformHTTPRedirection:(NSHTTPURLResponse *)response |
| newRequest:(NSURLRequest *)request |
| completionHandler:(void (^)(NSURLRequest *))completionHandler |
| { |
| if (completionHandler) completionHandler(request); |
| } |
| |
| - (void)URLSession:(NSURLSession *)session |
| task:(NSURLSessionTask *)task |
| didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge |
| completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler |
| { |
| if (completionHandler) { |
| completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); |
| } |
| |
| } |
| |
| @end |