ResponseTests.swift 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. //
  2. // ResponseTests.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. import Alamofire
  25. import Foundation
  26. import XCTest
  27. final class ResponseTestCase: BaseTestCase {
  28. func testThatResponseReturnsSuccessResultWithValidData() {
  29. // Given
  30. let urlString = "https://httpbin.org/get"
  31. let expectation = self.expectation(description: "request should succeed")
  32. var response: DataResponse<Data?, AFError>?
  33. // When
  34. AF.request(urlString, parameters: ["foo": "bar"]).response { resp in
  35. response = resp
  36. expectation.fulfill()
  37. }
  38. waitForExpectations(timeout: timeout, handler: nil)
  39. // Then
  40. XCTAssertNotNil(response?.request)
  41. XCTAssertNotNil(response?.response)
  42. XCTAssertNotNil(response?.data)
  43. XCTAssertNil(response?.error)
  44. XCTAssertNotNil(response?.metrics)
  45. }
  46. func testThatResponseReturnsFailureResultWithOptionalDataAndError() {
  47. // Given
  48. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  49. let expectation = self.expectation(description: "request should fail with invalid hostname error")
  50. var response: DataResponse<Data?, AFError>?
  51. // When
  52. AF.request(urlString, parameters: ["foo": "bar"]).response { resp in
  53. response = resp
  54. expectation.fulfill()
  55. }
  56. waitForExpectations(timeout: timeout, handler: nil)
  57. // Then
  58. XCTAssertNotNil(response?.request)
  59. XCTAssertNil(response?.response)
  60. XCTAssertNil(response?.data)
  61. XCTAssertNotNil(response?.error)
  62. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  63. XCTAssertEqual(response?.error?.isHostURLError, true)
  64. XCTAssertNotNil(response?.metrics)
  65. }
  66. }
  67. // MARK: -
  68. final class ResponseDataTestCase: BaseTestCase {
  69. func testThatResponseDataReturnsSuccessResultWithValidData() {
  70. // Given
  71. let urlString = "https://httpbin.org/get"
  72. let expectation = self.expectation(description: "request should succeed")
  73. var response: DataResponse<Data, AFError>?
  74. // When
  75. AF.request(urlString, parameters: ["foo": "bar"]).responseData { resp in
  76. response = resp
  77. expectation.fulfill()
  78. }
  79. waitForExpectations(timeout: timeout, handler: nil)
  80. // Then
  81. XCTAssertNotNil(response?.request)
  82. XCTAssertNotNil(response?.response)
  83. XCTAssertNotNil(response?.data)
  84. XCTAssertNotNil(response?.data)
  85. XCTAssertEqual(response?.result.isSuccess, true)
  86. XCTAssertNotNil(response?.metrics)
  87. }
  88. func testThatResponseDataReturnsFailureResultWithOptionalDataAndError() {
  89. // Given
  90. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  91. let expectation = self.expectation(description: "request should fail with 404")
  92. var response: DataResponse<Data, AFError>?
  93. // When
  94. AF.request(urlString, parameters: ["foo": "bar"]).responseData { resp in
  95. response = resp
  96. expectation.fulfill()
  97. }
  98. waitForExpectations(timeout: timeout, handler: nil)
  99. // Then
  100. XCTAssertNotNil(response?.request)
  101. XCTAssertNil(response?.response)
  102. XCTAssertNil(response?.data)
  103. XCTAssertEqual(response?.result.isFailure, true)
  104. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  105. XCTAssertEqual(response?.error?.isHostURLError, true)
  106. XCTAssertNotNil(response?.metrics)
  107. }
  108. }
  109. // MARK: -
  110. final class ResponseStringTestCase: BaseTestCase {
  111. func testThatResponseStringReturnsSuccessResultWithValidString() {
  112. // Given
  113. let urlString = "https://httpbin.org/get"
  114. let expectation = self.expectation(description: "request should succeed")
  115. var response: DataResponse<String, AFError>?
  116. // When
  117. AF.request(urlString, parameters: ["foo": "bar"]).responseString { resp in
  118. response = resp
  119. expectation.fulfill()
  120. }
  121. waitForExpectations(timeout: timeout, handler: nil)
  122. // Then
  123. XCTAssertNotNil(response?.request)
  124. XCTAssertNotNil(response?.response)
  125. XCTAssertNotNil(response?.data)
  126. XCTAssertNotNil(response?.data)
  127. XCTAssertEqual(response?.result.isSuccess, true)
  128. XCTAssertNotNil(response?.metrics)
  129. }
  130. func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
  131. // Given
  132. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  133. let expectation = self.expectation(description: "request should fail with 404")
  134. var response: DataResponse<String, AFError>?
  135. // When
  136. AF.request(urlString, parameters: ["foo": "bar"]).responseString { resp in
  137. response = resp
  138. expectation.fulfill()
  139. }
  140. waitForExpectations(timeout: timeout, handler: nil)
  141. // Then
  142. XCTAssertNotNil(response?.request)
  143. XCTAssertNil(response?.response)
  144. XCTAssertNil(response?.data)
  145. XCTAssertEqual(response?.result.isFailure, true)
  146. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  147. XCTAssertEqual(response?.error?.isHostURLError, true)
  148. XCTAssertNotNil(response?.metrics)
  149. }
  150. }
  151. // MARK: -
  152. final class ResponseJSONTestCase: BaseTestCase {
  153. func testThatResponseJSONReturnsSuccessResultWithValidJSON() {
  154. // Given
  155. let urlString = "https://httpbin.org/get"
  156. let expectation = self.expectation(description: "request should succeed")
  157. var response: DataResponse<Any, AFError>?
  158. // When
  159. AF.request(urlString, parameters: ["foo": "bar"]).responseJSON { resp in
  160. response = resp
  161. expectation.fulfill()
  162. }
  163. waitForExpectations(timeout: timeout, handler: nil)
  164. // Then
  165. XCTAssertNotNil(response?.request)
  166. XCTAssertNotNil(response?.response)
  167. XCTAssertNotNil(response?.data)
  168. XCTAssertNotNil(response?.data)
  169. XCTAssertEqual(response?.result.isSuccess, true)
  170. XCTAssertNotNil(response?.metrics)
  171. }
  172. func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
  173. // Given
  174. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  175. let expectation = self.expectation(description: "request should fail")
  176. var response: DataResponse<Any, AFError>?
  177. // When
  178. AF.request(urlString, parameters: ["foo": "bar"]).responseJSON { resp in
  179. response = resp
  180. expectation.fulfill()
  181. }
  182. waitForExpectations(timeout: timeout, handler: nil)
  183. // Then
  184. XCTAssertNotNil(response?.request)
  185. XCTAssertNil(response?.response)
  186. XCTAssertNil(response?.data)
  187. XCTAssertEqual(response?.result.isFailure, true)
  188. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  189. XCTAssertEqual(response?.error?.isHostURLError, true)
  190. XCTAssertNotNil(response?.metrics)
  191. }
  192. func testThatResponseJSONReturnsSuccessResultForGETRequest() {
  193. // Given
  194. let urlString = "https://httpbin.org/get"
  195. let expectation = self.expectation(description: "request should succeed")
  196. var response: DataResponse<Any, AFError>?
  197. // When
  198. AF.request(urlString, parameters: ["foo": "bar"]).responseJSON { resp in
  199. response = resp
  200. expectation.fulfill()
  201. }
  202. waitForExpectations(timeout: timeout, handler: nil)
  203. // Then
  204. XCTAssertNotNil(response?.request)
  205. XCTAssertNotNil(response?.response)
  206. XCTAssertNotNil(response?.data)
  207. XCTAssertNotNil(response?.data)
  208. XCTAssertEqual(response?.result.isSuccess, true)
  209. XCTAssertNotNil(response?.metrics)
  210. if
  211. let responseDictionary = response?.result.success as? [String: Any],
  212. let args = responseDictionary["args"] as? [String: String] {
  213. XCTAssertEqual(args, ["foo": "bar"], "args should match parameters")
  214. } else {
  215. XCTFail("args should not be nil")
  216. }
  217. }
  218. func testThatResponseJSONReturnsSuccessResultForPOSTRequest() {
  219. // Given
  220. let urlString = "https://httpbin.org/post"
  221. let expectation = self.expectation(description: "request should succeed")
  222. var response: DataResponse<Any, AFError>?
  223. // When
  224. AF.request(urlString, method: .post, parameters: ["foo": "bar"]).responseJSON { resp in
  225. response = resp
  226. expectation.fulfill()
  227. }
  228. waitForExpectations(timeout: timeout, handler: nil)
  229. // Then
  230. XCTAssertNotNil(response?.request)
  231. XCTAssertNotNil(response?.response)
  232. XCTAssertNotNil(response?.data)
  233. XCTAssertNotNil(response?.data)
  234. XCTAssertEqual(response?.result.isSuccess, true)
  235. XCTAssertNotNil(response?.metrics)
  236. if
  237. let responseDictionary = response?.result.success as? [String: Any],
  238. let form = responseDictionary["form"] as? [String: String] {
  239. XCTAssertEqual(form, ["foo": "bar"], "form should match parameters")
  240. } else {
  241. XCTFail("form should not be nil")
  242. }
  243. }
  244. }
  245. final class ResponseJSONDecodableTestCase: BaseTestCase {
  246. func testThatResponseDecodableReturnsSuccessResultWithValidJSON() {
  247. // Given
  248. let urlString = "https://httpbin.org/get"
  249. let expectation = self.expectation(description: "request should succeed")
  250. var response: DataResponse<HTTPBinResponse, AFError>?
  251. // When
  252. AF.request(urlString, parameters: [:]).responseDecodable(of: HTTPBinResponse.self) { resp in
  253. response = resp
  254. expectation.fulfill()
  255. }
  256. waitForExpectations(timeout: timeout, handler: nil)
  257. // Then
  258. XCTAssertNotNil(response?.request)
  259. XCTAssertNotNil(response?.response)
  260. XCTAssertNotNil(response?.data)
  261. XCTAssertEqual(response?.result.isSuccess, true)
  262. XCTAssertEqual(response?.result.success?.url, "https://httpbin.org/get")
  263. XCTAssertNotNil(response?.metrics)
  264. }
  265. func testThatResponseDecodableWithPassedTypeReturnsSuccessResultWithValidJSON() {
  266. // Given
  267. let urlString = "https://httpbin.org/get"
  268. let expectation = self.expectation(description: "request should succeed")
  269. var response: DataResponse<HTTPBinResponse, AFError>?
  270. // When
  271. AF.request(urlString, parameters: [:]).responseDecodable(of: HTTPBinResponse.self) {
  272. response = $0
  273. expectation.fulfill()
  274. }
  275. waitForExpectations(timeout: timeout, handler: nil)
  276. // Then
  277. XCTAssertNotNil(response?.request)
  278. XCTAssertNotNil(response?.response)
  279. XCTAssertNotNil(response?.data)
  280. XCTAssertEqual(response?.result.isSuccess, true)
  281. XCTAssertEqual(response?.result.success?.url, "https://httpbin.org/get")
  282. XCTAssertNotNil(response?.metrics)
  283. }
  284. func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
  285. // Given
  286. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  287. let expectation = self.expectation(description: "request should fail")
  288. var response: DataResponse<HTTPBinResponse, AFError>?
  289. // When
  290. AF.request(urlString, parameters: [:]).responseDecodable(of: HTTPBinResponse.self) { resp in
  291. response = resp
  292. expectation.fulfill()
  293. }
  294. waitForExpectations(timeout: timeout, handler: nil)
  295. // Then
  296. XCTAssertNotNil(response?.request)
  297. XCTAssertNil(response?.response)
  298. XCTAssertNil(response?.data)
  299. XCTAssertEqual(response?.result.isFailure, true)
  300. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  301. XCTAssertEqual(response?.error?.isHostURLError, true)
  302. XCTAssertNotNil(response?.metrics)
  303. }
  304. }
  305. // MARK: -
  306. final class ResponseMapTestCase: BaseTestCase {
  307. func testThatMapTransformsSuccessValue() {
  308. // Given
  309. let urlString = "https://httpbin.org/get"
  310. let expectation = self.expectation(description: "request should succeed")
  311. var response: DataResponse<String, AFError>?
  312. // When
  313. AF.request(urlString, parameters: ["foo": "bar"]).responseJSON { resp in
  314. response = resp.map { json in
  315. // json["args"]["foo"] is "bar": use this invariant to test the map function
  316. ((json as? [String: Any])?["args"] as? [String: Any])?["foo"] as? String ?? "invalid"
  317. }
  318. expectation.fulfill()
  319. }
  320. waitForExpectations(timeout: timeout, handler: nil)
  321. // Then
  322. XCTAssertNotNil(response?.request)
  323. XCTAssertNotNil(response?.response)
  324. XCTAssertNotNil(response?.data)
  325. XCTAssertEqual(response?.result.isSuccess, true)
  326. XCTAssertEqual(response?.result.success, "bar")
  327. XCTAssertNotNil(response?.metrics)
  328. }
  329. func testThatMapPreservesFailureError() {
  330. // Given
  331. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  332. let expectation = self.expectation(description: "request should fail with 404")
  333. var response: DataResponse<String, AFError>?
  334. // When
  335. AF.request(urlString, parameters: ["foo": "bar"]).responseData { resp in
  336. response = resp.map { _ in "ignored" }
  337. expectation.fulfill()
  338. }
  339. waitForExpectations(timeout: timeout, handler: nil)
  340. // Then
  341. XCTAssertNotNil(response?.request)
  342. XCTAssertNil(response?.response)
  343. XCTAssertNil(response?.data)
  344. XCTAssertEqual(response?.result.isFailure, true)
  345. XCTAssertEqual(response?.error?.isSessionTaskError, true)
  346. XCTAssertEqual(response?.error?.isHostURLError, true)
  347. XCTAssertNotNil(response?.metrics)
  348. }
  349. }
  350. // MARK: -
  351. final class ResponseTryMapTestCase: BaseTestCase {
  352. func testThatTryMapTransformsSuccessValue() {
  353. // Given
  354. let urlString = "https://httpbin.org/get"
  355. let expectation = self.expectation(description: "request should succeed")
  356. var response: DataResponse<String, Error>?
  357. // When
  358. AF.request(urlString, parameters: ["foo": "bar"]).responseJSON { resp in
  359. response = resp.tryMap { json in
  360. // json["args"]["foo"] is "bar": use this invariant to test the tryMap function
  361. ((json as? [String: Any])?["args"] as? [String: Any])?["foo"] as? String ?? "invalid"
  362. }
  363. expectation.fulfill()
  364. }
  365. waitForExpectations(timeout: timeout, handler: nil)
  366. // Then
  367. XCTAssertNotNil(response?.request)
  368. XCTAssertNotNil(response?.response)
  369. XCTAssertNotNil(response?.data)
  370. XCTAssertEqual(response?.result.isSuccess, true)
  371. XCTAssertEqual(response?.result.success, "bar")
  372. XCTAssertNotNil(response?.metrics)
  373. }
  374. func testThatTryMapCatchesTransformationError() {
  375. // Given
  376. struct TransformError: Error {}
  377. let urlString = "https://httpbin.org/get"
  378. let expectation = self.expectation(description: "request should succeed")
  379. var response: DataResponse<String, Error>?
  380. // When
  381. AF.request(urlString, parameters: ["foo": "bar"]).responseData { resp in
  382. response = resp.tryMap { _ in
  383. throw TransformError()
  384. }
  385. expectation.fulfill()
  386. }
  387. waitForExpectations(timeout: timeout, handler: nil)
  388. // Then
  389. XCTAssertNotNil(response?.request)
  390. XCTAssertNotNil(response?.response)
  391. XCTAssertNotNil(response?.data)
  392. XCTAssertEqual(response?.result.isFailure, true)
  393. if let error = response?.result.failure {
  394. XCTAssertTrue(error is TransformError)
  395. } else {
  396. XCTFail("tryMap should catch the transformation error")
  397. }
  398. XCTAssertNotNil(response?.metrics)
  399. }
  400. func testThatTryMapPreservesFailureError() {
  401. // Given
  402. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  403. let expectation = self.expectation(description: "request should fail with 404")
  404. var response: DataResponse<String, Error>?
  405. // When
  406. AF.request(urlString, parameters: ["foo": "bar"]).responseData { resp in
  407. response = resp.tryMap { _ in "ignored" }
  408. expectation.fulfill()
  409. }
  410. waitForExpectations(timeout: timeout, handler: nil)
  411. // Then
  412. XCTAssertNotNil(response?.request)
  413. XCTAssertNil(response?.response)
  414. XCTAssertNil(response?.data)
  415. XCTAssertEqual(response?.result.isFailure, true)
  416. XCTAssertEqual(response?.error?.asAFError?.isSessionTaskError, true)
  417. XCTAssertEqual(response?.error?.asAFError?.isHostURLError, true)
  418. XCTAssertNotNil(response?.metrics)
  419. }
  420. }
  421. // MARK: -
  422. enum TestError: Error {
  423. case error(error: AFError)
  424. }
  425. enum TransformationError: Error {
  426. case error
  427. func alwaysFails() throws -> TestError {
  428. throw TransformationError.error
  429. }
  430. }
  431. final class ResponseMapErrorTestCase: BaseTestCase {
  432. func testThatMapErrorTransformsFailureValue() {
  433. // Given
  434. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  435. let expectation = self.expectation(description: "request should not succeed")
  436. var response: DataResponse<Any, TestError>?
  437. // When
  438. AF.request(urlString).responseJSON { resp in
  439. response = resp.mapError { error in
  440. TestError.error(error: error)
  441. }
  442. expectation.fulfill()
  443. }
  444. waitForExpectations(timeout: timeout, handler: nil)
  445. // Then
  446. XCTAssertNotNil(response?.request)
  447. XCTAssertNil(response?.response)
  448. XCTAssertNil(response?.data)
  449. XCTAssertEqual(response?.result.isFailure, true)
  450. guard let error = response?.error, case .error = error else { XCTFail(); return }
  451. XCTAssertNotNil(response?.metrics)
  452. }
  453. func testThatMapErrorPreservesSuccessValue() {
  454. // Given
  455. let urlString = "https://httpbin.org/get"
  456. let expectation = self.expectation(description: "request should succeed")
  457. var response: DataResponse<Data, TestError>?
  458. // When
  459. AF.request(urlString).responseData { resp in
  460. response = resp.mapError { TestError.error(error: $0) }
  461. expectation.fulfill()
  462. }
  463. waitForExpectations(timeout: timeout, handler: nil)
  464. // Then
  465. XCTAssertNotNil(response?.request)
  466. XCTAssertNotNil(response?.response)
  467. XCTAssertNotNil(response?.data)
  468. XCTAssertEqual(response?.result.isSuccess, true)
  469. XCTAssertNotNil(response?.metrics)
  470. }
  471. }
  472. // MARK: -
  473. final class ResponseTryMapErrorTestCase: BaseTestCase {
  474. func testThatTryMapErrorPreservesSuccessValue() {
  475. // Given
  476. let urlString = "https://httpbin.org/get"
  477. let expectation = self.expectation(description: "request should succeed")
  478. var response: DataResponse<Data, Error>?
  479. // When
  480. AF.request(urlString).responseData { resp in
  481. response = resp.tryMapError { TestError.error(error: $0) }
  482. expectation.fulfill()
  483. }
  484. waitForExpectations(timeout: timeout, handler: nil)
  485. // Then
  486. XCTAssertNotNil(response?.request)
  487. XCTAssertNotNil(response?.response)
  488. XCTAssertNotNil(response?.data)
  489. XCTAssertEqual(response?.result.isSuccess, true)
  490. XCTAssertNotNil(response?.metrics)
  491. }
  492. func testThatTryMapErrorCatchesTransformationError() {
  493. // Given
  494. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  495. let expectation = self.expectation(description: "request should fail")
  496. var response: DataResponse<Data, Error>?
  497. // When
  498. AF.request(urlString).responseData { resp in
  499. response = resp.tryMapError { _ in try TransformationError.error.alwaysFails() }
  500. expectation.fulfill()
  501. }
  502. waitForExpectations(timeout: timeout, handler: nil)
  503. // Then
  504. XCTAssertNotNil(response?.request)
  505. XCTAssertNil(response?.response)
  506. XCTAssertNil(response?.data)
  507. XCTAssertEqual(response?.result.isFailure, true)
  508. if let error = response?.result.failure {
  509. XCTAssertTrue(error is TransformationError)
  510. } else {
  511. XCTFail("tryMapError should catch the transformation error")
  512. }
  513. XCTAssertNotNil(response?.metrics)
  514. }
  515. func testThatTryMapErrorTransformsError() {
  516. // Given
  517. let urlString = "https://invalid-url-here.org/this/does/not/exist"
  518. let expectation = self.expectation(description: "request should fail")
  519. var response: DataResponse<Data, Error>?
  520. // When
  521. AF.request(urlString).responseData { resp in
  522. response = resp.tryMapError { TestError.error(error: $0) }
  523. expectation.fulfill()
  524. }
  525. waitForExpectations(timeout: timeout, handler: nil)
  526. // Then
  527. XCTAssertNotNil(response?.request)
  528. XCTAssertNil(response?.response)
  529. XCTAssertNil(response?.data)
  530. XCTAssertEqual(response?.result.isFailure, true)
  531. guard let error = response?.error as? TestError,
  532. case let .error(underlyingError) = error
  533. else { XCTFail(); return }
  534. XCTAssertEqual(underlyingError.asAFError?.isSessionTaskError, true)
  535. XCTAssertEqual(underlyingError.asAFError?.isHostURLError, true)
  536. XCTAssertNotNil(response?.metrics)
  537. }
  538. }