diff --git a/Sources/Experiments/ExPlatService.swift b/Sources/Experiments/ExPlatService.swift index 6da31b05..03b4ebb2 100644 --- a/Sources/Experiments/ExPlatService.swift +++ b/Sources/Experiments/ExPlatService.swift @@ -24,12 +24,12 @@ public class ExPlatService { return "https://public-api.wordpress.com/wpcom/v2/experiments/0.1.0/assignments/\(platform)" } - init(configuration: ExPlatConfiguration) { + init(configuration: ExPlatConfiguration, urlSession: URLSession = URLSession(configuration: .ephemeral)) { self.platform = configuration.platform self.oAuthToken = configuration.oAuthToken self.userAgent = configuration.userAgent self.anonId = configuration.anonId - self.urlSession = URLSession(configuration: .ephemeral) + self.urlSession = urlSession } func getAssignments(completion: @escaping (Assignments?) -> Void) { @@ -70,7 +70,7 @@ public class ExPlatService { request.setValue(userAgent, forHTTPHeaderField: "User-Agent") } - let task = URLSession.shared.dataTask(with: request) { data, _, error in + let task = urlSession.dataTask(with: request) { data, _, error in guard let data, error == nil else { completion(nil) return diff --git a/Tests/Tests/ABTesting/ExPlatServiceTests.swift b/Tests/Tests/ABTesting/ExPlatServiceTests.swift index f42c3c61..cb30bec7 100644 --- a/Tests/Tests/ABTesting/ExPlatServiceTests.swift +++ b/Tests/Tests/ABTesting/ExPlatServiceTests.swift @@ -20,6 +20,7 @@ class ExPlatServiceTests: XCTestCase { super.tearDown() HTTPStubs.removeAllStubs() + SpyURLProtocol.requestHandled = false } // Return TTL and variations @@ -71,6 +72,25 @@ class ExPlatServiceTests: XCTestCase { wait(for: [expectation], timeout: 2.0) } + // Verify that the service uses the URLSession it was configured with, not URLSession.shared + // + func testUsesConfiguredURLSession() { + let expectation = XCTestExpectation(description: "Request handled by configured session") + + let sessionConfig = URLSessionConfiguration.ephemeral + sessionConfig.protocolClasses = [SpyURLProtocol.self] + let spySession = URLSession(configuration: sessionConfig) + let service = ExPlatService(configuration: exPlatTestConfiguration, urlSession: spySession) + service.experimentNames = ["experiment1"] + + service.getAssignments { _ in + expectation.fulfill() + } + + wait(for: [expectation], timeout: 2.0) + XCTAssertTrue(SpyURLProtocol.requestHandled, "ExPlatService must use its configured urlSession, not URLSession.shared") + } + // When no experiments names are given, just return nil assignments // func testEmptyExperiments() { @@ -109,3 +129,32 @@ class ExPlatServiceTests: XCTestCase { } } } + +// A URLProtocol that records whether it was asked to handle a request. +// Used to verify that ExPlatService sends requests through its configured URLSession. +private class SpyURLProtocol: URLProtocol { + private static let lock = NSLock() + private static var _requestHandled = false + static var requestHandled: Bool { + get { lock.withLock { _requestHandled } } + set { lock.withLock { _requestHandled = newValue } } + } + + override class func canInit(with request: URLRequest) -> Bool { + requestHandled = true + return true + } + + override class func canonicalRequest(for request: URLRequest) -> URLRequest { + return request + } + + override func startLoading() { + let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! + client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) + client?.urlProtocol(self, didLoad: Data()) + client?.urlProtocolDidFinishLoading(self) + } + + override func stopLoading() {} +}