//
//  CRSessionControllerReachabilityTests.m
//  Courier
//
//  Created by absmith on 1/27/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 <OCMock/OCMock.h>
#import "CRTestCase.h"

#import "CRSessionController.h"

@interface CRSessionController (Private)

@property (nonatomic, strong) Reachability *reachabilityObject;

@end

@interface CRSessionControllerReachabilityTests : CRTestCase

@property (nonatomic, strong) CRSessionController *sessionController;

@end

@implementation CRSessionControllerReachabilityTests

- (void)setUp {
    [super setUp];
    _sessionController = [CRSessionController sessionControllerWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
}

- (void)tearDown {
    [super tearDown];
}

- (void)testIsNotReachable {
    id mockReachability = OCMPartialMock(_sessionController.reachabilityObject);
    OCMStub([mockReachability isReachable]).andReturn(NO);
    _sessionController.reachabilityObject = mockReachability;
    XCTAssertEqual(_sessionController.isInternetReachable,
                   NO,
                   @"CRSessionController report not reachable");
}

- (void)testIsReachable {
    id mockReachability = OCMPartialMock(_sessionController.reachabilityObject);
    OCMStub([mockReachability isReachable]).andReturn(YES);
    _sessionController.reachabilityObject = mockReachability;
    XCTAssertEqual(_sessionController.isInternetReachable,
                   YES,
                   @"CRSessionController report not reachable");
}

- (void)testReachabilityChangedReachable {
    __block BOOL blockRan = NO;
    [_sessionController setReachabilityStatusChangeBlock:^(NetworkStatus status) {
        blockRan = YES;
    }];
    
    _sessionController.reachabilityObject.reachableBlock(nil);
    
    XCTAssertTrue(blockRan);
}

- (void)testReachabilityChangedUnreachable {
    __block BOOL blockRan = NO;
    [_sessionController setReachabilityStatusChangeBlock:^(NetworkStatus status) {
        blockRan = YES;
    }];
    
    _sessionController.reachabilityObject.unreachableBlock(nil);
    
    XCTAssertTrue(blockRan);
}

@end
