ResponseTests.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. // ResponseTests.swift
  2. //
  3. // Copyright (c) 2014–2016 Alamofire Software Foundation (http://alamofire.org/)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. import Alamofire
  23. import Foundation
  24. import XCTest
  25. class ResponseDataTestCase: BaseTestCase {
  26. func testThatResponseDataReturnsSuccessResultWithValidData() {
  27. // Given
  28. let URLString = "https://httpbin.org/get"
  29. let expectation = expectationWithDescription("request should succeed")
  30. var response: Response<NSData, NSError>?
  31. // When
  32. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  33. .responseData { closureResponse in
  34. response = closureResponse
  35. expectation.fulfill()
  36. }
  37. waitForExpectationsWithTimeout(timeout, handler: nil)
  38. // Then
  39. if let response = response {
  40. XCTAssertNotNil(response.request, "request should not be nil")
  41. XCTAssertNotNil(response.response, "response should not be nil")
  42. XCTAssertNotNil(response.data, "data should not be nil")
  43. XCTAssertTrue(response.result.isSuccess, "result should be success")
  44. } else {
  45. XCTFail("response should not be nil")
  46. }
  47. }
  48. func testThatResponseDataReturnsFailureResultWithOptionalDataAndError() {
  49. // Given
  50. let URLString = "https://invalid-url-here.org/this/does/not/exist"
  51. let expectation = expectationWithDescription("request should fail with 404")
  52. var response: Response<NSData, NSError>?
  53. // When
  54. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  55. .responseData { closureResponse in
  56. response = closureResponse
  57. expectation.fulfill()
  58. }
  59. waitForExpectationsWithTimeout(timeout, handler: nil)
  60. // Then
  61. if let response = response {
  62. XCTAssertNotNil(response.request, "request should not be nil")
  63. XCTAssertNil(response.response, "response should be nil")
  64. XCTAssertNotNil(response.data, "data should not be nil")
  65. XCTAssertTrue(response.result.isFailure, "result should be failure")
  66. } else {
  67. XCTFail("response should not be nil")
  68. }
  69. }
  70. }
  71. // MARK: -
  72. class ResponseStringTestCase: BaseTestCase {
  73. func testThatResponseStringReturnsSuccessResultWithValidString() {
  74. // Given
  75. let URLString = "https://httpbin.org/get"
  76. let expectation = expectationWithDescription("request should succeed")
  77. var response: Response<String, NSError>?
  78. // When
  79. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  80. .responseString { closureResponse in
  81. response = closureResponse
  82. expectation.fulfill()
  83. }
  84. waitForExpectationsWithTimeout(timeout, handler: nil)
  85. // Then
  86. if let response = response {
  87. XCTAssertNotNil(response.request, "request should not be nil")
  88. XCTAssertNotNil(response.response, "response should not be nil")
  89. XCTAssertNotNil(response.data, "data should not be nil")
  90. XCTAssertTrue(response.result.isSuccess, "result should be success")
  91. } else {
  92. XCTFail("response should not be nil")
  93. }
  94. }
  95. func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
  96. // Given
  97. let URLString = "https://invalid-url-here.org/this/does/not/exist"
  98. let expectation = expectationWithDescription("request should fail with 404")
  99. var response: Response<String, NSError>?
  100. // When
  101. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  102. .responseString { closureResponse in
  103. response = closureResponse
  104. expectation.fulfill()
  105. }
  106. waitForExpectationsWithTimeout(timeout, handler: nil)
  107. // Then
  108. if let response = response {
  109. XCTAssertNotNil(response.request, "request should not be nil")
  110. XCTAssertNil(response.response, "response should be nil")
  111. XCTAssertNotNil(response.data, "data should not be nil")
  112. XCTAssertTrue(response.result.isFailure, "result should be failure")
  113. } else {
  114. XCTFail("response should not be nil")
  115. }
  116. }
  117. }
  118. // MARK: -
  119. class ResponseJSONTestCase: BaseTestCase {
  120. func testThatResponseJSONReturnsSuccessResultWithValidJSON() {
  121. // Given
  122. let URLString = "https://httpbin.org/get"
  123. let expectation = expectationWithDescription("request should succeed")
  124. var response: Response<AnyObject, NSError>?
  125. // When
  126. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  127. .responseJSON { closureResponse in
  128. response = closureResponse
  129. expectation.fulfill()
  130. }
  131. waitForExpectationsWithTimeout(timeout, handler: nil)
  132. // Then
  133. if let response = response {
  134. XCTAssertNotNil(response.request, "request should not be nil")
  135. XCTAssertNotNil(response.response, "response should not be nil")
  136. XCTAssertNotNil(response.data, "data should not be nil")
  137. XCTAssertTrue(response.result.isSuccess, "result should be success")
  138. } else {
  139. XCTFail("response should not be nil")
  140. }
  141. }
  142. func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
  143. // Given
  144. let URLString = "https://invalid-url-here.org/this/does/not/exist"
  145. let expectation = expectationWithDescription("request should fail with 404")
  146. var response: Response<AnyObject, NSError>?
  147. // When
  148. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  149. .responseJSON { closureResponse in
  150. response = closureResponse
  151. expectation.fulfill()
  152. }
  153. waitForExpectationsWithTimeout(timeout, handler: nil)
  154. // Then
  155. if let response = response {
  156. XCTAssertNotNil(response.request, "request should not be nil")
  157. XCTAssertNil(response.response, "response should be nil")
  158. XCTAssertNotNil(response.data, "data should not be nil")
  159. XCTAssertTrue(response.result.isFailure, "result should be failure")
  160. } else {
  161. XCTFail("response should not be nil")
  162. }
  163. }
  164. func testThatResponseJSONReturnsSuccessResultForGETRequest() {
  165. // Given
  166. let URLString = "https://httpbin.org/get"
  167. let expectation = expectationWithDescription("request should succeed")
  168. var response: Response<AnyObject, NSError>?
  169. // When
  170. Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
  171. .responseJSON { closureResponse in
  172. response = closureResponse
  173. expectation.fulfill()
  174. }
  175. waitForExpectationsWithTimeout(timeout, handler: nil)
  176. // Then
  177. if let response = response {
  178. XCTAssertNotNil(response.request, "request should not be nil")
  179. XCTAssertNotNil(response.response, "response should not be nil")
  180. XCTAssertNotNil(response.data, "data should not be nil")
  181. XCTAssertTrue(response.result.isSuccess, "result should be success")
  182. // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
  183. // - https://openradar.appspot.com/radar?id=5517037090635776
  184. if let args = response.result.value?["args" as NSString] as? [String: String] {
  185. XCTAssertEqual(args, ["foo": "bar"], "args should match parameters")
  186. } else {
  187. XCTFail("args should not be nil")
  188. }
  189. } else {
  190. XCTFail("response should not be nil")
  191. }
  192. }
  193. func testThatResponseJSONReturnsSuccessResultForPOSTRequest() {
  194. // Given
  195. let URLString = "https://httpbin.org/post"
  196. let expectation = expectationWithDescription("request should succeed")
  197. var response: Response<AnyObject, NSError>?
  198. // When
  199. Alamofire.request(.POST, URLString, parameters: ["foo": "bar"])
  200. .responseJSON { closureResponse in
  201. response = closureResponse
  202. expectation.fulfill()
  203. }
  204. waitForExpectationsWithTimeout(timeout, handler: nil)
  205. // Then
  206. if let response = response {
  207. XCTAssertNotNil(response.request, "request should not be nil")
  208. XCTAssertNotNil(response.response, "response should not be nil")
  209. XCTAssertNotNil(response.data, "data should not be nil")
  210. XCTAssertTrue(response.result.isSuccess, "result should be success")
  211. // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
  212. // - https://openradar.appspot.com/radar?id=5517037090635776
  213. if let form = response.result.value?["form" as NSString] as? [String: String] {
  214. XCTAssertEqual(form, ["foo": "bar"], "form should match parameters")
  215. } else {
  216. XCTFail("form should not be nil")
  217. }
  218. } else {
  219. XCTFail("response should not be nil")
  220. }
  221. }
  222. }
  223. // MARK: -
  224. class RedirectResponseTestCase: BaseTestCase {
  225. var manager: Alamofire.Manager!
  226. // MARK: Setup and Teardown
  227. override func setUp() {
  228. super.setUp()
  229. manager = Alamofire.Manager(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration())
  230. }
  231. override func tearDown() {
  232. super.tearDown()
  233. }
  234. // MARK: Tests
  235. func testThatRequestWillPerformHTTPRedirectionByDefault() {
  236. // Given
  237. let redirectURLString = "https://www.apple.com"
  238. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  239. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  240. var request: NSURLRequest?
  241. var response: NSHTTPURLResponse?
  242. var data: NSData?
  243. var error: NSError?
  244. // When
  245. manager.request(.GET, URLString)
  246. .response { responseRequest, responseResponse, responseData, responseError in
  247. request = responseRequest
  248. response = responseResponse
  249. data = responseData
  250. error = responseError
  251. expectation.fulfill()
  252. }
  253. waitForExpectationsWithTimeout(timeout, handler: nil)
  254. // Then
  255. XCTAssertNotNil(request, "request should not be nil")
  256. XCTAssertNotNil(response, "response should not be nil")
  257. XCTAssertNotNil(data, "data should not be nil")
  258. XCTAssertNil(error, "error should be nil")
  259. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  260. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  261. }
  262. func testThatRequestWillPerformRedirectionMultipleTimesByDefault() {
  263. // Given
  264. let redirectURLString = "https://httpbin.org/get"
  265. let URLString = "https://httpbin.org/redirect/5"
  266. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  267. var request: NSURLRequest?
  268. var response: NSHTTPURLResponse?
  269. var data: NSData?
  270. var error: NSError?
  271. // When
  272. manager.request(.GET, URLString)
  273. .response { responseRequest, responseResponse, responseData, responseError in
  274. request = responseRequest
  275. response = responseResponse
  276. data = responseData
  277. error = responseError
  278. expectation.fulfill()
  279. }
  280. waitForExpectationsWithTimeout(timeout, handler: nil)
  281. // Then
  282. XCTAssertNotNil(request, "request should not be nil")
  283. XCTAssertNotNil(response, "response should not be nil")
  284. XCTAssertNotNil(data, "data should not be nil")
  285. XCTAssertNil(error, "error should be nil")
  286. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  287. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  288. }
  289. func testThatTaskOverrideClosureCanPerformHTTPRedirection() {
  290. // Given
  291. let redirectURLString = "https://www.apple.com"
  292. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  293. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  294. let callbackExpectation = expectationWithDescription("Redirect callback should be made")
  295. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  296. delegate.taskWillPerformHTTPRedirection = { _, _, _, request in
  297. callbackExpectation.fulfill()
  298. return request
  299. }
  300. var request: NSURLRequest?
  301. var response: NSHTTPURLResponse?
  302. var data: NSData?
  303. var error: NSError?
  304. // When
  305. manager.request(.GET, URLString)
  306. .response { responseRequest, responseResponse, responseData, responseError in
  307. request = responseRequest
  308. response = responseResponse
  309. data = responseData
  310. error = responseError
  311. expectation.fulfill()
  312. }
  313. waitForExpectationsWithTimeout(timeout, handler: nil)
  314. // Then
  315. XCTAssertNotNil(request, "request should not be nil")
  316. XCTAssertNotNil(response, "response should not be nil")
  317. XCTAssertNotNil(data, "data should not be nil")
  318. XCTAssertNil(error, "error should be nil")
  319. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  320. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  321. }
  322. func testThatTaskOverrideClosureWithCompletionCanPerformHTTPRedirection() {
  323. // Given
  324. let redirectURLString = "https://www.apple.com"
  325. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  326. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  327. let callbackExpectation = expectationWithDescription("Redirect callback should be made")
  328. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  329. delegate.taskWillPerformHTTPRedirectionWithCompletion = { _, _, _, request, completion in
  330. completion(request)
  331. callbackExpectation.fulfill()
  332. }
  333. var request: NSURLRequest?
  334. var response: NSHTTPURLResponse?
  335. var data: NSData?
  336. var error: NSError?
  337. // When
  338. manager.request(.GET, URLString)
  339. .response { responseRequest, responseResponse, responseData, responseError in
  340. request = responseRequest
  341. response = responseResponse
  342. data = responseData
  343. error = responseError
  344. expectation.fulfill()
  345. }
  346. waitForExpectationsWithTimeout(timeout, handler: nil)
  347. // Then
  348. XCTAssertNotNil(request, "request should not be nil")
  349. XCTAssertNotNil(response, "response should not be nil")
  350. XCTAssertNotNil(data, "data should not be nil")
  351. XCTAssertNil(error, "error should be nil")
  352. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  353. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  354. }
  355. func testThatTaskOverrideClosureCanCancelHTTPRedirection() {
  356. // Given
  357. let redirectURLString = "https://www.apple.com"
  358. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  359. let expectation = expectationWithDescription("Request should not redirect to \(redirectURLString)")
  360. let callbackExpectation = expectationWithDescription("Redirect callback should be made")
  361. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  362. delegate.taskWillPerformHTTPRedirectionWithCompletion = { _, _, _, _, completion in
  363. callbackExpectation.fulfill()
  364. completion(nil)
  365. }
  366. var request: NSURLRequest?
  367. var response: NSHTTPURLResponse?
  368. var data: NSData?
  369. var error: NSError?
  370. // When
  371. manager.request(.GET, URLString)
  372. .response { responseRequest, responseResponse, responseData, responseError in
  373. request = responseRequest
  374. response = responseResponse
  375. data = responseData
  376. error = responseError
  377. expectation.fulfill()
  378. }
  379. waitForExpectationsWithTimeout(timeout, handler: nil)
  380. // Then
  381. XCTAssertNotNil(request, "request should not be nil")
  382. XCTAssertNotNil(response, "response should not be nil")
  383. XCTAssertNotNil(data, "data should not be nil")
  384. XCTAssertNil(error, "error should be nil")
  385. XCTAssertEqual(response?.URL?.URLString ?? "", URLString, "response URL should match the origin URL")
  386. XCTAssertEqual(response?.statusCode ?? -1, 302, "response should have a 302 status code")
  387. }
  388. func testThatTaskOverrideClosureWithCompletionCanCancelHTTPRedirection() {
  389. // Given
  390. let redirectURLString = "https://www.apple.com"
  391. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  392. let expectation = expectationWithDescription("Request should not redirect to \(redirectURLString)")
  393. let callbackExpectation = expectationWithDescription("Redirect callback should be made")
  394. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  395. delegate.taskWillPerformHTTPRedirection = { _, _, _, _ in
  396. callbackExpectation.fulfill()
  397. return nil
  398. }
  399. var request: NSURLRequest?
  400. var response: NSHTTPURLResponse?
  401. var data: NSData?
  402. var error: NSError?
  403. // When
  404. manager.request(.GET, URLString)
  405. .response { responseRequest, responseResponse, responseData, responseError in
  406. request = responseRequest
  407. response = responseResponse
  408. data = responseData
  409. error = responseError
  410. expectation.fulfill()
  411. }
  412. waitForExpectationsWithTimeout(timeout, handler: nil)
  413. // Then
  414. XCTAssertNotNil(request, "request should not be nil")
  415. XCTAssertNotNil(response, "response should not be nil")
  416. XCTAssertNotNil(data, "data should not be nil")
  417. XCTAssertNil(error, "error should be nil")
  418. XCTAssertEqual(response?.URL?.URLString ?? "", URLString, "response URL should match the origin URL")
  419. XCTAssertEqual(response?.statusCode ?? -1, 302, "response should have a 302 status code")
  420. }
  421. func testThatTaskOverrideClosureIsCalledMultipleTimesForMultipleHTTPRedirects() {
  422. // Given
  423. let redirectCount = 5
  424. let redirectURLString = "https://httpbin.org/get"
  425. let URLString = "https://httpbin.org/redirect/\(redirectCount)"
  426. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  427. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  428. var redirectExpectations = [XCTestExpectation]()
  429. for index in 0..<redirectCount {
  430. redirectExpectations.insert(expectationWithDescription("Redirect #\(index) callback was received"), atIndex: 0)
  431. }
  432. delegate.taskWillPerformHTTPRedirection = { _, _, _, request in
  433. if let redirectExpectation = redirectExpectations.popLast() {
  434. redirectExpectation.fulfill()
  435. } else {
  436. XCTFail("Too many redirect callbacks were received")
  437. }
  438. return request
  439. }
  440. var request: NSURLRequest?
  441. var response: NSHTTPURLResponse?
  442. var data: NSData?
  443. var error: NSError?
  444. // When
  445. manager.request(.GET, URLString)
  446. .response { responseRequest, responseResponse, responseData, responseError in
  447. request = responseRequest
  448. response = responseResponse
  449. data = responseData
  450. error = responseError
  451. expectation.fulfill()
  452. }
  453. waitForExpectationsWithTimeout(timeout, handler: nil)
  454. // Then
  455. XCTAssertNotNil(request, "request should not be nil")
  456. XCTAssertNotNil(response, "response should not be nil")
  457. XCTAssertNotNil(data, "data should not be nil")
  458. XCTAssertNil(error, "error should be nil")
  459. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  460. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  461. }
  462. func testThatTaskOverrideClosureWithCompletionIsCalledMultipleTimesForMultipleHTTPRedirects() {
  463. // Given
  464. let redirectCount = 5
  465. let redirectURLString = "https://httpbin.org/get"
  466. let URLString = "https://httpbin.org/redirect/\(redirectCount)"
  467. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  468. let delegate: Alamofire.Manager.SessionDelegate = manager.delegate
  469. var redirectExpectations = [XCTestExpectation]()
  470. for index in 0..<redirectCount {
  471. redirectExpectations.insert(expectationWithDescription("Redirect #\(index) callback was received"), atIndex: 0)
  472. }
  473. delegate.taskWillPerformHTTPRedirectionWithCompletion = { _, _, _, request, completion in
  474. if let redirectExpectation = redirectExpectations.popLast() {
  475. redirectExpectation.fulfill()
  476. } else {
  477. XCTFail("Too many redirect callbacks were received")
  478. }
  479. completion(request)
  480. }
  481. var request: NSURLRequest?
  482. var response: NSHTTPURLResponse?
  483. var data: NSData?
  484. var error: NSError?
  485. // When
  486. manager.request(.GET, URLString)
  487. .response { responseRequest, responseResponse, responseData, responseError in
  488. request = responseRequest
  489. response = responseResponse
  490. data = responseData
  491. error = responseError
  492. expectation.fulfill()
  493. }
  494. waitForExpectationsWithTimeout(timeout, handler: nil)
  495. // Then
  496. XCTAssertNotNil(request, "request should not be nil")
  497. XCTAssertNotNil(response, "response should not be nil")
  498. XCTAssertNotNil(data, "data should not be nil")
  499. XCTAssertNil(error, "error should be nil")
  500. XCTAssertEqual(response?.URL?.URLString ?? "", redirectURLString, "response URL should match the redirect URL")
  501. XCTAssertEqual(response?.statusCode ?? -1, 200, "response should have a 200 status code")
  502. }
  503. func testThatRedirectedRequestContainsAllHeadersFromOriginalRequest() {
  504. // Given
  505. let redirectURLString = "https://httpbin.org/get"
  506. let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
  507. let headers = [
  508. "Authorization": "1234",
  509. "Custom-Header": "foobar",
  510. ]
  511. // NOTE: It appears that most headers are maintained during a redirect with the exception of the `Authorization`
  512. // header. It appears that Apple's strips the `Authorization` header from the redirected URL request. If you
  513. // need to maintain the `Authorization` header, you need to manually append it to the redirected request.
  514. manager.delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
  515. var redirectedRequest = request
  516. if let
  517. originalRequest = task.originalRequest,
  518. headers = originalRequest.allHTTPHeaderFields,
  519. authorizationHeaderValue = headers["Authorization"]
  520. {
  521. let mutableRequest = request.mutableCopy() as! NSMutableURLRequest
  522. mutableRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
  523. redirectedRequest = mutableRequest
  524. }
  525. return redirectedRequest
  526. }
  527. let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
  528. var response: Response<AnyObject, NSError>?
  529. // When
  530. manager.request(.GET, URLString, headers: headers)
  531. .responseJSON { closureResponse in
  532. response = closureResponse
  533. expectation.fulfill()
  534. }
  535. waitForExpectationsWithTimeout(timeout, handler: nil)
  536. // Then
  537. XCTAssertNotNil(response?.request, "request should not be nil")
  538. XCTAssertNotNil(response?.response, "response should not be nil")
  539. XCTAssertNotNil(response?.data, "data should not be nil")
  540. XCTAssertTrue(response?.result.isSuccess ?? false, "response result should be a success")
  541. if let
  542. JSON = response?.result.value as? [String: AnyObject],
  543. headers = JSON["headers"] as? [String: String]
  544. {
  545. XCTAssertEqual(headers["Custom-Header"], "foobar", "Custom-Header should be equal to foobar")
  546. XCTAssertEqual(headers["Authorization"], "1234", "Authorization header should be equal to 1234")
  547. }
  548. }
  549. }