RequestTests.swift 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. //
  2. // RequestTests.swift
  3. //
  4. // Copyright (c) 2014-2020 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 RequestResponseTestCase: BaseTestCase {
  28. func testRequestResponse() {
  29. // Given
  30. let urlString = "https://httpbin.org/get"
  31. let expectation = self.expectation(description: "GET request should succeed: \(urlString)")
  32. var response: DataResponse<Data?, AFError>?
  33. // When
  34. AF.request(urlString, parameters: ["foo": "bar"])
  35. .response { resp in
  36. response = resp
  37. expectation.fulfill()
  38. }
  39. waitForExpectations(timeout: timeout, handler: nil)
  40. // Then
  41. XCTAssertNotNil(response?.request)
  42. XCTAssertNotNil(response?.response)
  43. XCTAssertNotNil(response?.data)
  44. XCTAssertNil(response?.error)
  45. }
  46. func testRequestResponseWithProgress() {
  47. // Given
  48. let randomBytes = 1 * 25 * 1024
  49. let urlString = "https://httpbin.org/bytes/\(randomBytes)"
  50. let expectation = self.expectation(description: "Bytes download progress should be reported: \(urlString)")
  51. var progressValues: [Double] = []
  52. var response: DataResponse<Data?, AFError>?
  53. // When
  54. AF.request(urlString)
  55. .downloadProgress { progress in
  56. progressValues.append(progress.fractionCompleted)
  57. }
  58. .response { resp in
  59. response = resp
  60. expectation.fulfill()
  61. }
  62. waitForExpectations(timeout: timeout, handler: nil)
  63. // Then
  64. XCTAssertNotNil(response?.request)
  65. XCTAssertNotNil(response?.response)
  66. XCTAssertNotNil(response?.data)
  67. XCTAssertNil(response?.error)
  68. var previousProgress: Double = progressValues.first ?? 0.0
  69. for progress in progressValues {
  70. XCTAssertGreaterThanOrEqual(progress, previousProgress)
  71. previousProgress = progress
  72. }
  73. if let lastProgressValue = progressValues.last {
  74. XCTAssertEqual(lastProgressValue, 1.0)
  75. } else {
  76. XCTFail("last item in progressValues should not be nil")
  77. }
  78. }
  79. func testPOSTRequestWithUnicodeParameters() {
  80. // Given
  81. let urlString = "https://httpbin.org/post"
  82. let parameters = ["french": "français",
  83. "japanese": "日本語",
  84. "arabic": "العربية",
  85. "emoji": "😃"]
  86. let expectation = self.expectation(description: "request should succeed")
  87. var response: DataResponse<Any, AFError>?
  88. // When
  89. AF.request(urlString, method: .post, parameters: parameters)
  90. .responseJSON { closureResponse in
  91. response = closureResponse
  92. expectation.fulfill()
  93. }
  94. waitForExpectations(timeout: timeout, handler: nil)
  95. // Then
  96. XCTAssertNotNil(response?.request)
  97. XCTAssertNotNil(response?.response)
  98. XCTAssertNotNil(response?.data)
  99. if let json = response?.result.success as? [String: Any], let form = json["form"] as? [String: String] {
  100. XCTAssertEqual(form["french"], parameters["french"])
  101. XCTAssertEqual(form["japanese"], parameters["japanese"])
  102. XCTAssertEqual(form["arabic"], parameters["arabic"])
  103. XCTAssertEqual(form["emoji"], parameters["emoji"])
  104. } else {
  105. XCTFail("form parameter in JSON should not be nil")
  106. }
  107. }
  108. #if !SWIFT_PACKAGE
  109. func testPOSTRequestWithBase64EncodedImages() {
  110. // Given
  111. let urlString = "https://httpbin.org/post"
  112. let pngBase64EncodedString: String = {
  113. let URL = url(forResource: "unicorn", withExtension: "png")
  114. let data = try! Data(contentsOf: URL)
  115. return data.base64EncodedString(options: .lineLength64Characters)
  116. }()
  117. let jpegBase64EncodedString: String = {
  118. let URL = url(forResource: "rainbow", withExtension: "jpg")
  119. let data = try! Data(contentsOf: URL)
  120. return data.base64EncodedString(options: .lineLength64Characters)
  121. }()
  122. let parameters = ["email": "user@alamofire.org",
  123. "png_image": pngBase64EncodedString,
  124. "jpeg_image": jpegBase64EncodedString]
  125. let expectation = self.expectation(description: "request should succeed")
  126. var response: DataResponse<Any, AFError>?
  127. // When
  128. AF.request(urlString, method: .post, parameters: parameters)
  129. .responseJSON { closureResponse in
  130. response = closureResponse
  131. expectation.fulfill()
  132. }
  133. waitForExpectations(timeout: timeout, handler: nil)
  134. // Then
  135. XCTAssertNotNil(response?.request)
  136. XCTAssertNotNil(response?.response)
  137. XCTAssertNotNil(response?.data)
  138. XCTAssertEqual(response?.result.isSuccess, true)
  139. if let json = response?.result.success as? [String: Any], let form = json["form"] as? [String: String] {
  140. XCTAssertEqual(form["email"], parameters["email"])
  141. XCTAssertEqual(form["png_image"], parameters["png_image"])
  142. XCTAssertEqual(form["jpeg_image"], parameters["jpeg_image"])
  143. } else {
  144. XCTFail("form parameter in JSON should not be nil")
  145. }
  146. }
  147. #endif
  148. // MARK: Queues
  149. func testThatResponseSerializationWorksWithSerializationQueue() {
  150. // Given
  151. let queue = DispatchQueue(label: "org.alamofire.testSerializationQueue")
  152. let manager = Session(serializationQueue: queue)
  153. let expectation = self.expectation(description: "request should complete")
  154. var response: DataResponse<Any, AFError>?
  155. // When
  156. manager.request("https://httpbin.org/get").responseJSON { resp in
  157. response = resp
  158. expectation.fulfill()
  159. }
  160. waitForExpectations(timeout: timeout, handler: nil)
  161. // Then
  162. XCTAssertEqual(response?.result.isSuccess, true)
  163. }
  164. func testThatRequestsWorksWithRequestAndSerializationQueues() {
  165. // Given
  166. let requestQueue = DispatchQueue(label: "org.alamofire.testRequestQueue")
  167. let serializationQueue = DispatchQueue(label: "org.alamofire.testSerializationQueue")
  168. let manager = Session(requestQueue: requestQueue, serializationQueue: serializationQueue)
  169. let expectation = self.expectation(description: "request should complete")
  170. var response: DataResponse<Any, AFError>?
  171. // When
  172. manager.request("https://httpbin.org/get").responseJSON { resp in
  173. response = resp
  174. expectation.fulfill()
  175. }
  176. waitForExpectations(timeout: timeout, handler: nil)
  177. // Then
  178. XCTAssertEqual(response?.result.isSuccess, true)
  179. }
  180. func testThatRequestsWorksWithConcurrentRequestAndSerializationQueues() {
  181. // Given
  182. let requestQueue = DispatchQueue(label: "org.alamofire.testRequestQueue", attributes: .concurrent)
  183. let serializationQueue = DispatchQueue(label: "org.alamofire.testSerializationQueue", attributes: .concurrent)
  184. let session = Session(requestQueue: requestQueue, serializationQueue: serializationQueue)
  185. let count = 10
  186. let expectation = self.expectation(description: "request should complete")
  187. expectation.expectedFulfillmentCount = count
  188. var responses: [DataResponse<Any, AFError>] = []
  189. // When
  190. DispatchQueue.concurrentPerform(iterations: count) { _ in
  191. session.request("https://httpbin.org/get").responseJSON { resp in
  192. responses.append(resp)
  193. expectation.fulfill()
  194. }
  195. }
  196. waitForExpectations(timeout: timeout, handler: nil)
  197. // Then
  198. XCTAssertEqual(responses.count, count)
  199. XCTAssertTrue(responses.allSatisfy { $0.result.isSuccess })
  200. }
  201. // MARK: Encodable Parameters
  202. func testThatRequestsCanPassEncodableParametersAsJSONBodyData() {
  203. // Given
  204. let parameters = HTTPBinParameters(property: "one")
  205. let expect = expectation(description: "request should complete")
  206. var receivedResponse: DataResponse<HTTPBinResponse, AFError>?
  207. // When
  208. AF.request("https://httpbin.org/post", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default)
  209. .responseDecodable(of: HTTPBinResponse.self) { response in
  210. receivedResponse = response
  211. expect.fulfill()
  212. }
  213. waitForExpectations(timeout: timeout, handler: nil)
  214. // Then
  215. XCTAssertEqual(receivedResponse?.result.success?.data, "{\"property\":\"one\"}")
  216. }
  217. func testThatRequestsCanPassEncodableParametersAsAURLQuery() {
  218. // Given
  219. let parameters = HTTPBinParameters(property: "one")
  220. let expect = expectation(description: "request should complete")
  221. var receivedResponse: DataResponse<HTTPBinResponse, AFError>?
  222. // When
  223. AF.request("https://httpbin.org/get", method: .get, parameters: parameters)
  224. .responseDecodable(of: HTTPBinResponse.self) { response in
  225. receivedResponse = response
  226. expect.fulfill()
  227. }
  228. waitForExpectations(timeout: timeout, handler: nil)
  229. // Then
  230. XCTAssertEqual(receivedResponse?.result.success?.args, ["property": "one"])
  231. }
  232. func testThatRequestsCanPassEncodableParametersAsURLEncodedBodyData() {
  233. // Given
  234. let parameters = HTTPBinParameters(property: "one")
  235. let expect = expectation(description: "request should complete")
  236. var receivedResponse: DataResponse<HTTPBinResponse, AFError>?
  237. // When
  238. AF.request("https://httpbin.org/post", method: .post, parameters: parameters)
  239. .responseDecodable(of: HTTPBinResponse.self) { response in
  240. receivedResponse = response
  241. expect.fulfill()
  242. }
  243. waitForExpectations(timeout: timeout, handler: nil)
  244. // Then
  245. XCTAssertEqual(receivedResponse?.result.success?.form, ["property": "one"])
  246. }
  247. // MARK: Lifetime Events
  248. func testThatAutomaticallyResumedRequestReceivesAppropriateLifetimeEvents() {
  249. // Given
  250. let eventMonitor = ClosureEventMonitor()
  251. let session = Session(eventMonitors: [eventMonitor])
  252. let expect = expectation(description: "request should receive appropriate lifetime events")
  253. expect.expectedFulfillmentCount = 4
  254. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  255. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  256. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  257. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  258. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  259. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  260. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  261. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  262. // When
  263. let request = session.request(URLRequest.makeHTTPBinRequest()).response { _ in expect.fulfill() }
  264. waitForExpectations(timeout: timeout, handler: nil)
  265. // Then
  266. XCTAssertEqual(request.state, .finished)
  267. }
  268. func testThatAutomaticallyAndManuallyResumedRequestReceivesAppropriateLifetimeEvents() {
  269. // Given
  270. let eventMonitor = ClosureEventMonitor()
  271. let session = Session(eventMonitors: [eventMonitor])
  272. let expect = expectation(description: "request should receive appropriate lifetime events")
  273. expect.expectedFulfillmentCount = 4
  274. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  275. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  276. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  277. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  278. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  279. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  280. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  281. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  282. // When
  283. let request = session.request(URLRequest.makeHTTPBinRequest()).response { _ in expect.fulfill() }
  284. for _ in 0..<100 {
  285. request.resume()
  286. }
  287. waitForExpectations(timeout: timeout, handler: nil)
  288. // Then
  289. XCTAssertEqual(request.state, .finished)
  290. }
  291. func testThatManuallyResumedRequestReceivesAppropriateLifetimeEvents() {
  292. // Given
  293. let eventMonitor = ClosureEventMonitor()
  294. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  295. let expect = expectation(description: "request should receive appropriate lifetime events")
  296. expect.expectedFulfillmentCount = 3
  297. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  298. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  299. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  300. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  301. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  302. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  303. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  304. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  305. // When
  306. let request = session.request(URLRequest.makeHTTPBinRequest())
  307. for _ in 0..<100 {
  308. request.resume()
  309. }
  310. waitForExpectations(timeout: timeout, handler: nil)
  311. // Then
  312. XCTAssertEqual(request.state, .finished)
  313. }
  314. func testThatRequestManuallyResumedManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  315. // Given
  316. let eventMonitor = ClosureEventMonitor()
  317. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  318. let expect = expectation(description: "request should receive appropriate lifetime events")
  319. expect.expectedFulfillmentCount = 4
  320. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  321. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  322. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  323. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  324. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  325. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  326. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  327. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  328. // When
  329. let request = session.request(URLRequest.makeHTTPBinRequest()).response { _ in expect.fulfill() }
  330. for _ in 0..<100 {
  331. request.resume()
  332. }
  333. waitForExpectations(timeout: timeout, handler: nil)
  334. // Then
  335. XCTAssertEqual(request.state, .finished)
  336. }
  337. func testThatRequestManuallySuspendedManyTimesAfterAutomaticResumeOnlyReceivesAppropriateLifetimeEvents() {
  338. // Given
  339. let eventMonitor = ClosureEventMonitor()
  340. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  341. let expect = expectation(description: "request should receive appropriate lifetime events")
  342. expect.expectedFulfillmentCount = 2
  343. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  344. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  345. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  346. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  347. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  348. // When
  349. let request = session.request(URLRequest.makeHTTPBinRequest())
  350. for _ in 0..<100 {
  351. request.suspend()
  352. }
  353. waitForExpectations(timeout: timeout, handler: nil)
  354. // Then
  355. XCTAssertEqual(request.state, .suspended)
  356. }
  357. func testThatRequestManuallySuspendedManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  358. // Given
  359. let eventMonitor = ClosureEventMonitor()
  360. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  361. let expect = expectation(description: "request should receive appropriate lifetime events")
  362. expect.expectedFulfillmentCount = 2
  363. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  364. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  365. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  366. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  367. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  368. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  369. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  370. // When
  371. let request = session.request(URLRequest.makeHTTPBinRequest())
  372. for _ in 0..<100 {
  373. request.suspend()
  374. }
  375. waitForExpectations(timeout: timeout, handler: nil)
  376. // Then
  377. XCTAssertEqual(request.state, .suspended)
  378. }
  379. func testThatRequestManuallyCancelledManyTimesAfterAutomaticResumeOnlyReceivesAppropriateLifetimeEvents() {
  380. // Given
  381. let eventMonitor = ClosureEventMonitor()
  382. let session = Session(eventMonitors: [eventMonitor])
  383. let expect = expectation(description: "request should receive appropriate lifetime events")
  384. expect.expectedFulfillmentCount = 2
  385. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  386. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  387. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  388. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  389. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  390. // When
  391. let request = session.request(URLRequest.makeHTTPBinRequest())
  392. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  393. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  394. for _ in 0..<100 {
  395. request.cancel()
  396. }
  397. }
  398. waitForExpectations(timeout: timeout, handler: nil)
  399. // Then
  400. XCTAssertEqual(request.state, .cancelled)
  401. }
  402. func testThatRequestManuallyCancelledManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  403. // Given
  404. let eventMonitor = ClosureEventMonitor()
  405. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  406. let expect = expectation(description: "request should receive appropriate lifetime events")
  407. expect.expectedFulfillmentCount = 2
  408. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  409. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  410. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  411. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  412. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  413. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  414. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  415. // When
  416. let request = session.request(URLRequest.makeHTTPBinRequest())
  417. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  418. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  419. for _ in 0..<100 {
  420. request.cancel()
  421. }
  422. }
  423. waitForExpectations(timeout: timeout, handler: nil)
  424. // Then
  425. XCTAssertEqual(request.state, .cancelled)
  426. }
  427. func testThatRequestManuallyCancelledManyTimesOnManyQueuesOnlyReceivesAppropriateLifetimeEvents() {
  428. // Given
  429. let eventMonitor = ClosureEventMonitor()
  430. let session = Session(eventMonitors: [eventMonitor])
  431. let expect = expectation(description: "request should receive appropriate lifetime events")
  432. expect.expectedFulfillmentCount = 6
  433. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  434. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  435. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  436. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  437. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  438. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  439. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  440. // When
  441. let request = session.request(URLRequest.makeHTTPBinRequest(path: "delay/5")).response { _ in expect.fulfill() }
  442. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  443. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  444. DispatchQueue.concurrentPerform(iterations: 100) { i in
  445. request.cancel()
  446. if i == 99 { expect.fulfill() }
  447. }
  448. }
  449. waitForExpectations(timeout: timeout, handler: nil)
  450. // Then
  451. XCTAssertEqual(request.state, .cancelled)
  452. }
  453. func testThatRequestTriggersAllAppropriateLifetimeEvents() {
  454. // Given
  455. let eventMonitor = ClosureEventMonitor()
  456. let session = Session(eventMonitors: [eventMonitor])
  457. let didReceiveChallenge = expectation(description: "didReceiveChallenge should fire")
  458. let taskDidFinishCollecting = expectation(description: "taskDidFinishCollecting should fire")
  459. let didReceiveData = expectation(description: "didReceiveData should fire")
  460. let willCacheResponse = expectation(description: "willCacheResponse should fire")
  461. let didCreateURLRequest = expectation(description: "didCreateInitialURLRequest should fire")
  462. let didCreateTask = expectation(description: "didCreateTask should fire")
  463. let didGatherMetrics = expectation(description: "didGatherMetrics should fire")
  464. let didComplete = expectation(description: "didComplete should fire")
  465. let didFinish = expectation(description: "didFinish should fire")
  466. let didResume = expectation(description: "didResume should fire")
  467. let didResumeTask = expectation(description: "didResumeTask should fire")
  468. let didParseResponse = expectation(description: "didParseResponse should fire")
  469. let responseHandler = expectation(description: "responseHandler should fire")
  470. var dataReceived = false
  471. eventMonitor.taskDidReceiveChallenge = { _, _, _ in didReceiveChallenge.fulfill() }
  472. eventMonitor.taskDidFinishCollectingMetrics = { _, _, _ in taskDidFinishCollecting.fulfill() }
  473. eventMonitor.dataTaskDidReceiveData = { _, _, _ in
  474. guard !dataReceived else { return }
  475. // Data may be received many times, fulfill only once.
  476. dataReceived = true
  477. didReceiveData.fulfill()
  478. }
  479. eventMonitor.dataTaskWillCacheResponse = { _, _, _ in willCacheResponse.fulfill() }
  480. eventMonitor.requestDidCreateInitialURLRequest = { _, _ in didCreateURLRequest.fulfill() }
  481. eventMonitor.requestDidCreateTask = { _, _ in didCreateTask.fulfill() }
  482. eventMonitor.requestDidGatherMetrics = { _, _ in didGatherMetrics.fulfill() }
  483. eventMonitor.requestDidCompleteTaskWithError = { _, _, _ in didComplete.fulfill() }
  484. eventMonitor.requestDidFinish = { _ in didFinish.fulfill() }
  485. eventMonitor.requestDidResume = { _ in didResume.fulfill() }
  486. eventMonitor.requestDidResumeTask = { _, _ in didResumeTask.fulfill() }
  487. eventMonitor.requestDidParseResponse = { _, _ in didParseResponse.fulfill() }
  488. // When
  489. let request = session.request(URLRequest.makeHTTPBinRequest()).response { _ in
  490. responseHandler.fulfill()
  491. }
  492. waitForExpectations(timeout: timeout, handler: nil)
  493. // Then
  494. XCTAssertEqual(request.state, .finished)
  495. }
  496. func testThatCancelledRequestTriggersAllAppropriateLifetimeEvents() {
  497. // Given
  498. let eventMonitor = ClosureEventMonitor()
  499. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  500. let taskDidFinishCollecting = expectation(description: "taskDidFinishCollecting should fire")
  501. let didCreateURLRequest = expectation(description: "didCreateInitialURLRequest should fire")
  502. let didCreateTask = expectation(description: "didCreateTask should fire")
  503. let didGatherMetrics = expectation(description: "didGatherMetrics should fire")
  504. let didComplete = expectation(description: "didComplete should fire")
  505. let didFinish = expectation(description: "didFinish should fire")
  506. let didResume = expectation(description: "didResume should fire")
  507. let didResumeTask = expectation(description: "didResumeTask should fire")
  508. let didParseResponse = expectation(description: "didParseResponse should fire")
  509. let didCancel = expectation(description: "didCancel should fire")
  510. let didCancelTask = expectation(description: "didCancelTask should fire")
  511. let responseHandler = expectation(description: "responseHandler should fire")
  512. eventMonitor.taskDidFinishCollectingMetrics = { _, _, _ in taskDidFinishCollecting.fulfill() }
  513. eventMonitor.requestDidCreateInitialURLRequest = { _, _ in didCreateURLRequest.fulfill() }
  514. eventMonitor.requestDidCreateTask = { _, _ in didCreateTask.fulfill() }
  515. eventMonitor.requestDidGatherMetrics = { _, _ in didGatherMetrics.fulfill() }
  516. eventMonitor.requestDidCompleteTaskWithError = { _, _, _ in didComplete.fulfill() }
  517. eventMonitor.requestDidFinish = { _ in didFinish.fulfill() }
  518. eventMonitor.requestDidResume = { _ in didResume.fulfill() }
  519. eventMonitor.requestDidParseResponse = { _, _ in didParseResponse.fulfill() }
  520. eventMonitor.requestDidCancel = { _ in didCancel.fulfill() }
  521. eventMonitor.requestDidCancelTask = { _, _ in didCancelTask.fulfill() }
  522. // When
  523. let request = session.request(URLRequest.makeHTTPBinRequest(path: "delay/5")).response { _ in
  524. responseHandler.fulfill()
  525. }
  526. eventMonitor.requestDidResumeTask = { [unowned request] _, _ in
  527. request.cancel()
  528. didResumeTask.fulfill()
  529. }
  530. request.resume()
  531. waitForExpectations(timeout: timeout, handler: nil)
  532. // Then
  533. XCTAssertEqual(request.state, .cancelled)
  534. }
  535. func testThatAppendingResponseSerializerToCancelledRequestCallsCompletion() {
  536. // Given
  537. let session = Session()
  538. var response1: DataResponse<Any, AFError>?
  539. var response2: DataResponse<Any, AFError>?
  540. let expect = expectation(description: "both response serializer completions should be called")
  541. expect.expectedFulfillmentCount = 2
  542. // When
  543. let request = session.request(URLRequest.makeHTTPBinRequest())
  544. request.responseJSON { resp in
  545. response1 = resp
  546. expect.fulfill()
  547. request.responseJSON { resp in
  548. response2 = resp
  549. expect.fulfill()
  550. }
  551. }
  552. request.cancel()
  553. waitForExpectations(timeout: timeout, handler: nil)
  554. // Then
  555. XCTAssertEqual(response1?.error?.isExplicitlyCancelledError, true)
  556. XCTAssertEqual(response2?.error?.isExplicitlyCancelledError, true)
  557. }
  558. func testThatAppendingResponseSerializerToCompletedRequestInsideCompletionResumesRequest() {
  559. // Given
  560. let session = Session()
  561. var response1: DataResponse<Any, AFError>?
  562. var response2: DataResponse<Any, AFError>?
  563. var response3: DataResponse<Any, AFError>?
  564. let expect = expectation(description: "all response serializer completions should be called")
  565. expect.expectedFulfillmentCount = 3
  566. // When
  567. let request = session.request(URLRequest.makeHTTPBinRequest())
  568. request.responseJSON { resp in
  569. response1 = resp
  570. expect.fulfill()
  571. request.responseJSON { resp in
  572. response2 = resp
  573. expect.fulfill()
  574. request.responseJSON { resp in
  575. response3 = resp
  576. expect.fulfill()
  577. }
  578. }
  579. }
  580. waitForExpectations(timeout: timeout, handler: nil)
  581. // Then
  582. XCTAssertNotNil(response1?.value)
  583. XCTAssertNotNil(response2?.value)
  584. XCTAssertNotNil(response3?.value)
  585. }
  586. func testThatAppendingResponseSerializerToCompletedRequestOutsideCompletionResumesRequest() {
  587. // Given
  588. let session = Session()
  589. let request = session.request(URLRequest.makeHTTPBinRequest())
  590. var response1: DataResponse<Any, AFError>?
  591. var response2: DataResponse<Any, AFError>?
  592. var response3: DataResponse<Any, AFError>?
  593. // When
  594. let expect1 = expectation(description: "response serializer 1 completion should be called")
  595. request.responseJSON { response1 = $0; expect1.fulfill() }
  596. waitForExpectations(timeout: timeout, handler: nil)
  597. let expect2 = expectation(description: "response serializer 2 completion should be called")
  598. request.responseJSON { response2 = $0; expect2.fulfill() }
  599. waitForExpectations(timeout: timeout, handler: nil)
  600. let expect3 = expectation(description: "response serializer 3 completion should be called")
  601. request.responseJSON { response3 = $0; expect3.fulfill() }
  602. waitForExpectations(timeout: timeout, handler: nil)
  603. // Then
  604. XCTAssertNotNil(response1?.value)
  605. XCTAssertNotNil(response2?.value)
  606. XCTAssertNotNil(response3?.value)
  607. }
  608. }
  609. // MARK: -
  610. class RequestDescriptionTestCase: BaseTestCase {
  611. func testRequestDescription() {
  612. // Given
  613. let urlString = "https://httpbin.org/get"
  614. let manager = Session(startRequestsImmediately: false)
  615. let request = manager.request(urlString)
  616. let expectation = self.expectation(description: "Request description should update: \(urlString)")
  617. var response: HTTPURLResponse?
  618. // When
  619. request.response { resp in
  620. response = resp.response
  621. expectation.fulfill()
  622. }.resume()
  623. waitForExpectations(timeout: timeout, handler: nil)
  624. // Then
  625. XCTAssertEqual(request.description, "GET https://httpbin.org/get (\(response?.statusCode ?? -1))")
  626. }
  627. }
  628. // MARK: -
  629. final class RequestCURLDescriptionTestCase: BaseTestCase {
  630. // MARK: Properties
  631. let manager: Session = {
  632. let manager = Session()
  633. return manager
  634. }()
  635. let managerWithAcceptLanguageHeader: Session = {
  636. var headers = HTTPHeaders.default
  637. headers["Accept-Language"] = "en-US"
  638. let configuration = URLSessionConfiguration.af.default
  639. configuration.headers = headers
  640. let manager = Session(configuration: configuration)
  641. return manager
  642. }()
  643. let managerWithContentTypeHeader: Session = {
  644. var headers = HTTPHeaders.default
  645. headers["Content-Type"] = "application/json"
  646. let configuration = URLSessionConfiguration.af.default
  647. configuration.headers = headers
  648. let manager = Session(configuration: configuration)
  649. return manager
  650. }()
  651. func managerWithCookie(_ cookie: HTTPCookie) -> Session {
  652. let configuration = URLSessionConfiguration.af.default
  653. configuration.httpCookieStorage?.setCookie(cookie)
  654. return Session(configuration: configuration)
  655. }
  656. let managerDisallowingCookies: Session = {
  657. let configuration = URLSessionConfiguration.af.default
  658. configuration.httpShouldSetCookies = false
  659. let manager = Session(configuration: configuration)
  660. return manager
  661. }()
  662. // MARK: Tests
  663. func testGETRequestCURLDescription() {
  664. // Given
  665. let urlString = "https://httpbin.org/get"
  666. let expectation = self.expectation(description: "request should complete")
  667. var components: [String]?
  668. // When
  669. manager.request(urlString).cURLDescription {
  670. components = self.cURLCommandComponents(from: $0)
  671. expectation.fulfill()
  672. }
  673. waitForExpectations(timeout: timeout, handler: nil)
  674. // Then
  675. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  676. XCTAssertTrue(components?.contains("-X") == true)
  677. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  678. }
  679. func testGETRequestCURLDescriptionOnMainQueue() {
  680. // Given
  681. let url = URL.makeHTTPBinURL()
  682. let expectation = self.expectation(description: "request should complete")
  683. var isMainThread = false
  684. var components: [String]?
  685. // When
  686. manager.request(url).cURLDescription(on: .main) {
  687. components = self.cURLCommandComponents(from: $0)
  688. isMainThread = Thread.isMainThread
  689. expectation.fulfill()
  690. }
  691. waitForExpectations(timeout: timeout, handler: nil)
  692. // Then
  693. XCTAssertTrue(isMainThread)
  694. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  695. XCTAssertTrue(components?.contains("-X") == true)
  696. XCTAssertEqual(components?.last, "\"\(url)\"")
  697. }
  698. func testGETRequestCURLDescriptionSynchronous() {
  699. // Given
  700. let urlString = "https://httpbin.org/get"
  701. let expectation = self.expectation(description: "request should complete")
  702. var components: [String]?
  703. var syncComponents: [String]?
  704. // When
  705. let request = manager.request(urlString)
  706. request.cURLDescription {
  707. components = self.cURLCommandComponents(from: $0)
  708. syncComponents = self.cURLCommandComponents(from: request.cURLDescription())
  709. expectation.fulfill()
  710. }
  711. waitForExpectations(timeout: timeout, handler: nil)
  712. // Then
  713. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  714. XCTAssertTrue(components?.contains("-X") == true)
  715. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  716. XCTAssertEqual(components?.sorted(), syncComponents?.sorted())
  717. }
  718. func testGETRequestCURLDescriptionCanBeRequestedManyTimes() {
  719. // Given
  720. let urlString = "https://httpbin.org/get"
  721. let expectation = self.expectation(description: "request should complete")
  722. var components: [String]?
  723. var secondComponents: [String]?
  724. // When
  725. let request = manager.request(urlString)
  726. request.cURLDescription {
  727. components = self.cURLCommandComponents(from: $0)
  728. request.cURLDescription {
  729. secondComponents = self.cURLCommandComponents(from: $0)
  730. expectation.fulfill()
  731. }
  732. }
  733. waitForExpectations(timeout: timeout, handler: nil)
  734. // Then
  735. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  736. XCTAssertTrue(components?.contains("-X") == true)
  737. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  738. XCTAssertEqual(components?.sorted(), secondComponents?.sorted())
  739. }
  740. func testGETRequestWithCustomHeaderCURLDescription() {
  741. // Given
  742. let urlString = "https://httpbin.org/get"
  743. let expectation = self.expectation(description: "request should complete")
  744. var cURLDescription: String?
  745. // When
  746. let headers: HTTPHeaders = ["X-Custom-Header": "{\"key\": \"value\"}"]
  747. manager.request(urlString, headers: headers).cURLDescription {
  748. cURLDescription = $0
  749. expectation.fulfill()
  750. }
  751. waitForExpectations(timeout: timeout, handler: nil)
  752. // Then
  753. XCTAssertNotNil(cURLDescription?.range(of: "-H \"X-Custom-Header: {\\\"key\\\": \\\"value\\\"}\""))
  754. }
  755. func testGETRequestWithDuplicateHeadersDebugDescription() {
  756. // Given
  757. let urlString = "https://httpbin.org/get"
  758. let expectation = self.expectation(description: "request should complete")
  759. var cURLDescription: String?
  760. var components: [String]?
  761. // When
  762. let headers: HTTPHeaders = ["Accept-Language": "en-GB"]
  763. managerWithAcceptLanguageHeader.request(urlString, headers: headers).cURLDescription {
  764. components = self.cURLCommandComponents(from: $0)
  765. cURLDescription = $0
  766. expectation.fulfill()
  767. }
  768. waitForExpectations(timeout: timeout, handler: nil)
  769. // Then
  770. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  771. XCTAssertTrue(components?.contains("-X") == true)
  772. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  773. let acceptLanguageCount = components?.filter { $0.contains("Accept-Language") }.count
  774. XCTAssertEqual(acceptLanguageCount, 1, "command should contain a single Accept-Language header")
  775. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Accept-Language: en-GB\""))
  776. }
  777. func testPOSTRequestCURLDescription() {
  778. // Given
  779. let urlString = "https://httpbin.org/post"
  780. let expectation = self.expectation(description: "request should complete")
  781. var components: [String]?
  782. // When
  783. manager.request(urlString, method: .post).cURLDescription {
  784. components = self.cURLCommandComponents(from: $0)
  785. expectation.fulfill()
  786. }
  787. waitForExpectations(timeout: timeout, handler: nil)
  788. // Then
  789. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  790. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  791. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  792. }
  793. func testPOSTRequestWithJSONParametersCURLDescription() {
  794. // Given
  795. let urlString = "https://httpbin.org/post"
  796. let expectation = self.expectation(description: "request should complete")
  797. var cURLDescription: String?
  798. var components: [String]?
  799. let parameters = ["foo": "bar",
  800. "fo\"o": "b\"ar",
  801. "f'oo": "ba'r"]
  802. // When
  803. manager.request(urlString, method: .post, parameters: parameters, encoding: JSONEncoding.default).cURLDescription {
  804. components = self.cURLCommandComponents(from: $0)
  805. cURLDescription = $0
  806. expectation.fulfill()
  807. }
  808. waitForExpectations(timeout: timeout, handler: nil)
  809. // Then
  810. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  811. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  812. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Content-Type: application/json\""))
  813. XCTAssertNotNil(cURLDescription?.range(of: "-d \"{"))
  814. XCTAssertNotNil(cURLDescription?.range(of: "\\\"f'oo\\\":\\\"ba'r\\\""))
  815. XCTAssertNotNil(cURLDescription?.range(of: "\\\"fo\\\\\\\"o\\\":\\\"b\\\\\\\"ar\\\""))
  816. XCTAssertNotNil(cURLDescription?.range(of: "\\\"foo\\\":\\\"bar\\"))
  817. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  818. }
  819. func testPOSTRequestWithCookieCURLDescription() {
  820. // Given
  821. let urlString = "https://httpbin.org/post"
  822. let properties = [HTTPCookiePropertyKey.domain: "httpbin.org",
  823. HTTPCookiePropertyKey.path: "/post",
  824. HTTPCookiePropertyKey.name: "foo",
  825. HTTPCookiePropertyKey.value: "bar"]
  826. let cookie = HTTPCookie(properties: properties)!
  827. let cookieManager = managerWithCookie(cookie)
  828. let expectation = self.expectation(description: "request should complete")
  829. var components: [String]?
  830. // When
  831. cookieManager.request(urlString, method: .post).cURLDescription {
  832. components = self.cURLCommandComponents(from: $0)
  833. expectation.fulfill()
  834. }
  835. waitForExpectations(timeout: timeout, handler: nil)
  836. // Then
  837. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  838. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  839. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  840. XCTAssertEqual(components?[5..<6], ["-b"])
  841. }
  842. func testPOSTRequestWithCookiesDisabledCURLDescriptionHasNoCookies() {
  843. // Given
  844. let urlString = "https://httpbin.org/post"
  845. let properties = [HTTPCookiePropertyKey.domain: "httpbin.org",
  846. HTTPCookiePropertyKey.path: "/post",
  847. HTTPCookiePropertyKey.name: "foo",
  848. HTTPCookiePropertyKey.value: "bar"]
  849. let cookie = HTTPCookie(properties: properties)!
  850. managerDisallowingCookies.session.configuration.httpCookieStorage?.setCookie(cookie)
  851. let expectation = self.expectation(description: "request should complete")
  852. var components: [String]?
  853. // When
  854. managerDisallowingCookies.request(urlString, method: .post).cURLDescription {
  855. components = self.cURLCommandComponents(from: $0)
  856. expectation.fulfill()
  857. }
  858. waitForExpectations(timeout: timeout, handler: nil)
  859. // Then
  860. let cookieComponents = components?.filter { $0 == "-b" }
  861. XCTAssertTrue(cookieComponents?.isEmpty == true)
  862. }
  863. func testMultipartFormDataRequestWithDuplicateHeadersCURLDescriptionHasOneContentTypeHeader() {
  864. // Given
  865. let urlString = "https://httpbin.org/post"
  866. let japaneseData = Data("日本語".utf8)
  867. let expectation = self.expectation(description: "multipart form data encoding should succeed")
  868. var cURLDescription: String?
  869. var components: [String]?
  870. // When
  871. managerWithContentTypeHeader.upload(multipartFormData: { data in
  872. data.append(japaneseData, withName: "japanese")
  873. }, to: urlString).cURLDescription {
  874. components = self.cURLCommandComponents(from: $0)
  875. cURLDescription = $0
  876. expectation.fulfill()
  877. }
  878. waitForExpectations(timeout: timeout, handler: nil)
  879. // Then
  880. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  881. XCTAssertTrue(components?.contains("-X") == true)
  882. XCTAssertEqual(components?.last, "\"\(urlString)\"")
  883. let contentTypeCount = components?.filter { $0.contains("Content-Type") }.count
  884. XCTAssertEqual(contentTypeCount, 1, "command should contain a single Content-Type header")
  885. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Content-Type: multipart/form-data;"))
  886. }
  887. func testThatRequestWithInvalidURLDebugDescription() {
  888. // Given
  889. let urlString = "invalid_url"
  890. let expectation = self.expectation(description: "request should complete")
  891. var cURLDescription: String?
  892. // When
  893. manager.request(urlString).cURLDescription {
  894. cURLDescription = $0
  895. expectation.fulfill()
  896. }
  897. waitForExpectations(timeout: timeout, handler: nil)
  898. // Then
  899. XCTAssertNotNil(cURLDescription, "debugDescription should not crash")
  900. }
  901. // MARK: Test Helper Methods
  902. private func cURLCommandComponents(from cURLString: String) -> [String] {
  903. cURLString.components(separatedBy: .whitespacesAndNewlines)
  904. .filter { $0 != "" && $0 != "\\" }
  905. }
  906. }
  907. final class RequestLifetimeTests: BaseTestCase {
  908. func testThatRequestProvidesURLRequestWhenCreated() {
  909. // Given
  910. let didReceiveRequest = expectation(description: "did receive task")
  911. let didComplete = expectation(description: "request did complete")
  912. var request: URLRequest?
  913. // When
  914. AF.request(URLRequest.makeHTTPBinRequest())
  915. .onURLRequestCreation { request = $0; didReceiveRequest.fulfill() }
  916. .responseDecodable(of: HTTPBinResponse.self) { _ in didComplete.fulfill() }
  917. wait(for: [didReceiveRequest, didComplete], timeout: timeout, enforceOrder: true)
  918. // Then
  919. XCTAssertNotNil(request)
  920. }
  921. func testThatRequestProvidesTaskWhenCreated() {
  922. // Given
  923. let didReceiveTask = expectation(description: "did receive task")
  924. let didComplete = expectation(description: "request did complete")
  925. var task: URLSessionTask?
  926. // When
  927. AF.request(URLRequest.makeHTTPBinRequest())
  928. .onURLSessionTaskCreation { task = $0; didReceiveTask.fulfill() }
  929. .responseDecodable(of: HTTPBinResponse.self) { _ in didComplete.fulfill() }
  930. wait(for: [didReceiveTask, didComplete], timeout: timeout, enforceOrder: true)
  931. // Then
  932. XCTAssertNotNil(task)
  933. }
  934. }
  935. // MARK: -
  936. #if !SWIFT_PACKAGE
  937. final class RequestInvalidURLTestCase: BaseTestCase {
  938. func testThatDataRequestWithFileURLThrowsError() {
  939. // Given
  940. let fileURL = url(forResource: "valid_data", withExtension: "json")
  941. let expectation = self.expectation(description: "Request should succeed.")
  942. var response: DataResponse<Data?, AFError>?
  943. // When
  944. AF.request(fileURL)
  945. .response { resp in
  946. response = resp
  947. expectation.fulfill()
  948. }
  949. waitForExpectations(timeout: timeout)
  950. // Then
  951. XCTAssertEqual(response?.result.isSuccess, true)
  952. }
  953. func testThatDownloadRequestWithFileURLThrowsError() {
  954. // Given
  955. let fileURL = url(forResource: "valid_data", withExtension: "json")
  956. let expectation = self.expectation(description: "Request should succeed.")
  957. var response: DownloadResponse<URL?, AFError>?
  958. // When
  959. AF.download(fileURL)
  960. .response { resp in
  961. response = resp
  962. expectation.fulfill()
  963. }
  964. waitForExpectations(timeout: timeout)
  965. // Then
  966. XCTAssertEqual(response?.result.isSuccess, true)
  967. }
  968. func testThatDataStreamRequestWithFileURLThrowsError() {
  969. // Given
  970. let fileURL = url(forResource: "valid_data", withExtension: "json")
  971. let expectation = self.expectation(description: "Request should succeed.")
  972. var response: DataStreamRequest.Completion?
  973. // When
  974. AF.streamRequest(fileURL)
  975. .responseStream { stream in
  976. guard case let .complete(completion) = stream.event else { return }
  977. response = completion
  978. expectation.fulfill()
  979. }
  980. waitForExpectations(timeout: timeout)
  981. // Then
  982. XCTAssertNil(response?.response)
  983. }
  984. }
  985. #endif