<commit_before>//
//  APEReactiveNetworkingTests.swift
//  APEReactiveNetworkingTests
//
//  Created by <NAME> on 07/06/16.
//  Copyright © 2016 Apegroup. All rights reserved.
//

import XCTest
import ReactiveSwift
@testable import APEReactiveNetworking

struct GoogleEndpoint: Endpoint {
    let absoluteUrl = "http://www.google.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [.ok]
}

struct InvalidResponseCodeEndpoint: Endpoint {
    let absoluteUrl = "http://www.google.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [.badRequest, .internalServerError]
}


struct InvalidEndpoint: Endpoint {
    let absoluteUrl = "http://www._thisisaninvalidURL_asdfasoiddlkdk.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [Http.StatusCode.badRequest]
}

class APEReactiveNetworkingTests: XCTestCase {
    
    /**
     Tests the successful case of 200 OK
     */
    func testSuccessfulGET() {
        let maxSecondsPermitted: TimeInterval = 5
        let endpoint = GoogleEndpoint()
        let expect = expectation(description: "Expected status \(endpoint.acceptedResponseCodes) within \(maxSecondsPermitted) seconds")
        
        
        let request = ApeRequestBuilder(endpoint: endpoint).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request)
            .on(completed: {
                expect.fulfill()
            })
        
        producer.start()
        waitForExpectations(timeout: maxSecondsPermitted, handler: nil)
    }
    
    /**
     Tests the scenario of an invalid response code
     */
    func testInvalidResponseCodeGET() {
        let maxSecondsPermitted: TimeInterval = 5
        let endpoint = InvalidResponseCodeEndpoint()
        let expect = expectation(description: "Expected status \(endpoint.acceptedResponseCodes) within \(maxSecondsPermitted) seconds")
        
        let request = ApeRequestBuilder(endpoint: endpoint).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request, maxRetries: 0)
        producer.startWithFailed { (operationError: Network.OperationError) in
            guard case let .unexpectedResponseCode(httpCode, _) = operationError,
                !endpoint.acceptedResponseCodes.contains(httpCode) else {
                    return
            }
            expect.fulfill()
        }
    
        waitForExpectations(timeout: maxSecondsPermitted, handler: nil)
    }
    
    /**
     Tests the 'abortAfter' functionality, ensuring that the operation is aborted immediately and that a TimedOut error is sent.
     */
    func testAbortAfter() {
        let expect = expectation(description: "Expected timeout")
        
        let request = ApeRequestBuilder(endpoint: GoogleEndpoint()).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request, abortAfter: 0.0)
            .on(failed: { (error: Network.OperationError) in
                XCTAssertEqual(error._code, Network.OperationError.timedOut._code)
                expect.fulfill()
            })
        
        producer.start()
        waitForExpectations(timeout: 1, handler: nil)
    }
    
    /**
     Tests the 'exponential backoff retry' functionality.
     
     This is tested by connecting to an invalid URL and ensuring that:
       - a request failure occurs
       - a minimum required amount of time (based on the number of retries and the exponential backoff time units added between each retry) has elapsed before the failure occurs.
     */
    func testExponentialBackoff() {
        let expect = expectation(description: "Minimum required time has not elapsed")
        
        //Number of times to retry the request operation
        let numberOfRetries = 4
        
        //Calculate the minimum amount of seconds that the network request will take (due to exponential backoff)
        var minimumRequiredTime: TimeInterval = 0
        let exponentialGenerator = ExponentialSequence().makeIterator()
        (0..<numberOfRetries).forEach { _ in
            minimumRequiredTime += exponentialGenerator.next()!
        }
        
        //Set a maximum time permitted before failing the test (give each request 2 seconds to complete)
        let secondsPerRequest = 2
        let marginSeconds = TimeInterval(numberOfRetries * secondsPerRequest)
        let maximumTimePermitted = minimumRequiredTime + marginSeconds
        
        var startTime: TimeInterval?
        var endTime: TimeInterval?
        let request = ApeRequestBuilder(endpoint: InvalidEndpoint()).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request, abortAfter: maximumTimePermitted, maxRetries: numberOfRetries)
            .on(started: {
                    //Capture the start time
                    startTime = Date().timeIntervalSince1970
                    
                }, failed: { (error: Network.OperationError) in
                    //Capture the end time
                    endTime = Date().timeIntervalSince1970
                    
                    //Calculate the total time elapsed
                    let timeElapsed = endTime! - startTime!
                    
                    //Assert that the total time elapsed is larger than the minimum required time
                    XCTAssert(timeElapsed > minimumRequiredTime)
                    
                    //Assert that a request failure has occurred
                    let expectedError = NSError(domain: "URLErrorDomain", code: -1003, userInfo: nil)
                    XCTAssertEqual(error._code, Network.OperationError.requestFailure(error: expectedError)._code)
                    
                    expect.fulfill()
            })
        
        producer.start()
        
        waitForExpectations(timeout: maximumTimePermitted, handler: nil)
    }
}<commit_msg>Fixed broken test and removed legacy test<commit_after>//
//  APEReactiveNetworkingTests.swift
//  APEReactiveNetworkingTests
//
//  Created by <NAME> on 07/06/16.
//  Copyright © 2016 Apegroup. All rights reserved.
//

