Pārlūkot izejas kodu

Added tests for cached response handler per request and session behaviors

Christian Noon 6 gadi atpakaļ
vecāks
revīzija
027f16e32d

+ 8 - 0
Alamofire.xcodeproj/project.pbxproj

@@ -305,6 +305,9 @@
 		4CFD6B102201145500FFB5E3 /* RedirectHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B0F2201145500FFB5E3 /* RedirectHandlerTests.swift */; };
 		4CFD6B112201145500FFB5E3 /* RedirectHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B0F2201145500FFB5E3 /* RedirectHandlerTests.swift */; };
 		4CFD6B122201145500FFB5E3 /* RedirectHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B0F2201145500FFB5E3 /* RedirectHandlerTests.swift */; };
+		4CFD6B142201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B132201338E00FFB5E3 /* CachedResponseHandlerTests.swift */; };
+		4CFD6B152201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B132201338E00FFB5E3 /* CachedResponseHandlerTests.swift */; };
+		4CFD6B162201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD6B132201338E00FFB5E3 /* CachedResponseHandlerTests.swift */; };
 		4DD67C241A5C58FB00ED2280 /* Alamofire.h in Headers */ = {isa = PBXBuildFile; fileRef = F8111E3819A95C8B0040E7D1 /* Alamofire.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		4DD67C251A5C590000ED2280 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897FF4019AA800700AB5182 /* Alamofire.swift */; };
 		8035DB621BAB492500466CB3 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8111E3319A95C8B0040E7D1 /* Alamofire.framework */; };
@@ -437,6 +440,7 @@
 		4CFB02F31D7D2FA20056F249 /* utf32_string.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = utf32_string.txt; sourceTree = "<group>"; };
 		4CFB02F41D7D2FA20056F249 /* utf8_string.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = utf8_string.txt; sourceTree = "<group>"; };
 		4CFD6B0F2201145500FFB5E3 /* RedirectHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedirectHandlerTests.swift; sourceTree = "<group>"; };
+		4CFD6B132201338E00FFB5E3 /* CachedResponseHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedResponseHandlerTests.swift; sourceTree = "<group>"; };
 		4DD67C0B1A5C55C900ED2280 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		B39E2F831C1A72F8002DA1A9 /* certDER.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = certDER.cer; path = selfSignedAndMalformedCerts/certDER.cer; sourceTree = "<group>"; };
 		B39E2F841C1A72F8002DA1A9 /* certDER.crt */ = {isa = PBXFileReference; lastKnownFileType = file; name = certDER.crt; path = selfSignedAndMalformedCerts/certDER.crt; sourceTree = "<group>"; };
