ResponseTests.swift 21 KB

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