SessionTests.swift 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817
  1. //
  2. // SessionTests.swift
  3. //
  4. // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. @testable import Alamofire
  25. import Foundation
  26. import XCTest
  27. final class SessionTestCase: BaseTestCase {
  28. // MARK: Helper Types
  29. private class HTTPMethodAdapter: RequestInterceptor {
  30. let method: HTTPMethod
  31. let throwsError: Bool
  32. var adaptedCount = 0
  33. init(method: HTTPMethod, throwsError: Bool = false) {
  34. self.method = method
  35. self.throwsError = throwsError
  36. }
  37. func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  38. adaptedCount += 1
  39. let result: Result<URLRequest, Error> = Result {
  40. guard !throwsError else { throw AFError.invalidURL(url: "") }
  41. var urlRequest = urlRequest
  42. urlRequest.httpMethod = method.rawValue
  43. return urlRequest
  44. }
  45. completion(result)
  46. }
  47. }
  48. private class HeaderAdapter: RequestInterceptor {
  49. let headers: HTTPHeaders
  50. let throwsError: Bool
  51. var adaptedCount = 0
  52. init(headers: HTTPHeaders = ["field": "value"], throwsError: Bool = false) {
  53. self.headers = headers
  54. self.throwsError = throwsError
  55. }
  56. func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  57. adaptedCount += 1
  58. let result: Result<URLRequest, Error> = Result {
  59. guard !throwsError else { throw AFError.invalidURL(url: "") }
  60. var urlRequest = urlRequest
  61. var finalHeaders = urlRequest.headers
  62. headers.forEach { finalHeaders.add($0) }
  63. urlRequest.headers = finalHeaders
  64. return urlRequest
  65. }
  66. completion(result)
  67. }
  68. }
  69. private class RequestHandler: RequestInterceptor {
  70. var adaptCalledCount = 0
  71. var adaptedCount = 0
  72. var retryCount = 0
  73. var retryCalledCount = 0
  74. var retryErrors: [Error] = []
  75. var shouldApplyAuthorizationHeader = false
  76. var throwsErrorOnFirstAdapt = false
  77. var throwsErrorOnSecondAdapt = false
  78. var throwsErrorOnRetry = false
  79. var shouldRetry = true
  80. var retryDelay: TimeInterval?
  81. func adapt(_ urlRequest: URLRequest,
  82. using state: RequestAdapterState,
  83. completion: @escaping (Result<URLRequest, Error>) -> Void) {
  84. adaptCalledCount += 1
  85. let result: Result<URLRequest, Error> = Result {
  86. if throwsErrorOnFirstAdapt {
  87. throwsErrorOnFirstAdapt = false
  88. throw AFError.invalidURL(url: "/adapt/error/1")
  89. }
  90. if throwsErrorOnSecondAdapt && adaptedCount == 1 {
  91. throwsErrorOnSecondAdapt = false
  92. throw AFError.invalidURL(url: "/adapt/error/2")
  93. }
  94. var urlRequest = urlRequest
  95. adaptedCount += 1
  96. if shouldApplyAuthorizationHeader && adaptedCount > 1 {
  97. urlRequest.headers.update(.authorization(username: "user", password: "password"))
  98. }
  99. return urlRequest
  100. }
  101. completion(result)
  102. }
  103. func retry(_ request: Request,
  104. for session: Session,
  105. dueTo error: Error,
  106. completion: @escaping (RetryResult) -> Void) {
  107. retryCalledCount += 1
  108. if throwsErrorOnRetry {
  109. let error = AFError.invalidURL(url: "/invalid/url/\(retryCalledCount)")
  110. completion(.doNotRetryWithError(error))
  111. return
  112. }
  113. guard shouldRetry else { completion(.doNotRetry); return }
  114. retryCount += 1
  115. retryErrors.append(error)
  116. if retryCount < 2 {
  117. if let retryDelay {
  118. completion(.retryWithDelay(retryDelay))
  119. } else {
  120. completion(.retry)
  121. }
  122. } else {
  123. completion(.doNotRetry)
  124. }
  125. }
  126. }
  127. private class UploadHandler: RequestInterceptor {
  128. struct MutableState {
  129. var adaptCalledCount = 0
  130. var adaptedCount = 0
  131. var retryCalledCount = 0
  132. var retryCount = 0
  133. var retryErrors: [Error] = []
  134. }
  135. private let mutableState = Protected(MutableState())
  136. var adaptCalledCount: Int { mutableState.adaptCalledCount }
  137. var adaptedCount: Int { mutableState.adaptedCount }
  138. var retryCalledCount: Int { mutableState.retryCalledCount }
  139. var retryCount: Int { mutableState.retryCount }
  140. var retryErrors: [Error] { mutableState.retryErrors }
  141. func adapt(_ urlRequest: URLRequest,
  142. using state: RequestAdapterState,
  143. completion: @escaping (Result<URLRequest, Error>) -> Void) {
  144. let result: Result<URLRequest, Error> = mutableState.write { mutableState in
  145. mutableState.adaptCalledCount += 1
  146. return Result {
  147. mutableState.adaptedCount += 1
  148. if mutableState.adaptedCount == 1 { throw AFError.invalidURL(url: "") }
  149. return urlRequest
  150. }
  151. }
  152. completion(result)
  153. }
  154. func retry(_ request: Request,
  155. for session: Session,
  156. dueTo error: Error,
  157. completion: @escaping (RetryResult) -> Void) {
  158. mutableState.write { mutableState in
  159. mutableState.retryCalledCount += 1
  160. mutableState.retryCount += 1
  161. mutableState.retryErrors.append(error)
  162. }
  163. completion(.retry)
  164. }
  165. }
  166. // MARK: Tests - Initialization
  167. func testInitializerWithDefaultArguments() {
  168. // Given, When
  169. let session = Session()
  170. // Then
  171. XCTAssertNotNil(session.session.delegate, "session delegate should not be nil")
  172. XCTAssertTrue(session.delegate === session.session.delegate, "manager delegate should equal session delegate")
  173. XCTAssertNil(session.serverTrustManager, "session server trust policy manager should be nil")
  174. }
  175. func testInitializerWithSpecifiedArguments() {
  176. // Given
  177. let configuration = URLSessionConfiguration.default
  178. let delegate = SessionDelegate()
  179. let serverTrustManager = ServerTrustManager(evaluators: [:])
  180. // When
  181. let session = Session(configuration: configuration,
  182. delegate: delegate,
  183. serverTrustManager: serverTrustManager)
  184. // Then
  185. XCTAssertNotNil(session.session.delegate, "session delegate should not be nil")
  186. XCTAssertTrue(session.delegate === session.session.delegate, "manager delegate should equal session delegate")
  187. XCTAssertNotNil(session.serverTrustManager, "session server trust policy manager should not be nil")
  188. }
  189. func testThatSessionInitializerSucceedsWithDefaultArguments() {
  190. // Given
  191. let delegate = SessionDelegate()
  192. let underlyingQueue = DispatchQueue(label: "underlyingQueue")
  193. let urlSession: URLSession = {
  194. let configuration = URLSessionConfiguration.default
  195. let queue = OperationQueue(underlyingQueue: underlyingQueue, name: "delegateQueue")
  196. return URLSession(configuration: configuration, delegate: delegate, delegateQueue: queue)
  197. }()
  198. // When
  199. let session = Session(session: urlSession, delegate: delegate, rootQueue: underlyingQueue)
  200. // Then
  201. XCTAssertTrue(session.delegate === session.session.delegate, "manager delegate should equal session delegate")
  202. XCTAssertNil(session.serverTrustManager, "session server trust policy manager should be nil")
  203. }
  204. func testThatSessionInitializerSucceedsWithSpecifiedArguments() {
  205. // Given
  206. let delegate = SessionDelegate()
  207. let underlyingQueue = DispatchQueue(label: "underlyingQueue")
  208. let urlSession: URLSession = {
  209. let configuration = URLSessionConfiguration.default
  210. let queue = OperationQueue(underlyingQueue: underlyingQueue, name: "delegateQueue")
  211. return URLSession(configuration: configuration, delegate: delegate, delegateQueue: queue)
  212. }()
  213. let serverTrustManager = ServerTrustManager(evaluators: [:])
  214. // When
  215. let session = Session(session: urlSession,
  216. delegate: delegate,
  217. rootQueue: underlyingQueue,
  218. serverTrustManager: serverTrustManager)
  219. // Then
  220. XCTAssertTrue(session.delegate === session.session.delegate, "manager delegate should equal session delegate")
  221. XCTAssertNotNil(session.serverTrustManager, "session server trust policy manager should not be nil")
  222. }
  223. // MARK: Tests - Parallel Root Queue
  224. func testThatSessionWorksCorrectlyWhenPassedAConcurrentRootQueue() {
  225. // Given
  226. let queue = DispatchQueue(label: "ohNoAParallelQueue", attributes: .concurrent)
  227. let session = Session(rootQueue: queue)
  228. let didFinish = expectation(description: "request did finish")
  229. var receivedResponse: TestResponse?
  230. // When
  231. session.request(.get).responseDecodable(of: TestResponse.self) { response in
  232. receivedResponse = response.value
  233. didFinish.fulfill()
  234. }
  235. waitForExpectations(timeout: timeout)
  236. // Then
  237. XCTAssertNotNil(receivedResponse, "Should receive TestResponse.")
  238. }
  239. // MARK: Tests - Default HTTP Headers
  240. func testDefaultUserAgentHeader() {
  241. // Given, When
  242. let userAgent = HTTPHeaders.default["User-Agent"]
  243. // Then
  244. let osNameVersion: String = {
  245. let version = ProcessInfo.processInfo.operatingSystemVersion
  246. let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
  247. let osName: String = {
  248. #if os(iOS)
  249. #if targetEnvironment(macCatalyst)
  250. return "macOS(Catalyst)"
  251. #else
  252. return "iOS"
  253. #endif
  254. #elseif os(watchOS)
  255. return "watchOS"
  256. #elseif os(tvOS)
  257. return "tvOS"
  258. #elseif os(macOS)
  259. #if targetEnvironment(macCatalyst)
  260. return "macOS(Catalyst)"
  261. #else
  262. return "macOS"
  263. #endif
  264. #elseif swift(>=5.9.2) && os(visionOS)
  265. return "visionOS"
  266. #elseif os(Linux)
  267. return "Linux"
  268. #elseif os(Windows)
  269. return "Windows"
  270. #elseif os(Android)
  271. return "Android"
  272. #else
  273. return "Unknown"
  274. #endif
  275. }()
  276. return "\(osName) \(versionString)"
  277. }()
  278. let alamofireVersion = "Alamofire/\(AFInfo.version)"
  279. XCTAssertTrue(userAgent?.contains(alamofireVersion) == true)
  280. XCTAssertTrue(userAgent?.contains(osNameVersion) == true)
  281. XCTAssertTrue(userAgent?.contains("xctest/") == true)
  282. }
  283. // MARK: Tests - Supported Accept-Encodings
  284. // Disabled due to HTTPBin flakiness.
  285. func _testDefaultAcceptEncodingSupportsAppropriateEncodingsOnAppropriateSystems() {
  286. // Given
  287. let brotliExpectation = expectation(description: "brotli request should complete")
  288. let gzipExpectation = expectation(description: "gzip request should complete")
  289. let deflateExpectation = expectation(description: "deflate request should complete")
  290. var brotliResponse: DataResponse<TestResponse, AFError>?
  291. var gzipResponse: DataResponse<TestResponse, AFError>?
  292. var deflateResponse: DataResponse<TestResponse, AFError>?
  293. // When
  294. AF.request(.compression(.brotli)).responseDecodable(of: TestResponse.self) { response in
  295. brotliResponse = response
  296. brotliExpectation.fulfill()
  297. }
  298. AF.request(.compression(.gzip)).responseDecodable(of: TestResponse.self) { response in
  299. gzipResponse = response
  300. gzipExpectation.fulfill()
  301. }
  302. AF.request(.compression(.deflate)).responseDecodable(of: TestResponse.self) { response in
  303. deflateResponse = response
  304. deflateExpectation.fulfill()
  305. }
  306. waitForExpectations(timeout: timeout)
  307. // Then
  308. if #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) {
  309. XCTAssertTrue(brotliResponse?.result.isSuccess == true)
  310. } else {
  311. XCTAssertTrue(brotliResponse?.result.isFailure == true)
  312. }
  313. XCTAssertTrue(gzipResponse?.result.isSuccess == true)
  314. XCTAssertTrue(deflateResponse?.result.isSuccess == true)
  315. }
  316. // MARK: Tests - Start Requests Immediately
  317. func testSetStartRequestsImmediatelyToFalseAndResumeRequest() {
  318. // Given
  319. let session = Session(startRequestsImmediately: false)
  320. let url = Endpoint().url
  321. let urlRequest = URLRequest(url: url)
  322. let expectation = expectation(description: "\(url)")
  323. var response: HTTPURLResponse?
  324. // When
  325. session.request(urlRequest)
  326. .response { resp in
  327. response = resp.response
  328. expectation.fulfill()
  329. }
  330. .resume()
  331. waitForExpectations(timeout: timeout)
  332. // Then
  333. XCTAssertNotNil(response, "response should not be nil")
  334. XCTAssertTrue(response?.statusCode == 200, "response status code should be 200")
  335. }
  336. func testSetStartRequestsImmediatelyToFalseAndCancelledCallsResponseHandlers() {
  337. // Given
  338. let session = Session(startRequestsImmediately: false)
  339. let url = Endpoint().url
  340. let urlRequest = URLRequest(url: url)
  341. let expectation = expectation(description: "\(url)")
  342. var response: DataResponse<Data?, AFError>?
  343. // When
  344. let request = session.request(urlRequest)
  345. .cancel()
  346. .response { resp in
  347. response = resp
  348. expectation.fulfill()
  349. }
  350. waitForExpectations(timeout: timeout)
  351. // Then
  352. XCTAssertNotNil(response, "response should not be nil")
  353. XCTAssertTrue(request.isCancelled)
  354. XCTAssertTrue((request.task == nil) || (request.task?.state == .canceling || request.task?.state == .completed))
  355. XCTAssertEqual(request.error?.isExplicitlyCancelledError, true)
  356. }
  357. func testSetStartRequestsImmediatelyToFalseAndResumeThenCancelRequestHasCorrectOutput() {
  358. // Given
  359. let session = Session(startRequestsImmediately: false)
  360. let url = Endpoint().url
  361. let urlRequest = URLRequest(url: url)
  362. let expectation = expectation(description: "\(url)")
  363. var response: DataResponse<Data?, AFError>?
  364. // When
  365. let request = session.request(urlRequest)
  366. .response { resp in
  367. response = resp
  368. expectation.fulfill()
  369. }
  370. .resume()
  371. .cancel()
  372. waitForExpectations(timeout: timeout)
  373. // Then
  374. XCTAssertNotNil(response, "response should not be nil")
  375. XCTAssertTrue(request.isCancelled)
  376. XCTAssertTrue((request.task == nil) || (request.task?.state == .canceling || request.task?.state == .completed))
  377. XCTAssertEqual(request.error?.isExplicitlyCancelledError, true)
  378. }
  379. func testSetStartRequestsImmediatelyToFalseAndCancelThenResumeRequestDoesntCreateTaskAndStaysCancelled() {
  380. // Given
  381. let session = Session(startRequestsImmediately: false)
  382. let url = Endpoint().url
  383. let urlRequest = URLRequest(url: url)
  384. let expectation = expectation(description: "\(url)")
  385. var response: DataResponse<Data?, AFError>?
  386. // When
  387. let request = session.request(urlRequest)
  388. .response { resp in
  389. response = resp
  390. expectation.fulfill()
  391. }
  392. .cancel()
  393. .resume()
  394. waitForExpectations(timeout: timeout)
  395. // Then
  396. XCTAssertNotNil(response, "response should not be nil")
  397. XCTAssertTrue(request.isCancelled)
  398. XCTAssertTrue((request.task == nil) || (request.task?.state == .canceling || request.task?.state == .completed))
  399. XCTAssertEqual(request.error?.isExplicitlyCancelledError, true)
  400. }
  401. // MARK: Tests - Deinitialization
  402. func testReleasingManagerWithPendingRequestDeinitializesSuccessfully() {
  403. // Given
  404. let monitor = ClosureEventMonitor()
  405. let didCreateRequest = expectation(description: "Request created")
  406. monitor.requestDidCreateTask = { _, _ in didCreateRequest.fulfill() }
  407. var session: Session? = Session(startRequestsImmediately: false, eventMonitors: [monitor])
  408. weak var weakSession = session
  409. // When
  410. let request = session?.request(.default)
  411. session = nil
  412. waitForExpectations(timeout: timeout)
  413. // Then
  414. if #available(macOS 13, iOS 16, tvOS 16, watchOS 9, *) {
  415. // On 2022 OS versions and later, URLSessionTasks are completed even if not resumed before invalidating a session.
  416. XCTAssertTrue([.canceling, .completed].contains(request?.task?.state))
  417. } else {
  418. XCTAssertEqual(request?.task?.state, .suspended)
  419. }
  420. XCTAssertNil(session, "session should be nil")
  421. XCTAssertNil(weakSession, "weak session should be nil")
  422. }
  423. func testReleasingManagerWithPendingCanceledRequestDeinitializesSuccessfully() {
  424. // Given
  425. var session: Session? = Session(startRequestsImmediately: false)
  426. // When
  427. let request = session?.request(.default)
  428. request?.cancel()
  429. session = nil
  430. let state = request?.state
  431. // Then
  432. XCTAssertTrue(state == .cancelled, "state should be .cancelled")
  433. XCTAssertNil(session, "manager should be nil")
  434. }
  435. // MARK: Tests - Bad Requests
  436. func testThatDataRequestWithInvalidURLStringThrowsResponseHandlerError() {
  437. // Given
  438. let session = Session()
  439. let url = ""
  440. let expectation = expectation(description: "Request should fail with error")
  441. var response: DataResponse<Data?, AFError>?
  442. // When
  443. session.request(url).response { resp in
  444. response = resp
  445. expectation.fulfill()
  446. }
  447. waitForExpectations(timeout: timeout)
  448. // Then
  449. XCTAssertNil(response?.request)
  450. XCTAssertNil(response?.response)
  451. XCTAssertNil(response?.data)
  452. XCTAssertNotNil(response?.error)
  453. XCTAssertEqual(response?.error?.isInvalidURLError, true)
  454. XCTAssertEqual(response?.error?.urlConvertible as? String, url)
  455. }
  456. func testThatDownloadRequestWithInvalidURLStringThrowsResponseHandlerError() {
  457. // Given
  458. let session = Session()
  459. let url = ""
  460. let expectation = expectation(description: "Download should fail with error")
  461. var response: DownloadResponse<URL?, AFError>?
  462. // When
  463. session.download(url).response { resp in
  464. response = resp
  465. expectation.fulfill()
  466. }
  467. waitForExpectations(timeout: timeout)
  468. // Then
  469. XCTAssertNil(response?.request)
  470. XCTAssertNil(response?.response)
  471. XCTAssertNil(response?.fileURL)
  472. XCTAssertNil(response?.resumeData)
  473. XCTAssertNotNil(response?.error)
  474. XCTAssertEqual(response?.error?.isInvalidURLError, true)
  475. XCTAssertEqual(response?.error?.urlConvertible as? String, url)
  476. }
  477. func testThatUploadDataRequestWithInvalidURLStringThrowsResponseHandlerError() {
  478. // Given
  479. let session = Session()
  480. let url = ""
  481. let expectation = expectation(description: "Upload should fail with error")
  482. var response: DataResponse<Data?, AFError>?
  483. // When
  484. session.upload(Data(), to: url).response { resp in
  485. response = resp
  486. expectation.fulfill()
  487. }
  488. waitForExpectations(timeout: timeout)
  489. // Then
  490. XCTAssertNil(response?.request)
  491. XCTAssertNil(response?.response)
  492. XCTAssertNil(response?.data)
  493. XCTAssertNotNil(response?.error)
  494. XCTAssertEqual(response?.error?.isInvalidURLError, true)
  495. XCTAssertEqual(response?.error?.urlConvertible as? String, url)
  496. }
  497. func testThatUploadFileRequestWithInvalidURLStringThrowsResponseHandlerError() {
  498. // Given
  499. let session = Session()
  500. let url = ""
  501. let expectation = expectation(description: "Upload should fail with error")
  502. var response: DataResponse<Data?, AFError>?
  503. // When
  504. session.upload(URL(fileURLWithPath: "/invalid"), to: url).response { resp in
  505. response = resp
  506. expectation.fulfill()
  507. }
  508. waitForExpectations(timeout: timeout)
  509. // Then
  510. XCTAssertNil(response?.request)
  511. XCTAssertNil(response?.response)
  512. XCTAssertNil(response?.data)
  513. XCTAssertNotNil(response?.error)
  514. XCTAssertEqual(response?.error?.isInvalidURLError, true)
  515. XCTAssertEqual(response?.error?.urlConvertible as? String, url)
  516. }
  517. func testThatUploadStreamRequestWithInvalidURLStringThrowsResponseHandlerError() {
  518. // Given
  519. let session = Session()
  520. let url = ""
  521. let expectation = expectation(description: "Upload should fail with error")
  522. var response: DataResponse<Data?, AFError>?
  523. // When
  524. session.upload(InputStream(data: Data()), to: url).response { resp in
  525. response = resp
  526. expectation.fulfill()
  527. }
  528. waitForExpectations(timeout: timeout)
  529. // Then
  530. XCTAssertNil(response?.request)
  531. XCTAssertNil(response?.response)
  532. XCTAssertNil(response?.data)
  533. XCTAssertNotNil(response?.error)
  534. XCTAssertEqual(response?.error?.isInvalidURLError, true)
  535. XCTAssertEqual(response?.error?.urlConvertible as? String, url)
  536. }
  537. // MARK: Tests - Request Adapter
  538. func testThatSessionCallsRequestAdaptersWhenCreatingDataRequest() {
  539. // Given
  540. let endpoint = Endpoint()
  541. let methodAdapter = HTTPMethodAdapter(method: .post)
  542. let headerAdapter = HeaderAdapter()
  543. let monitor = ClosureEventMonitor()
  544. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  545. // When
  546. let expectation1 = expectation(description: "Request 1 created")
  547. monitor.requestDidCreateTask = { _, _ in expectation1.fulfill() }
  548. let request1 = session.request(endpoint)
  549. waitForExpectations(timeout: timeout)
  550. let expectation2 = expectation(description: "Request 2 created")
  551. monitor.requestDidCreateTask = { _, _ in expectation2.fulfill() }
  552. let request2 = session.request(endpoint, interceptor: headerAdapter)
  553. waitForExpectations(timeout: timeout)
  554. // Then
  555. XCTAssertEqual(request1.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  556. XCTAssertEqual(request2.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  557. XCTAssertEqual(request2.task?.originalRequest?.allHTTPHeaderFields?.count, 1)
  558. XCTAssertEqual(methodAdapter.adaptedCount, 2)
  559. XCTAssertEqual(headerAdapter.adaptedCount, 1)
  560. }
  561. func testThatSessionCallsRequestAdaptersWhenCreatingDownloadRequest() {
  562. // Given
  563. let endpoint = Endpoint()
  564. let methodAdapter = HTTPMethodAdapter(method: .post)
  565. let headerAdapter = HeaderAdapter()
  566. let monitor = ClosureEventMonitor()
  567. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  568. // When
  569. let expectation1 = expectation(description: "Request 1 created")
  570. monitor.requestDidCreateTask = { _, _ in expectation1.fulfill() }
  571. let request1 = session.download(endpoint)
  572. waitForExpectations(timeout: timeout)
  573. let expectation2 = expectation(description: "Request 2 created")
  574. monitor.requestDidCreateTask = { _, _ in expectation2.fulfill() }
  575. let request2 = session.download(endpoint, interceptor: headerAdapter)
  576. waitForExpectations(timeout: timeout)
  577. // Then
  578. XCTAssertEqual(request1.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  579. XCTAssertEqual(request2.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  580. XCTAssertEqual(request2.task?.originalRequest?.allHTTPHeaderFields?.count, 1)
  581. XCTAssertEqual(methodAdapter.adaptedCount, 2)
  582. XCTAssertEqual(headerAdapter.adaptedCount, 1)
  583. }
  584. func testThatSessionCallsRequestAdaptersWhenCreatingUploadRequestWithData() {
  585. // Given
  586. let data = Data("data".utf8)
  587. let endpoint = Endpoint.method(.post)
  588. let methodAdapter = HTTPMethodAdapter(method: .get)
  589. let headerAdapter = HeaderAdapter()
  590. let monitor = ClosureEventMonitor()
  591. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  592. // When
  593. let expectation1 = expectation(description: "Request 1 created")
  594. monitor.requestDidCreateTask = { _, _ in expectation1.fulfill() }
  595. let request1 = session.upload(data, to: endpoint)
  596. waitForExpectations(timeout: timeout)
  597. let expectation2 = expectation(description: "Request 2 created")
  598. monitor.requestDidCreateTask = { _, _ in expectation2.fulfill() }
  599. let request2 = session.upload(data, to: endpoint, interceptor: headerAdapter)
  600. waitForExpectations(timeout: timeout)
  601. // Then
  602. XCTAssertEqual(request1.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  603. XCTAssertEqual(request2.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  604. XCTAssertEqual(request2.task?.originalRequest?.allHTTPHeaderFields?.count, 1)
  605. XCTAssertEqual(methodAdapter.adaptedCount, 2)
  606. XCTAssertEqual(headerAdapter.adaptedCount, 1)
  607. }
  608. func testThatSessionCallsRequestAdaptersWhenCreatingUploadRequestWithFile() {
  609. // Given
  610. let fileURL = URL(fileURLWithPath: "/path/to/some/file.txt")
  611. let endpoint = Endpoint.method(.post)
  612. let methodAdapter = HTTPMethodAdapter(method: .get)
  613. let headerAdapter = HeaderAdapter()
  614. let monitor = ClosureEventMonitor()
  615. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  616. // When
  617. let expectation1 = expectation(description: "Request 1 created")
  618. monitor.requestDidCreateTask = { _, _ in expectation1.fulfill() }
  619. let request1 = session.upload(fileURL, to: endpoint)
  620. waitForExpectations(timeout: timeout)
  621. let expectation2 = expectation(description: "Request 2 created")
  622. monitor.requestDidCreateTask = { _, _ in expectation2.fulfill() }
  623. let request2 = session.upload(fileURL, to: endpoint, interceptor: headerAdapter)
  624. waitForExpectations(timeout: timeout)
  625. // Then
  626. XCTAssertEqual(request1.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  627. XCTAssertEqual(request2.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  628. XCTAssertEqual(request2.task?.originalRequest?.allHTTPHeaderFields?.count, 1)
  629. XCTAssertEqual(methodAdapter.adaptedCount, 2)
  630. XCTAssertEqual(headerAdapter.adaptedCount, 1)
  631. }
  632. func testThatSessionCallsRequestAdaptersWhenCreatingUploadRequestWithInputStream() {
  633. // Given
  634. let inputStream = InputStream(data: Data("data".utf8))
  635. let endpoint = Endpoint.method(.post)
  636. let methodAdapter = HTTPMethodAdapter(method: .get)
  637. let headerAdapter = HeaderAdapter()
  638. let monitor = ClosureEventMonitor()
  639. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  640. // When
  641. let expectation1 = expectation(description: "Request 1 created")
  642. monitor.requestDidCreateTask = { _, _ in expectation1.fulfill() }
  643. let request1 = session.upload(inputStream, to: endpoint)
  644. waitForExpectations(timeout: timeout)
  645. let expectation2 = expectation(description: "Request 2 created")
  646. monitor.requestDidCreateTask = { _, _ in expectation2.fulfill() }
  647. let request2 = session.upload(inputStream, to: endpoint, interceptor: headerAdapter)
  648. waitForExpectations(timeout: timeout)
  649. // Then
  650. XCTAssertEqual(request1.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  651. XCTAssertEqual(request2.task?.originalRequest?.httpMethod, methodAdapter.method.rawValue)
  652. XCTAssertEqual(request2.task?.originalRequest?.allHTTPHeaderFields?.count, 1)
  653. XCTAssertEqual(methodAdapter.adaptedCount, 2)
  654. XCTAssertEqual(headerAdapter.adaptedCount, 1)
  655. }
  656. func testThatSessionReturnsRequestAdaptationErrorWhenRequestAdapterThrowsError() {
  657. // Given
  658. let endpoint = Endpoint()
  659. let methodAdapter = HTTPMethodAdapter(method: .post, throwsError: true)
  660. let headerAdapter = HeaderAdapter(throwsError: true)
  661. let monitor = ClosureEventMonitor()
  662. let session = Session(startRequestsImmediately: false, interceptor: methodAdapter, eventMonitors: [monitor])
  663. // When
  664. let expectation1 = expectation(description: "Request 1 created")
  665. monitor.requestDidFailToAdaptURLRequestWithError = { _, _, _ in expectation1.fulfill() }
  666. let request1 = session.request(endpoint)
  667. waitForExpectations(timeout: timeout)
  668. let expectation2 = expectation(description: "Request 2 created")
  669. monitor.requestDidFailToAdaptURLRequestWithError = { _, _, _ in expectation2.fulfill() }
  670. let request2 = session.request(endpoint, interceptor: headerAdapter)
  671. waitForExpectations(timeout: timeout)
  672. let requests = [request1, request2]
  673. // Then
  674. for request in requests {
  675. XCTAssertEqual(request.error?.isRequestAdaptationError, true)
  676. XCTAssertEqual(request.error?.underlyingError?.asAFError?.urlConvertible as? String, "")
  677. }
  678. }
  679. // MARK: Tests - Request Retrier
  680. func testThatSessionCallsRequestRetrierWhenRequestInitiallyEncountersAdaptError() {
  681. // Given
  682. let handler = RequestHandler()
  683. handler.adaptedCount = 1
  684. handler.throwsErrorOnSecondAdapt = true
  685. handler.shouldApplyAuthorizationHeader = true
  686. let session = Session()
  687. let expectation = expectation(description: "request should eventually fail")
  688. var response: DataResponse<TestResponse, AFError>?
  689. // When
  690. session.request(.basicAuth(), interceptor: handler)
  691. .validate()
  692. .responseDecodable(of: TestResponse.self) { jsonResponse in
  693. response = jsonResponse
  694. expectation.fulfill()
  695. }
  696. waitForExpectations(timeout: timeout)
  697. // Then
  698. XCTAssertEqual(handler.adaptCalledCount, 2)
  699. XCTAssertEqual(handler.adaptedCount, 2)
  700. XCTAssertEqual(handler.retryCalledCount, 1)
  701. XCTAssertEqual(handler.retryCount, 1)
  702. XCTAssertEqual(response?.result.isSuccess, true)
  703. assert(on: session.rootQueue) {
  704. XCTAssertTrue(session.requestTaskMap.isEmpty)
  705. XCTAssertTrue(session.activeRequests.isEmpty)
  706. }
  707. }
  708. func testThatSessionCallsRequestRetrierWhenDownloadInitiallyEncountersAdaptError() {
  709. // Given
  710. let handler = RequestHandler()
  711. handler.adaptedCount = 1
  712. handler.throwsErrorOnSecondAdapt = true
  713. handler.shouldApplyAuthorizationHeader = true
  714. let session = Session()
  715. let expectation = expectation(description: "request should eventually fail")
  716. var response: DownloadResponse<TestResponse, AFError>?
  717. let destination: DownloadRequest.Destination = { _, _ in
  718. let fileURL = self.testDirectoryURL.appendingPathComponent("test-output.json")
  719. return (fileURL, [.removePreviousFile])
  720. }
  721. // When
  722. session.download(.basicAuth(), interceptor: handler, to: destination)
  723. .validate()
  724. .responseDecodable(of: TestResponse.self) { jsonResponse in
  725. response = jsonResponse
  726. expectation.fulfill()
  727. }
  728. waitForExpectations(timeout: timeout)
  729. // Then
  730. XCTAssertEqual(handler.adaptCalledCount, 2)
  731. XCTAssertEqual(handler.adaptedCount, 2)
  732. XCTAssertEqual(handler.retryCalledCount, 1)
  733. XCTAssertEqual(handler.retryCount, 1)
  734. XCTAssertEqual(response?.result.isSuccess, true)
  735. assert(on: session.rootQueue) {
  736. XCTAssertTrue(session.requestTaskMap.isEmpty)
  737. XCTAssertTrue(session.activeRequests.isEmpty)
  738. }
  739. }
  740. func testThatSessionCallsRequestRetrierWhenUploadInitiallyEncountersAdaptError() {
  741. // Given
  742. let handler = UploadHandler()
  743. let session = Session(interceptor: handler)
  744. let expectation = expectation(description: "request should eventually fail")
  745. var response: DataResponse<TestResponse, AFError>?
  746. let uploadData = Data("upload data".utf8)
  747. // When
  748. session.upload(uploadData, to: .method(.post))
  749. .validate()
  750. .responseDecodable(of: TestResponse.self) { jsonResponse in
  751. response = jsonResponse
  752. expectation.fulfill()
  753. }
  754. waitForExpectations(timeout: timeout)
  755. // Then
  756. XCTAssertEqual(handler.adaptCalledCount, 2)
  757. XCTAssertEqual(handler.adaptedCount, 2)
  758. XCTAssertEqual(handler.retryCalledCount, 1)
  759. XCTAssertEqual(handler.retryCount, 1)
  760. XCTAssertEqual(response?.result.isSuccess, true)
  761. assert(on: session.rootQueue) {
  762. XCTAssertTrue(session.requestTaskMap.isEmpty)
  763. XCTAssertTrue(session.activeRequests.isEmpty)
  764. }
  765. }
  766. func testThatSessionCallsRequestRetrierWhenRequestEncountersError() {
  767. // Given
  768. let handler = RequestHandler()
  769. let session = Session()
  770. let expectation = expectation(description: "request should eventually fail")
  771. var response: DataResponse<TestResponse, AFError>?
  772. // When
  773. let request = session.request(.basicAuth(), interceptor: handler)
  774. .validate()
  775. .responseDecodable(of: TestResponse.self) { jsonResponse in
  776. response = jsonResponse
  777. expectation.fulfill()
  778. }
  779. waitForExpectations(timeout: timeout)
  780. // Then
  781. XCTAssertEqual(handler.adaptCalledCount, 2)
  782. XCTAssertEqual(handler.adaptedCount, 2)
  783. XCTAssertEqual(handler.retryCalledCount, 3)
  784. XCTAssertEqual(handler.retryCount, 3)
  785. XCTAssertEqual(request.retryCount, 1)
  786. XCTAssertEqual(response?.result.isSuccess, false)
  787. assert(on: session.rootQueue) {
  788. XCTAssertTrue(session.requestTaskMap.isEmpty)
  789. XCTAssertTrue(session.activeRequests.isEmpty)
  790. }
  791. }
  792. func testThatSessionCallsRequestRetrierThenSessionRetrierWhenRequestEncountersError() {
  793. // Given
  794. let sessionHandler = RequestHandler()
  795. let requestHandler = RequestHandler()
  796. let session = Session(interceptor: sessionHandler)
  797. let expectation = expectation(description: "request should eventually fail")
  798. var response: DataResponse<TestResponse, AFError>?
  799. // When
  800. let request = session.request(.basicAuth(), interceptor: requestHandler)
  801. .validate()
  802. .responseDecodable(of: TestResponse.self) { jsonResponse in
  803. response = jsonResponse
  804. expectation.fulfill()
  805. }
  806. waitForExpectations(timeout: timeout)
  807. // Then
  808. XCTAssertEqual(sessionHandler.adaptCalledCount, 3)
  809. XCTAssertEqual(sessionHandler.adaptedCount, 3)
  810. XCTAssertEqual(sessionHandler.retryCalledCount, 3)
  811. XCTAssertEqual(sessionHandler.retryCount, 3)
  812. XCTAssertEqual(requestHandler.adaptCalledCount, 3)
  813. XCTAssertEqual(requestHandler.adaptedCount, 3)
  814. XCTAssertEqual(requestHandler.retryCalledCount, 4)
  815. XCTAssertEqual(requestHandler.retryCount, 4)
  816. XCTAssertEqual(request.retryCount, 2)
  817. XCTAssertEqual(response?.result.isSuccess, false)
  818. assert(on: session.rootQueue) {
  819. XCTAssertTrue(session.requestTaskMap.isEmpty)
  820. XCTAssertTrue(session.activeRequests.isEmpty)
  821. }
  822. }
  823. func testThatSessionCallsAdapterWhenRequestIsRetried() {
  824. // Given
  825. let handler = RequestHandler()
  826. handler.shouldApplyAuthorizationHeader = true
  827. let session = Session(interceptor: handler)
  828. let expectation = expectation(description: "request should eventually succeed")
  829. var response: DataResponse<TestResponse, AFError>?
  830. // When
  831. let request = session.request(.basicAuth())
  832. .validate()
  833. .responseDecodable(of: TestResponse.self) { jsonResponse in
  834. response = jsonResponse
  835. expectation.fulfill()
  836. }
  837. waitForExpectations(timeout: timeout)
  838. // Then
  839. XCTAssertEqual(handler.adaptCalledCount, 2)
  840. XCTAssertEqual(handler.adaptedCount, 2)
  841. XCTAssertEqual(handler.retryCalledCount, 1)
  842. XCTAssertEqual(handler.retryCount, 1)
  843. XCTAssertEqual(request.retryCount, 1)
  844. XCTAssertEqual(response?.result.isSuccess, true)
  845. assert(on: session.rootQueue) {
  846. XCTAssertTrue(session.requestTaskMap.isEmpty)
  847. XCTAssertTrue(session.activeRequests.isEmpty)
  848. }
  849. }
  850. func testThatSessionReturnsRequestAdaptationErrorWhenRequestIsRetried() {
  851. // Given
  852. let handler = RequestHandler()
  853. handler.throwsErrorOnSecondAdapt = true
  854. let session = Session(interceptor: handler)
  855. let expectation = expectation(description: "request should eventually fail")
  856. var response: DataResponse<TestResponse, AFError>?
  857. // When
  858. let request = session.request(.basicAuth())
  859. .validate()
  860. .responseDecodable(of: TestResponse.self) { jsonResponse in
  861. response = jsonResponse
  862. expectation.fulfill()
  863. }
  864. waitForExpectations(timeout: timeout)
  865. // Then
  866. XCTAssertEqual(handler.adaptCalledCount, 2)
  867. XCTAssertEqual(handler.adaptedCount, 1)
  868. XCTAssertEqual(handler.retryCalledCount, 3)
  869. XCTAssertEqual(handler.retryCount, 3)
  870. XCTAssertEqual(request.retryCount, 1)
  871. XCTAssertEqual(response?.result.isSuccess, false)
  872. XCTAssertEqual(request.error?.isRequestAdaptationError, true)
  873. XCTAssertEqual(request.error?.underlyingError?.asAFError?.urlConvertible as? String, "/adapt/error/2")
  874. assert(on: session.rootQueue) {
  875. XCTAssertTrue(session.requestTaskMap.isEmpty)
  876. XCTAssertTrue(session.activeRequests.isEmpty)
  877. }
  878. }
  879. func testThatSessionRetriesRequestWithDelayWhenRetryResultContainsDelay() {
  880. // Given
  881. let handler = RequestHandler()
  882. handler.retryDelay = 0.01
  883. handler.throwsErrorOnSecondAdapt = true
  884. let session = Session(interceptor: handler)
  885. let expectation = expectation(description: "request should eventually fail")
  886. var response: DataResponse<TestResponse, AFError>?
  887. // When
  888. let request = session.request(.basicAuth())
  889. .validate()
  890. .responseDecodable(of: TestResponse.self) { jsonResponse in
  891. response = jsonResponse
  892. expectation.fulfill()
  893. }
  894. waitForExpectations(timeout: timeout)
  895. // Then
  896. XCTAssertEqual(handler.adaptCalledCount, 2)
  897. XCTAssertEqual(handler.adaptedCount, 1)
  898. XCTAssertEqual(handler.retryCalledCount, 3)
  899. XCTAssertEqual(handler.retryCount, 3)
  900. XCTAssertEqual(request.retryCount, 1)
  901. XCTAssertEqual(response?.result.isSuccess, false)
  902. XCTAssertEqual(request.error?.isRequestAdaptationError, true)
  903. XCTAssertEqual(request.error?.underlyingError?.asAFError?.urlConvertible as? String, "/adapt/error/2")
  904. assert(on: session.rootQueue) {
  905. XCTAssertTrue(session.requestTaskMap.isEmpty)
  906. XCTAssertTrue(session.activeRequests.isEmpty)
  907. }
  908. }
  909. func testThatSessionReturnsRequestRetryErrorWhenRequestRetrierThrowsError() {
  910. // Given
  911. let handler = RequestHandler()
  912. handler.throwsErrorOnRetry = true
  913. let session = Session(interceptor: handler)
  914. let expectation = expectation(description: "request should eventually fail")
  915. var response: DataResponse<TestResponse, AFError>?
  916. // When
  917. let request = session.request(.basicAuth())
  918. .validate()
  919. .responseDecodable(of: TestResponse.self) { jsonResponse in
  920. response = jsonResponse
  921. expectation.fulfill()
  922. }
  923. waitForExpectations(timeout: timeout)
  924. // Then
  925. XCTAssertEqual(handler.adaptCalledCount, 1)
  926. XCTAssertEqual(handler.adaptedCount, 1)
  927. XCTAssertEqual(handler.retryCalledCount, 2)
  928. XCTAssertEqual(handler.retryCount, 0)
  929. XCTAssertEqual(request.retryCount, 0)
  930. XCTAssertEqual(response?.result.isSuccess, false)
  931. assert(on: session.rootQueue) {
  932. XCTAssertTrue(session.requestTaskMap.isEmpty)
  933. XCTAssertTrue(session.activeRequests.isEmpty)
  934. }
  935. if let error = response?.result.failure {
  936. XCTAssertTrue(error.isRequestRetryError)
  937. XCTAssertEqual(error.underlyingError?.asAFError?.urlConvertible as? String, "/invalid/url/2")
  938. } else {
  939. XCTFail("error should not be nil")
  940. }
  941. }
  942. // MARK: Tests - Response Serializer Retry
  943. func testThatSessionCallsRequestRetrierWhenResponseSerializerThrowsError() {
  944. // Given
  945. let handler = RequestHandler()
  946. handler.shouldRetry = false
  947. let session = Session()
  948. let expectation = expectation(description: "request should eventually fail")
  949. var response: DataResponse<TestResponse, AFError>?
  950. // When
  951. let request = session.request(.image(.jpeg), interceptor: handler)
  952. .validate()
  953. .responseDecodable(of: TestResponse.self) { jsonResponse in
  954. response = jsonResponse
  955. expectation.fulfill()
  956. }
  957. waitForExpectations(timeout: timeout)
  958. // Then
  959. XCTAssertEqual(handler.adaptCalledCount, 1)
  960. XCTAssertEqual(handler.adaptedCount, 1)
  961. XCTAssertEqual(handler.retryCalledCount, 1)
  962. XCTAssertEqual(handler.retryCount, 0)
  963. XCTAssertEqual(request.retryCount, 0)
  964. XCTAssertEqual(response?.result.isSuccess, false)
  965. XCTAssertEqual(response?.error?.isResponseSerializationError, true)
  966. XCTAssertNotNil(response?.error?.underlyingError as? DecodingError)
  967. assert(on: session.rootQueue) {
  968. XCTAssertTrue(session.requestTaskMap.isEmpty)
  969. XCTAssertTrue(session.activeRequests.isEmpty)
  970. }
  971. }
  972. func testThatSessionCallsRequestRetrierForAllResponseSerializersThatThrowError() throws {
  973. // Given
  974. let handler = RequestHandler()
  975. handler.throwsErrorOnRetry = true
  976. let session = Session()
  977. let json1Expectation = expectation(description: "request should eventually fail")
  978. var json1Response: DataResponse<TestResponse, AFError>?
  979. let json2Expectation = expectation(description: "request should eventually fail")
  980. var json2Response: DataResponse<TestResponse, AFError>?
  981. // When
  982. let request = session.request(.image(.jpeg), interceptor: handler)
  983. .validate()
  984. .responseDecodable(of: TestResponse.self) { response in
  985. json1Response = response
  986. json1Expectation.fulfill()
  987. }
  988. .responseDecodable(of: TestResponse.self) { response in
  989. json2Response = response
  990. json2Expectation.fulfill()
  991. }
  992. waitForExpectations(timeout: timeout)
  993. // Then
  994. XCTAssertEqual(handler.adaptCalledCount, 1)
  995. XCTAssertEqual(handler.adaptedCount, 1)
  996. XCTAssertEqual(handler.retryCalledCount, 2)
  997. XCTAssertEqual(handler.retryCount, 0)
  998. XCTAssertEqual(request.retryCount, 0)
  999. XCTAssertEqual(json1Response?.result.isSuccess, false)
  1000. XCTAssertEqual(json2Response?.result.isSuccess, false)
  1001. assert(on: session.rootQueue) {
  1002. XCTAssertTrue(session.requestTaskMap.isEmpty)
  1003. XCTAssertTrue(session.activeRequests.isEmpty)
  1004. }
  1005. let errors = [json1Response, json2Response].compactMap { $0?.error }
  1006. XCTAssertEqual(errors.count, 2)
  1007. for (index, error) in errors.enumerated() {
  1008. XCTAssertTrue(error.isRequestRetryError)
  1009. if case let .requestRetryFailed(retryError, originalError) = error {
  1010. XCTAssertEqual(retryError.asAFError?.urlConvertible as? String, "/invalid/url/\(index + 1)")
  1011. XCTAssertNotNil(originalError.asAFError?.underlyingError as? DecodingError)
  1012. } else {
  1013. XCTFail("Error failure reason should be response serialization failure")
  1014. }
  1015. }
  1016. }
  1017. func testThatSessionRetriesRequestImmediatelyWhenResponseSerializerRequestsRetry() throws {
  1018. // Given
  1019. let handler = RequestHandler()
  1020. let session = Session()
  1021. let json1Expectation = expectation(description: "request should eventually fail")
  1022. var json1Response: DataResponse<TestResponse, AFError>?
  1023. let json2Expectation = expectation(description: "request should eventually fail")
  1024. var json2Response: DataResponse<TestResponse, AFError>?
  1025. // When
  1026. let request = session.request(.image(.jpeg), interceptor: handler)
  1027. .validate()
  1028. .responseDecodable(of: TestResponse.self) { response in
  1029. json1Response = response
  1030. json1Expectation.fulfill()
  1031. }
  1032. .responseDecodable(of: TestResponse.self) { response in
  1033. json2Response = response
  1034. json2Expectation.fulfill()
  1035. }
  1036. waitForExpectations(timeout: timeout)
  1037. // Then
  1038. XCTAssertEqual(handler.adaptCalledCount, 2)
  1039. XCTAssertEqual(handler.adaptedCount, 2)
  1040. XCTAssertEqual(handler.retryCalledCount, 3)
  1041. XCTAssertEqual(handler.retryCount, 3)
  1042. XCTAssertEqual(request.retryCount, 1)
  1043. XCTAssertEqual(json1Response?.result.isSuccess, false)
  1044. XCTAssertEqual(json2Response?.result.isSuccess, false)
  1045. assert(on: session.rootQueue) {
  1046. XCTAssertTrue(session.requestTaskMap.isEmpty)
  1047. XCTAssertTrue(session.activeRequests.isEmpty)
  1048. }
  1049. let errors = [json1Response, json2Response].compactMap { $0?.error }
  1050. XCTAssertEqual(errors.count, 2)
  1051. for error in errors {
  1052. XCTAssertTrue(error.isResponseSerializationError)
  1053. XCTAssertNotNil(error.underlyingError as? DecodingError)
  1054. }
  1055. }
  1056. func testThatSessionCallsResponseSerializerCompletionsWhenAdapterThrowsErrorDuringRetry() {
  1057. // Four retries should occur given this scenario:
  1058. // 1) Retrier is called from first response serializer failure (trips retry)
  1059. // 2) Retrier is called by Session for adapt error thrown
  1060. // 3) Retrier is called again from first response serializer failure
  1061. // 4) Retrier is called from second response serializer failure
  1062. // Given
  1063. let handler = RequestHandler()
  1064. handler.throwsErrorOnSecondAdapt = true
  1065. let session = Session()
  1066. let json1Expectation = expectation(description: "request should eventually fail")
  1067. var json1Response: DataResponse<TestResponse, AFError>?
  1068. let json2Expectation = expectation(description: "request should eventually fail")
  1069. var json2Response: DataResponse<TestResponse, AFError>?
  1070. // When
  1071. let request = session.request(.image(.jpeg), interceptor: handler)
  1072. .validate()
  1073. .responseDecodable(of: TestResponse.self) { response in
  1074. json1Response = response
  1075. json1Expectation.fulfill()
  1076. }
  1077. .responseDecodable(of: TestResponse.self) { response in
  1078. json2Response = response
  1079. json2Expectation.fulfill()
  1080. }
  1081. waitForExpectations(timeout: timeout)
  1082. // Then
  1083. XCTAssertEqual(handler.adaptCalledCount, 2)
  1084. XCTAssertEqual(handler.adaptedCount, 1)
  1085. XCTAssertEqual(handler.retryCalledCount, 4)
  1086. XCTAssertEqual(handler.retryCount, 4)
  1087. XCTAssertEqual(request.retryCount, 1)
  1088. XCTAssertEqual(json1Response?.result.isSuccess, false)
  1089. XCTAssertEqual(json2Response?.result.isSuccess, false)
  1090. assert(on: session.rootQueue) {
  1091. XCTAssertTrue(session.requestTaskMap.isEmpty)
  1092. XCTAssertTrue(session.activeRequests.isEmpty)
  1093. }
  1094. let errors = [json1Response, json2Response].compactMap { $0?.error }
  1095. XCTAssertEqual(errors.count, 2)
  1096. for error in errors {
  1097. XCTAssertTrue(error.isRequestAdaptationError)
  1098. XCTAssertEqual(error.underlyingError?.asAFError?.urlConvertible as? String, "/adapt/error/2")
  1099. }
  1100. }
  1101. func testThatSessionCallsResponseSerializerCompletionsWhenAdapterThrowsErrorDuringRetryForDownloads() {
  1102. // Four retries should occur given this scenario:
  1103. // 1) Retrier is called from first response serializer failure (trips retry)
  1104. // 2) Retrier is called by Session for adapt error thrown
  1105. // 3) Retrier is called again from first response serializer failure
  1106. // 4) Retrier is called from second response serializer failure
  1107. // Given
  1108. let handler = RequestHandler()
  1109. handler.throwsErrorOnSecondAdapt = true
  1110. let session = Session()
  1111. let json1Expectation = expectation(description: "request should eventually fail")
  1112. var json1Response: DownloadResponse<TestResponse, AFError>?
  1113. let json2Expectation = expectation(description: "request should eventually fail")
  1114. var json2Response: DownloadResponse<TestResponse, AFError>?
  1115. // When
  1116. let request = session.download(.image(.jpeg), interceptor: handler)
  1117. .validate()
  1118. .responseDecodable(of: TestResponse.self) { response in
  1119. json1Response = response
  1120. json1Expectation.fulfill()
  1121. }
  1122. .responseDecodable(of: TestResponse.self) { response in
  1123. json2Response = response
  1124. json2Expectation.fulfill()
  1125. }
  1126. waitForExpectations(timeout: timeout)
  1127. // Then
  1128. XCTAssertEqual(handler.adaptCalledCount, 2)
  1129. XCTAssertEqual(handler.adaptedCount, 1)
  1130. XCTAssertEqual(handler.retryCalledCount, 4)
  1131. XCTAssertEqual(handler.retryCount, 4)
  1132. XCTAssertEqual(request.retryCount, 1)
  1133. XCTAssertEqual(json1Response?.result.isSuccess, false)
  1134. XCTAssertEqual(json2Response?.result.isSuccess, false)
  1135. assert(on: session.rootQueue) {
  1136. XCTAssertTrue(session.requestTaskMap.isEmpty)
  1137. XCTAssertTrue(session.activeRequests.isEmpty)
  1138. }
  1139. let errors = [json1Response, json2Response].compactMap { $0?.error }
  1140. XCTAssertEqual(errors.count, 2)
  1141. for error in errors {
  1142. XCTAssertTrue(error.isRequestAdaptationError)
  1143. XCTAssertEqual(error.underlyingError?.asAFError?.urlConvertible as? String, "/adapt/error/2")
  1144. }
  1145. }
  1146. // MARK: Tests - Session Invalidation
  1147. func testThatSessionIsInvalidatedAndAllRequestsCompleteWhenSessionIsDeinitialized() {
  1148. // Given
  1149. let invalidationExpectation = expectation(description: "sessionDidBecomeInvalidWithError should be called")
  1150. let events = ClosureEventMonitor()
  1151. events.sessionDidBecomeInvalidWithError = { _, _ in
  1152. invalidationExpectation.fulfill()
  1153. }
  1154. var session: Session? = Session(startRequestsImmediately: false, eventMonitors: [events])
  1155. var error: AFError?
  1156. let requestExpectation = expectation(description: "request should complete")
  1157. // When
  1158. session?.request(.default).response { response in
  1159. error = response.error
  1160. requestExpectation.fulfill()
  1161. }
  1162. session = nil
  1163. waitForExpectations(timeout: timeout)
  1164. // Then
  1165. XCTAssertEqual(error?.isSessionDeinitializedError, true)
  1166. }
  1167. // MARK: Tests - Request Cancellation
  1168. func testThatSessionOnlyCallsResponseSerializerCompletionWhenCancellingInsideCompletion() {
  1169. // Given
  1170. let handler = RequestHandler()
  1171. let session = Session()
  1172. let expectation = expectation(description: "request should complete")
  1173. var response: DataResponse<TestResponse, AFError>?
  1174. var completionCallCount = 0
  1175. // When
  1176. let request = session.request(.default, interceptor: handler)
  1177. request.validate()
  1178. request.responseDecodable(of: TestResponse.self) { resp in
  1179. request.cancel()
  1180. response = resp
  1181. completionCallCount += 1
  1182. DispatchQueue.main.after(0.01) { expectation.fulfill() }
  1183. }
  1184. waitForExpectations(timeout: timeout)
  1185. // Then
  1186. XCTAssertEqual(handler.adaptCalledCount, 1)
  1187. XCTAssertEqual(handler.adaptedCount, 1)
  1188. XCTAssertEqual(handler.retryCalledCount, 0)
  1189. XCTAssertEqual(handler.retryCount, 0)
  1190. XCTAssertEqual(request.retryCount, 0)
  1191. XCTAssertEqual(response?.result.isSuccess, true)
  1192. XCTAssertEqual(completionCallCount, 1)
  1193. assert(on: session.rootQueue) {
  1194. XCTAssertTrue(session.requestTaskMap.isEmpty)
  1195. XCTAssertTrue(session.activeRequests.isEmpty)
  1196. }
  1197. }
  1198. // MARK: Tests - Request State
  1199. func testThatSessionSetsRequestStateWhenStartRequestsImmediatelyIsTrue() {
  1200. // Given
  1201. let session = Session()
  1202. let expectation = expectation(description: "request should complete")
  1203. var response: DataResponse<TestResponse, AFError>?
  1204. // When
  1205. let request = session.request(.default).responseDecodable(of: TestResponse.self) { resp in
  1206. response = resp
  1207. expectation.fulfill()
  1208. }
  1209. waitForExpectations(timeout: timeout)
  1210. // Then
  1211. XCTAssertEqual(request.state, .finished)
  1212. XCTAssertEqual(response?.result.isSuccess, true)
  1213. }
  1214. // MARK: Invalid Requests
  1215. func testThatGETRequestsWithBodyDataAreConsideredInvalid() {
  1216. // Given
  1217. let session = Session()
  1218. var request = Endpoint().urlRequest
  1219. request.httpBody = Data("invalid".utf8)
  1220. let expect = expectation(description: "request should complete")
  1221. var response: DataResponse<TestResponse, AFError>?
  1222. // When
  1223. session.request(request).responseDecodable(of: TestResponse.self) { resp in
  1224. response = resp
  1225. expect.fulfill()
  1226. }
  1227. waitForExpectations(timeout: timeout)
  1228. // Then
  1229. XCTAssertEqual(response?.result.isFailure, true)
  1230. XCTAssertEqual(response?.error?.isBodyDataInGETRequest, true)
  1231. }
  1232. func testThatAdaptedGETRequestsWithBodyDataAreConsideredInvalid() {
  1233. // Given
  1234. struct InvalidAdapter: RequestInterceptor {
  1235. func adapt(_ urlRequest: URLRequest,
  1236. for session: Session,
  1237. completion: @escaping (Result<URLRequest, Error>) -> Void) {
  1238. var request = urlRequest
  1239. request.httpBody = Data("invalid".utf8)
  1240. completion(.success(request))
  1241. }
  1242. }
  1243. let session = Session(interceptor: InvalidAdapter())
  1244. let expect = expectation(description: "request should complete")
  1245. var response: DataResponse<TestResponse, AFError>?
  1246. // When
  1247. session.request(.default).responseDecodable(of: TestResponse.self) { resp in
  1248. response = resp
  1249. expect.fulfill()
  1250. }
  1251. waitForExpectations(timeout: timeout)
  1252. // Then
  1253. XCTAssertEqual(response?.result.isFailure, true)
  1254. XCTAssertEqual(response?.error?.isRequestAdaptationError, true)
  1255. XCTAssertEqual(response?.error?.underlyingError?.asAFError?.isBodyDataInGETRequest, true)
  1256. }
  1257. }
  1258. // MARK: -
  1259. final class SessionMassActionTestCase: BaseTestCase {
  1260. func testThatRequestsCanHaveMassActionsPerformed() {
  1261. // Given
  1262. let count = 10
  1263. let createdTasks = expectation(description: "all tasks created")
  1264. createdTasks.expectedFulfillmentCount = count
  1265. let massActions = expectation(description: "cancel all requests should be called")
  1266. let monitor = ClosureEventMonitor()
  1267. monitor.requestDidCreateTask = { _, _ in createdTasks.fulfill() }
  1268. let session = Session(eventMonitors: [monitor])
  1269. let request = Endpoint.delay(1)
  1270. var requests: [DataRequest] = []
  1271. // When
  1272. requests = (0..<count).map { _ in session.request(request) }
  1273. wait(for: [createdTasks], timeout: timeout)
  1274. session.withAllRequests { $0.forEach { $0.suspend() }; massActions.fulfill() }
  1275. wait(for: [massActions], timeout: timeout)
  1276. // Then
  1277. XCTAssertTrue(requests.allSatisfy(\.isSuspended))
  1278. }
  1279. func testThatAutomaticallyResumedRequestsCanBeMassCancelled() {
  1280. // Given
  1281. let count = 100
  1282. let completion = expectation(description: "all requests should finish")
  1283. completion.expectedFulfillmentCount = count
  1284. let createdTasks = expectation(description: "all tasks created")
  1285. createdTasks.expectedFulfillmentCount = count
  1286. let gatheredMetrics = expectation(description: "metrics gathered for all tasks")
  1287. gatheredMetrics.expectedFulfillmentCount = count
  1288. let cancellation = expectation(description: "cancel all requests should be called")
  1289. let monitor = ClosureEventMonitor()
  1290. monitor.requestDidCreateTask = { _, _ in createdTasks.fulfill() }
  1291. monitor.requestDidGatherMetrics = { _, _ in gatheredMetrics.fulfill() }
  1292. let session = Session(eventMonitors: [monitor])
  1293. let request = Endpoint.delay(1)
  1294. var requests: [DataRequest] = []
  1295. var responses: [DataResponse<Data?, AFError>] = []
  1296. // When
  1297. requests = (0..<count).map { _ in session.request(request) }
  1298. wait(for: [createdTasks], timeout: timeout)
  1299. for request in requests {
  1300. request.response { response in
  1301. responses.append(response)
  1302. completion.fulfill()
  1303. }
  1304. }
  1305. session.cancelAllRequests {
  1306. cancellation.fulfill()
  1307. }
  1308. wait(for: [gatheredMetrics, cancellation, completion], timeout: timeout)
  1309. // Then
  1310. XCTAssertTrue(responses.allSatisfy { $0.error?.isExplicitlyCancelledError == true })
  1311. assert(on: session.rootQueue) {
  1312. XCTAssertTrue(session.requestTaskMap.isEmpty, "requestTaskMap should be empty but has \(session.requestTaskMap.count) items")
  1313. XCTAssertTrue(session.activeRequests.isEmpty, "activeRequests should be empty but has \(session.activeRequests.count) items")
  1314. }
  1315. }
  1316. func testThatManuallyResumedRequestsCanBeMassCancelled() {
  1317. // Given
  1318. let count = 100
  1319. let completion = expectation(description: "all requests should finish")
  1320. completion.expectedFulfillmentCount = count
  1321. let createdTasks = expectation(description: "all tasks created")
  1322. createdTasks.expectedFulfillmentCount = count
  1323. let gatheredMetrics = expectation(description: "metrics gathered for all tasks")
  1324. gatheredMetrics.expectedFulfillmentCount = count
  1325. let cancellation = expectation(description: "cancel all requests should be called")
  1326. let monitor = ClosureEventMonitor()
  1327. monitor.requestDidCreateTask = { _, _ in createdTasks.fulfill() }
  1328. monitor.requestDidGatherMetrics = { _, _ in gatheredMetrics.fulfill() }
  1329. let session = Session(startRequestsImmediately: false, eventMonitors: [monitor])
  1330. let request = Endpoint.delay(1)
  1331. var responses: [DataResponse<Data?, AFError>] = []
  1332. // When
  1333. for _ in 0..<count {
  1334. session.request(request).response { response in
  1335. responses.append(response)
  1336. completion.fulfill()
  1337. }
  1338. }
  1339. wait(for: [createdTasks], timeout: timeout)
  1340. session.cancelAllRequests {
  1341. cancellation.fulfill()
  1342. }
  1343. wait(for: [gatheredMetrics, cancellation, completion], timeout: timeout)
  1344. // Then
  1345. XCTAssertTrue(responses.allSatisfy { $0.error?.isExplicitlyCancelledError == true })
  1346. assert(on: session.rootQueue) {
  1347. XCTAssertTrue(session.requestTaskMap.isEmpty, "requestTaskMap should be empty but has \(session.requestTaskMap.count) items")
  1348. XCTAssertTrue(session.activeRequests.isEmpty, "activeRequests should be empty but has \(session.activeRequests.count) items")
  1349. }
  1350. }
  1351. func testThatRetriedRequestsCanBeMassCancelled() {
  1352. // Given
  1353. final class OnceRetrier: RequestInterceptor {
  1354. private var hasRetried = false
  1355. func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  1356. if hasRetried {
  1357. var request = urlRequest
  1358. request.url = Endpoint.delay(1).url
  1359. completion(.success(request))
  1360. } else {
  1361. completion(.success(urlRequest))
  1362. }
  1363. }
  1364. func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
  1365. completion(hasRetried ? .doNotRetry : .retry)
  1366. hasRetried = true
  1367. }
  1368. }
  1369. let queue = DispatchQueue(label: "com.alamofire.testQueue")
  1370. let monitor = ClosureEventMonitor(queue: queue)
  1371. let session = Session(rootQueue: queue, interceptor: OnceRetrier(), eventMonitors: [monitor])
  1372. let request = Endpoint.status(401)
  1373. let completion = expectation(description: "all requests should finish")
  1374. let cancellation = expectation(description: "cancel all requests should be called")
  1375. let createTask = expectation(description: "should create task twice")
  1376. createTask.expectedFulfillmentCount = 2
  1377. var tasksCreated = 0
  1378. monitor.requestDidCreateTask = { [unowned session] _, _ in
  1379. tasksCreated += 1
  1380. createTask.fulfill()
  1381. // Cancel after the second task is created to ensure proper lifetime events.
  1382. if tasksCreated == 2 {
  1383. session.cancelAllRequests {
  1384. cancellation.fulfill()
  1385. }
  1386. }
  1387. }
  1388. var received: DataResponse<Data?, AFError>?
  1389. // When
  1390. session.request(request).validate().response { response in
  1391. received = response
  1392. completion.fulfill()
  1393. }
  1394. waitForExpectations(timeout: timeout)
  1395. // Then
  1396. XCTAssertEqual(received?.error?.isExplicitlyCancelledError, true)
  1397. assert(on: session.rootQueue) {
  1398. XCTAssertTrue(session.requestTaskMap.isEmpty, "requestTaskMap should be empty but has \(session.requestTaskMap.count) items")
  1399. XCTAssertTrue(session.activeRequests.isEmpty, "activeRequests should be empty but has \(session.activeRequests.count) items")
  1400. }
  1401. }
  1402. }
  1403. // MARK: -
  1404. final class SessionConfigurationHeadersTestCase: BaseTestCase {
  1405. enum ConfigurationType {
  1406. case `default`, ephemeral
  1407. }
  1408. func testThatDefaultConfigurationHeadersAreSentWithRequest() {
  1409. // Given, When, Then
  1410. executeAuthorizationHeaderTest(for: .default)
  1411. }
  1412. func testThatEphemeralConfigurationHeadersAreSentWithRequest() {
  1413. // Given, When, Then
  1414. executeAuthorizationHeaderTest(for: .ephemeral)
  1415. }
  1416. private func executeAuthorizationHeaderTest(for type: ConfigurationType) {
  1417. // Given
  1418. let session: Session = {
  1419. let configuration: URLSessionConfiguration = {
  1420. let configuration: URLSessionConfiguration
  1421. switch type {
  1422. case .default:
  1423. configuration = .default
  1424. case .ephemeral:
  1425. configuration = .ephemeral
  1426. }
  1427. var headers = HTTPHeaders.default
  1428. headers["Authorization"] = "Bearer 123456"
  1429. configuration.headers = headers
  1430. return configuration
  1431. }()
  1432. return Session(configuration: configuration)
  1433. }()
  1434. let expectation = expectation(description: "request should complete successfully")
  1435. var response: DataResponse<TestResponse, AFError>?
  1436. // When
  1437. session.request(.default)
  1438. .responseDecodable(of: TestResponse.self) { closureResponse in
  1439. response = closureResponse
  1440. expectation.fulfill()
  1441. }
  1442. waitForExpectations(timeout: timeout)
  1443. // Then
  1444. XCTAssertNotNil(response?.request, "request should not be nil")
  1445. XCTAssertNotNil(response?.response, "response should not be nil")
  1446. XCTAssertNotNil(response?.data, "data should not be nil")
  1447. XCTAssertEqual(response?.result.isSuccess, true)
  1448. XCTAssertEqual(response?.value?.headers["Authorization"], "Bearer 123456", "Authorization header should match")
  1449. }
  1450. }