import XCTest
import ReactiveSwift
@testable import APEReactiveNetworking

struct GoogleEndpoint: Endpoint {
    let absoluteUrl = "http://www.google.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [.ok]
}

struct InvalidResponseCodeEndpoint: Endpoint {
    let absoluteUrl = "http://www.google.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [.badRequest, .internalServerError]
}


struct InvalidEndpoint: Endpoint {
    let absoluteUrl = "http://www._thisisaninvalidURL_asdfasoiddlkdk.com"
    let httpMethod: Http.Method = .get
    let acceptedResponseCodes: [Http.StatusCode] = [Http.StatusCode.badRequest]
}

class APEReactiveNetworkingTests: XCTestCase {
    
    /**
     Tests the successful case of 200 OK
     */
    func testSuccessfulGET() {
        let maxSecondsPermitted: TimeInterval = 5
        let endpoint = GoogleEndpoint()
        let expect = expectation(description: "Expected status \(endpoint.acceptedResponseCodes) within \(maxSecondsPermitted) seconds")
        
        
        let request = ApeRequestBuilder(endpoint: endpoint).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request)
            .on(completed: {
                expect.fulfill()
            })
        
        producer.start()
        waitForExpectations(timeout: maxSecondsPermitted, handler: nil)
    }
    
    /**
     Tests the scenario of an invalid response code
     */
    func testInvalidResponseCodeGET() {
        let maxSecondsPermitted: TimeInterval = 5
        let endpoint = InvalidResponseCodeEndpoint()
        let expect = expectation(description: "Expected status \(endpoint.acceptedResponseCodes) within \(maxSecondsPermitted) seconds")
        
        let request = ApeRequestBuilder(endpoint: endpoint).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request, abortAfter: 10)
        producer.startWithFailed { (operationError: Network.OperationError) in
            guard case let .unexpectedResponseCode(httpCode, _) = operationError,
                !endpoint.acceptedResponseCodes.contains(httpCode) else {
                    return
            }
            expect.fulfill()
        }
    
        waitForExpectations(timeout: maxSecondsPermitted, handler: nil)
    }
    
    /**
     Tests the 'abortAfter' functionality, ensuring that the operation is aborted immediately and that a TimedOut error is sent.
     */
    func testAbortAfter() {
        let expect = expectation(description: "Expected timeout")
        
        let request = ApeRequestBuilder(endpoint: GoogleEndpoint()).build()
        let producer: SignalProducer<Http.ResponseHeaders, Network.OperationError> = Network().send(request, abortAfter: 0.0)
            .on(failed: { (error: Network.OperationError) in
                XCTAssertEqual(error._code, Network.OperationError.timedOut._code)
                expect.fulfill()
            })
        
        producer.start()
        waitForExpectations(timeout: 1, handler: nil)
    }
}
{'fraction_non_alphanumeric': 0.08349226531044712, 'fraction_numerical': 0.005933460478915025, 'mean_word_length': 2.5220149253731345, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7485191', 'n_tokens_mistral': 2424, 'n_tokens_neox': 2348, 'n_words': 638}