@@ -540,6 +544,7 @@
 		4C256A4F1B09656E0065714F /* Features */ = {
 			isa = PBXGroup;
 			children = (
+				4CFD6B132201338E00FFB5E3 /* CachedResponseHandlerTests.swift */,
 				4C341BB91B1A865A00C1B34D /* CacheTests.swift */,
 				3113D46A21878227001CCD21 /* HTTPHeadersTests.swift */,
 				4C3238E61B3604DB00FE04AE /* MultipartFormDataTests.swift */,
@@ -1333,6 +1338,7 @@
 				3111CE9420A7EC32008315E2 /* ResponseSerializationTests.swift in Sources */,
 				3111CE8E20A7EBE7008315E2 /* MultipartFormDataTests.swift in Sources */,
 				311B199620B0ED990036823B /* UploadTests.swift in Sources */,
+				4CFD6B162201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */,
 				3107EA3720A11AE200445260 /* AuthenticationTests.swift in Sources */,
 				31ED52EA1D73891C00199085 /* AFError+AlamofireTests.swift in Sources */,
 				3107EA3A20A11F9700445260 /* ResponseTests.swift in Sources */,
@@ -1473,6 +1479,7 @@
 				3111CE9220A7EC30008315E2 /* ResponseSerializationTests.swift in Sources */,
 				3111CE8C20A7EBE6008315E2 /* MultipartFormDataTests.swift in Sources */,
 				311B199420B0ED980036823B /* UploadTests.swift in Sources */,
+				4CFD6B142201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */,
 				3107EA3520A11AE100445260 /* AuthenticationTests.swift in Sources */,
 				4CFB02901D7CF28F0056F249 /* FileManager+AlamofireTests.swift in Sources */,
 				3107EA3820A11F9600445260 /* ResponseTests.swift in Sources */,
@@ -1505,6 +1512,7 @@
 				3111CE9320A7EC31008315E2 /* ResponseSerializationTests.swift in Sources */,
 				3111CE8D20A7EBE7008315E2 /* MultipartFormDataTests.swift in Sources */,
 				311B199520B0ED980036823B /* UploadTests.swift in Sources */,
+				4CFD6B152201338E00FFB5E3 /* CachedResponseHandlerTests.swift in Sources */,
 				3107EA3620A11AE100445260 /* AuthenticationTests.swift in Sources */,
 				4CFB02911D7CF28F0056F249 /* FileManager+AlamofireTests.swift in Sources */,
 				3107EA3920A11F9600445260 /* ResponseTests.swift in Sources */,

+ 226 - 0
Tests/CachedResponseHandlerTests.swift

@@ -0,0 +1,226 @@
+//
+//  CachedResponseHandlerTests.swift
+//
+//  Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/)
+//
+//  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 Alamofire
+import Foundation
+import XCTest
+
+final class CachedResponseHandlerTestCase: BaseTestCase {
+
+    // MARK: Properties
+
+    private let urlString = "https://httpbin.org/get"
+
+    // MARK: Tests - Per Request
+
+    func testThatRequestCachedResponseHandlerCanCacheResponse() {
+        // Given
+        let session = self.session()
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should cache response")
+
+        // When
+        let request = session.request(urlString).cacheResponse(using: ResponseCacher.cache).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertTrue(session.cachedResponseExists(for: request))
+    }
+
+    func testThatRequestCachedResponseHandlerCanNotCacheResponse() {
+        // Given
+        let session = self.session()
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should not cache response")
+
+        // When
+        let request = session.request(urlString).cacheResponse(using: ResponseCacher.doNotCache).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertFalse(session.cachedResponseExists(for: request))
+    }
+
+    func testThatRequestCachedResponseHandlerCanModifyCacheResponse() {
+        // Given
+        let session = self.session()
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should cache response")
+
+        // When
+        let cacher = ResponseCacher(
+            behavior: .modify { _, response in
+                return CachedURLResponse(
+                    response: response.response,
+                    data: response.data,
+                    userInfo: ["key": "value"],
+                    storagePolicy: .allowed
+                )
+            }
+        )
+
+        let request = session.request(urlString).cacheResponse(using: cacher).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertTrue(session.cachedResponseExists(for: request))
+        XCTAssertEqual(session.cachedResponse(for: request)?.userInfo?["key"] as? String, "value")
+    }
+
+    // MARK: Tests - Per Session
+
+    func testThatSessionCachedResponseHandlerCanCacheResponse() {
+        // Given
+        let session = self.session(using: ResponseCacher.cache)
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should cache response")
+
+        // When
+        let request = session.request(urlString).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertTrue(session.cachedResponseExists(for: request))
+    }
+
+    func testThatSessionCachedResponseHandlerCanNotCacheResponse() {
+        // Given
+        let session = self.session(using: ResponseCacher.doNotCache)
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should not cache response")
+
+        // When
+        let request = session.request(urlString).cacheResponse(using: ResponseCacher.doNotCache).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertFalse(session.cachedResponseExists(for: request))
+    }
+
+    func testThatSessionCachedResponseHandlerCanModifyCacheResponse() {
+        // Given
+        let cacher = ResponseCacher(
+            behavior: .modify { _, response in
+                return CachedURLResponse(
+                    response: response.response,
+                    data: response.data,
+                    userInfo: ["key": "value"],
+                    storagePolicy: .allowed
+                )
+            }
+        )
+
+        let session = self.session(using: cacher)
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should cache response")
+
+        // When
+        let request = session.request(urlString).cacheResponse(using: cacher).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertTrue(session.cachedResponseExists(for: request))
+        XCTAssertEqual(session.cachedResponse(for: request)?.userInfo?["key"] as? String, "value")
+    }
+
+    // MARK: Tests - Per Request Prioritization
+
+    func testThatRequestCachedResponseHandlerIsPrioritizedOverSessionCachedResponseHandler() {
+        // Given
+        let session = self.session(using: ResponseCacher.cache)
+
+        var response: DataResponse<Data?>?
+        let expectation = self.expectation(description: "Request should cache response")
+
+        // When
+        let request = session.request(urlString).cacheResponse(using: ResponseCacher.doNotCache).response { resp in
+            response = resp
+            expectation.fulfill()
+        }
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertEqual(response?.result.isSuccess, true)
+        XCTAssertFalse(session.cachedResponseExists(for: request))
+    }
+
+    // MARK: Private - Test Helpers
+
+    private func session(using handler: CachedResponseHandler? = nil) -> Session {
+        let configuration = URLSessionConfiguration.alamofireDefault
+        configuration.urlCache = URLCache(memoryCapacity: 100_000_000, diskCapacity: 100_000_000, diskPath: UUID().uuidString)
+
+        return Session(configuration: configuration, cachedResponseHandler: handler)
+    }
+}
+
+// MARK: -
+
+extension Session {
+    fileprivate func cachedResponse(for request: Request) -> CachedURLResponse? {
+        guard let urlRequest = request.request else { return nil }
+        return session.configuration.urlCache?.cachedResponse(for: urlRequest)
+    }
+
+    fileprivate func cachedResponseExists(for request: Request) -> Bool {
+        return cachedResponse(for: request) != nil
+    }
+}