RequestTests.swift 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  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 Testing
  27. import XCTest
  28. final class RequestResponseTestCase: BaseTestCase {
  29. @MainActor
  30. func testRequestResponse() {
  31. // Given
  32. let url = Endpoint.get.url
  33. let expectation = expectation(description: "GET request should succeed: \(url)")
  34. var response: DataResponse<Data?, AFError>?
  35. // When
  36. AF.request(url, parameters: ["foo": "bar"])
  37. .response { resp in
  38. response = resp
  39. expectation.fulfill()
  40. }
  41. waitForExpectations(timeout: timeout)
  42. // Then
  43. XCTAssertNotNil(response?.request)
  44. XCTAssertNotNil(response?.response)
  45. XCTAssertNotNil(response?.data)
  46. XCTAssertNil(response?.error)
  47. }
  48. @MainActor
  49. func testThatDataRequestReceivesInitialResponse() {
  50. // Given
  51. let url = Endpoint.get.url
  52. var initialResponse: HTTPURLResponse?
  53. let didReceiveResponse = expectation(description: "didReceiveResponse")
  54. let didComplete = expectation(description: "GET request should succeed: \(url)")
  55. var response: DataResponse<Data?, AFError>?
  56. // When
  57. AF.request(url, parameters: ["foo": "bar"])
  58. .onHTTPResponse { response in
  59. initialResponse = response
  60. didReceiveResponse.fulfill()
  61. }
  62. .response { resp in
  63. response = resp
  64. didComplete.fulfill()
  65. }
  66. wait(for: [didReceiveResponse, didComplete], timeout: timeout, enforceOrder: true)
  67. // Then
  68. XCTAssertEqual(initialResponse, response?.response)
  69. XCTAssertNotNil(response?.request)
  70. XCTAssertNotNil(response?.response)
  71. XCTAssertNotNil(response?.data)
  72. XCTAssertNil(response?.error)
  73. }
  74. @MainActor
  75. func testThatDataRequestOnHTTPResponseCanAllow() {
  76. // Given
  77. let url = Endpoint.get.url
  78. var initialResponse: HTTPURLResponse?
  79. let didReceiveResponse = expectation(description: "didReceiveResponse")
  80. let didComplete = expectation(description: "GET request should succeed: \(url)")
  81. var response: DataResponse<Data?, AFError>?
  82. // When
  83. AF.request(url, parameters: ["foo": "bar"])
  84. .onHTTPResponse { response, completionHandler in
  85. initialResponse = response
  86. didReceiveResponse.fulfill()
  87. completionHandler(.allow)
  88. }
  89. .response { resp in
  90. response = resp
  91. didComplete.fulfill()
  92. }
  93. wait(for: [didReceiveResponse, didComplete], timeout: timeout, enforceOrder: true)
  94. // Then
  95. XCTAssertEqual(initialResponse, response?.response)
  96. XCTAssertNotNil(response?.request)
  97. XCTAssertNotNil(response?.response)
  98. XCTAssertNotNil(response?.data)
  99. XCTAssertNil(response?.error)
  100. }
  101. @MainActor
  102. func testThatDataRequestOnHTTPResponseCanCancel() {
  103. // Given
  104. let url = Endpoint.get.url
  105. var initialResponse: HTTPURLResponse?
  106. let didReceiveResponse = expectation(description: "didReceiveResponse")
  107. let didComplete = expectation(description: "GET request should succeed: \(url)")
  108. var response: DataResponse<Data?, AFError>?
  109. // When
  110. let request = AF.request(url, parameters: ["foo": "bar"])
  111. .onHTTPResponse { response, completionHandler in
  112. initialResponse = response
  113. didReceiveResponse.fulfill()
  114. completionHandler(.cancel)
  115. }
  116. .response { resp in
  117. response = resp
  118. didComplete.fulfill()
  119. }
  120. wait(for: [didReceiveResponse, didComplete], timeout: timeout, enforceOrder: true)
  121. // Then
  122. XCTAssertEqual(initialResponse, response?.response)
  123. XCTAssertNotNil(response?.request)
  124. XCTAssertNotNil(response?.response)
  125. XCTAssertNil(response?.data)
  126. XCTAssertTrue(request.isCancelled, "onHTTPResponse cancelled request should have isCancelled == true")
  127. XCTAssertTrue(response?.error?.isExplicitlyCancelledError == true, "onHTTPResponse cancelled request should be explicitly cancelled")
  128. }
  129. @MainActor
  130. func testRequestResponseWithProgress() {
  131. // Given
  132. let byteCount = 512
  133. let url = Endpoint.bytes(byteCount).url
  134. let expectation = expectation(description: "Bytes download progress should be reported: \(url)")
  135. var progressValues: [Double] = []
  136. var response: DataResponse<Data?, AFError>?
  137. // When
  138. AF.request(url)
  139. .downloadProgress { progress in
  140. progressValues.append(progress.fractionCompleted)
  141. }
  142. .response { resp in
  143. response = resp
  144. expectation.fulfill()
  145. }
  146. waitForExpectations(timeout: timeout)
  147. // Then
  148. XCTAssertNotNil(response?.request)
  149. XCTAssertNotNil(response?.response)
  150. XCTAssertNotNil(response?.data)
  151. XCTAssertNil(response?.error)
  152. var previousProgress: Double = progressValues.first ?? 0.0
  153. for progress in progressValues {
  154. XCTAssertGreaterThanOrEqual(progress, previousProgress)
  155. previousProgress = progress
  156. }
  157. if let lastProgressValue = progressValues.last {
  158. XCTAssertEqual(lastProgressValue, 1.0)
  159. } else {
  160. XCTFail("last item in progressValues should not be nil")
  161. }
  162. }
  163. @MainActor
  164. func testPOSTRequestWithUnicodeParameters() {
  165. // Given
  166. let parameters = ["french": "français",
  167. "japanese": "日本語",
  168. "arabic": "العربية",
  169. "emoji": "😃"]
  170. let expectation = expectation(description: "request should succeed")
  171. var response: DataResponse<TestResponse, AFError>?
  172. // When
  173. AF.request(.method(.post), parameters: parameters)
  174. .responseDecodable(of: TestResponse.self) { closureResponse in
  175. response = closureResponse
  176. expectation.fulfill()
  177. }
  178. waitForExpectations(timeout: timeout)
  179. // Then
  180. XCTAssertNotNil(response?.request)
  181. XCTAssertNotNil(response?.response)
  182. XCTAssertNotNil(response?.data)
  183. if let form = response?.result.success?.form {
  184. XCTAssertEqual(form["french"], parameters["french"])
  185. XCTAssertEqual(form["japanese"], parameters["japanese"])
  186. XCTAssertEqual(form["arabic"], parameters["arabic"])
  187. XCTAssertEqual(form["emoji"], parameters["emoji"])
  188. } else {
  189. XCTFail("form parameter in JSON should not be nil")
  190. }
  191. }
  192. @MainActor
  193. func testPOSTRequestWithBase64EncodedImages() {
  194. // Given
  195. let pngBase64EncodedString: String = {
  196. let fileURL = url(forResource: "unicorn", withExtension: "png")
  197. let data = try! Data(contentsOf: fileURL)
  198. return data.base64EncodedString(options: .lineLength64Characters)
  199. }()
  200. let jpegBase64EncodedString: String = {
  201. let fileURL = url(forResource: "rainbow", withExtension: "jpg")
  202. let data = try! Data(contentsOf: fileURL)
  203. return data.base64EncodedString(options: .lineLength64Characters)
  204. }()
  205. let parameters = ["email": "user@alamofire.org",
  206. "png_image": pngBase64EncodedString,
  207. "jpeg_image": jpegBase64EncodedString]
  208. let expectation = expectation(description: "request should succeed")
  209. var response: DataResponse<TestResponse, AFError>?
  210. // When
  211. AF.request(Endpoint.method(.post), method: .post, parameters: parameters)
  212. .responseDecodable(of: TestResponse.self) { closureResponse in
  213. response = closureResponse
  214. expectation.fulfill()
  215. }
  216. waitForExpectations(timeout: timeout)
  217. // Then
  218. XCTAssertNotNil(response?.request)
  219. XCTAssertNotNil(response?.response)
  220. XCTAssertNotNil(response?.data)
  221. XCTAssertEqual(response?.result.isSuccess, true)
  222. if let form = response?.result.success?.form {
  223. XCTAssertEqual(form["email"], parameters["email"])
  224. XCTAssertEqual(form["png_image"], parameters["png_image"])
  225. XCTAssertEqual(form["jpeg_image"], parameters["jpeg_image"])
  226. } else {
  227. XCTFail("form parameter in JSON should not be nil")
  228. }
  229. }
  230. // MARK: Queues
  231. @MainActor
  232. func testThatResponseSerializationWorksWithSerializationQueue() {
  233. // Given
  234. let queue = DispatchQueue(label: "org.alamofire.testSerializationQueue")
  235. let manager = Session(serializationQueue: queue)
  236. let expectation = expectation(description: "request should complete")
  237. var response: DataResponse<TestResponse, AFError>?
  238. // When
  239. manager.request(.get).responseDecodable(of: TestResponse.self) { resp in
  240. response = resp
  241. expectation.fulfill()
  242. }
  243. waitForExpectations(timeout: timeout)
  244. // Then
  245. XCTAssertEqual(response?.result.isSuccess, true)
  246. }
  247. @MainActor
  248. func testThatRequestsWorksWithRequestAndSerializationQueues() {
  249. // Given
  250. let requestQueue = DispatchQueue(label: "org.alamofire.testRequestQueue")
  251. let serializationQueue = DispatchQueue(label: "org.alamofire.testSerializationQueue")
  252. let manager = Session(requestQueue: requestQueue, serializationQueue: serializationQueue)
  253. let expectation = expectation(description: "request should complete")
  254. var response: DataResponse<TestResponse, AFError>?
  255. // When
  256. manager.request(.get).responseDecodable(of: TestResponse.self) { resp in
  257. response = resp
  258. expectation.fulfill()
  259. }
  260. waitForExpectations(timeout: timeout)
  261. // Then
  262. XCTAssertEqual(response?.result.isSuccess, true)
  263. }
  264. @MainActor
  265. func testThatRequestsWorksWithConcurrentRequestAndSerializationQueues() {
  266. // Given
  267. let requestQueue = DispatchQueue(label: "org.alamofire.testRequestQueue", attributes: .concurrent)
  268. let serializationQueue = DispatchQueue(label: "org.alamofire.testSerializationQueue", attributes: .concurrent)
  269. let session = Session(requestQueue: requestQueue, serializationQueue: serializationQueue)
  270. let count = 10
  271. let expectation = expectation(description: "request should complete")
  272. expectation.expectedFulfillmentCount = count
  273. var responses: [DataResponse<TestResponse, AFError>] = []
  274. // When
  275. DispatchQueue.concurrentPerform(iterations: count) { _ in
  276. session.request(.default).responseDecodable(of: TestResponse.self) { resp in
  277. responses.append(resp)
  278. expectation.fulfill()
  279. }
  280. }
  281. waitForExpectations(timeout: timeout, handler: nil)
  282. // Then
  283. XCTAssertEqual(responses.count, count)
  284. XCTAssertTrue(responses.allSatisfy(\.result.isSuccess))
  285. }
  286. // MARK: Encodable Parameters
  287. @MainActor
  288. func testThatRequestsCanPassEncodableParametersAsJSONBodyData() {
  289. // Given
  290. let parameters = TestParameters(property: "one")
  291. let expect = expectation(description: "request should complete")
  292. var receivedResponse: DataResponse<TestResponse, AFError>?
  293. // When
  294. AF.request(.method(.post), parameters: parameters, encoder: JSONParameterEncoder.default)
  295. .responseDecodable(of: TestResponse.self) { response in
  296. receivedResponse = response
  297. expect.fulfill()
  298. }
  299. waitForExpectations(timeout: timeout)
  300. // Then
  301. XCTAssertEqual(receivedResponse?.result.success?.data, "{\"property\":\"one\"}")
  302. }
  303. @MainActor
  304. func testThatRequestsCanPassEncodableParametersAsAURLQuery() {
  305. // Given
  306. let parameters = TestParameters(property: "one")
  307. let expect = expectation(description: "request should complete")
  308. var receivedResponse: DataResponse<TestResponse, AFError>?
  309. // When
  310. AF.request(.method(.get), parameters: parameters)
  311. .responseDecodable(of: TestResponse.self) { response in
  312. receivedResponse = response
  313. expect.fulfill()
  314. }
  315. waitForExpectations(timeout: timeout)
  316. // Then
  317. XCTAssertEqual(receivedResponse?.result.success?.args, ["property": "one"])
  318. }
  319. @MainActor
  320. func testThatRequestsCanPassEncodableParametersAsURLEncodedBodyData() {
  321. // Given
  322. let parameters = TestParameters(property: "one")
  323. let expect = expectation(description: "request should complete")
  324. var receivedResponse: DataResponse<TestResponse, AFError>?
  325. // When
  326. AF.request(.method(.post), parameters: parameters)
  327. .responseDecodable(of: TestResponse.self) { response in
  328. receivedResponse = response
  329. expect.fulfill()
  330. }
  331. waitForExpectations(timeout: timeout)
  332. // Then
  333. XCTAssertEqual(receivedResponse?.result.success?.form, ["property": "one"])
  334. }
  335. // MARK: Lifetime Events
  336. @MainActor
  337. func testThatAutomaticallyResumedRequestReceivesAppropriateLifetimeEvents() {
  338. // Given
  339. let eventMonitor = ClosureEventMonitor()
  340. let session = Session(eventMonitors: [eventMonitor])
  341. let expect = expectation(description: "request should receive appropriate lifetime events")
  342. expect.expectedFulfillmentCount = 4
  343. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  344. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  345. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  346. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  347. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  348. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  349. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  350. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  351. // When
  352. let request = session.request(.default).response { _ in expect.fulfill() }
  353. waitForExpectations(timeout: timeout)
  354. // Then
  355. XCTAssertEqual(request.state, .finished)
  356. }
  357. @MainActor
  358. func testThatInstanceAutomaticallyResumedRequestReceivesAppropriateLifetimeEvents() {
  359. // Given
  360. let eventMonitor = ClosureEventMonitor()
  361. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  362. let expect = expectation(description: "request should receive appropriate lifetime events")
  363. expect.expectedFulfillmentCount = 4
  364. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  365. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  366. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  367. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  368. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  369. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  370. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  371. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  372. // When
  373. let request = session.request(.default, shouldAutomaticallyResume: true).response { _ in expect.fulfill() }
  374. waitForExpectations(timeout: timeout)
  375. // Then
  376. XCTAssertEqual(request.state, .finished)
  377. }
  378. @MainActor
  379. func testThatAutomaticallyAndManuallyResumedRequestReceivesAppropriateLifetimeEvents() {
  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 = 4
  385. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  386. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  387. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  388. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  389. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  390. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  391. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  392. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  393. // When
  394. let request = session.request(.default).response { _ in expect.fulfill() }
  395. for _ in 0..<100 {
  396. request.resume()
  397. }
  398. waitForExpectations(timeout: timeout)
  399. // Then
  400. XCTAssertEqual(request.state, .finished)
  401. }
  402. @MainActor
  403. func testThatManuallyResumedRequestReceivesAppropriateLifetimeEvents() {
  404. // Given
  405. let eventMonitor = ClosureEventMonitor()
  406. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  407. let expect = expectation(description: "request should receive appropriate lifetime events")
  408. expect.expectedFulfillmentCount = 3
  409. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  410. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  411. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  412. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  413. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  414. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  415. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  416. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  417. // When
  418. let request = session.request(.default)
  419. for _ in 0..<100 {
  420. request.resume()
  421. }
  422. waitForExpectations(timeout: timeout)
  423. // Then
  424. XCTAssertEqual(request.state, .finished)
  425. }
  426. @MainActor
  427. func testThatInstanceManuallyResumedRequestReceivesAppropriateLifetimeEvents() {
  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 = 3
  433. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  434. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  435. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  436. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  437. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  438. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  439. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  440. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  441. // When
  442. let request = session.request(.default, shouldAutomaticallyResume: false)
  443. for _ in 0..<100 {
  444. request.resume()
  445. }
  446. waitForExpectations(timeout: timeout)
  447. // Then
  448. XCTAssertEqual(request.state, .finished)
  449. }
  450. @MainActor
  451. func testThatRequestManuallyResumedManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  452. // Given
  453. let eventMonitor = ClosureEventMonitor()
  454. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  455. let expect = expectation(description: "request should receive appropriate lifetime events")
  456. expect.expectedFulfillmentCount = 4
  457. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  458. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  459. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  460. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  461. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  462. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  463. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  464. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  465. // When
  466. let request = session.request(.default).response { _ in expect.fulfill() }
  467. for _ in 0..<100 {
  468. request.resume()
  469. }
  470. waitForExpectations(timeout: timeout)
  471. // Then
  472. XCTAssertEqual(request.state, .finished)
  473. }
  474. @MainActor
  475. func testThatRequestInstanceManuallyResumedManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  476. // Given
  477. let eventMonitor = ClosureEventMonitor()
  478. let session = Session(eventMonitors: [eventMonitor])
  479. let expect = expectation(description: "request should receive appropriate lifetime events")
  480. expect.expectedFulfillmentCount = 4
  481. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  482. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  483. eventMonitor.requestDidFinish = { _ in expect.fulfill() }
  484. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  485. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  486. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  487. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  488. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  489. // When
  490. let request = session.request(.default, shouldAutomaticallyResume: false).response { _ in expect.fulfill() }
  491. for _ in 0..<100 {
  492. request.resume()
  493. }
  494. waitForExpectations(timeout: timeout)
  495. // Then
  496. XCTAssertEqual(request.state, .finished)
  497. }
  498. @MainActor
  499. func testThatRequestManuallySuspendedManyTimesAfterAutomaticResumeOnlyReceivesAppropriateLifetimeEvents() {
  500. // Given
  501. let eventMonitor = ClosureEventMonitor()
  502. let session = Session(startRequestsImmediately: false, requestSetup: .eager, eventMonitors: [eventMonitor])
  503. let expect = expectation(description: "request should receive appropriate lifetime events")
  504. expect.expectedFulfillmentCount = 2
  505. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  506. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  507. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  508. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  509. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  510. // When
  511. let request = session.request(.default)
  512. for _ in 0..<100 {
  513. request.suspend()
  514. }
  515. waitForExpectations(timeout: timeout)
  516. // Then
  517. XCTAssertEqual(request.state, .suspended)
  518. }
  519. @MainActor
  520. func testThatRequestManuallySuspendedManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  521. // Given
  522. let eventMonitor = ClosureEventMonitor()
  523. let session = Session(startRequestsImmediately: false, requestSetup: .eager, eventMonitors: [eventMonitor])
  524. let expect = expectation(description: "request should receive appropriate lifetime events")
  525. expect.expectedFulfillmentCount = 2
  526. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  527. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  528. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  529. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  530. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  531. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  532. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  533. // When
  534. let request = session.request(.default)
  535. for _ in 0..<100 {
  536. request.suspend()
  537. }
  538. waitForExpectations(timeout: timeout)
  539. // Then
  540. XCTAssertEqual(request.state, .suspended)
  541. }
  542. @MainActor
  543. func testThatRequestManuallyCancelledManyTimesAfterAutomaticResumeOnlyReceivesAppropriateLifetimeEvents() {
  544. // Given
  545. let eventMonitor = ClosureEventMonitor()
  546. let session = Session(requestSetup: .eager, eventMonitors: [eventMonitor])
  547. let expect = expectation(description: "request should receive appropriate lifetime events")
  548. expect.expectedFulfillmentCount = 2
  549. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  550. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  551. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  552. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  553. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  554. // When
  555. let request = session.request(.default)
  556. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  557. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  558. for _ in 0..<100 {
  559. request.cancel()
  560. }
  561. }
  562. waitForExpectations(timeout: timeout)
  563. // Then
  564. XCTAssertEqual(request.state, .cancelled)
  565. }
  566. @MainActor
  567. func testThatRequestManuallyCancelledManyTimesOnlyReceivesAppropriateLifetimeEvents() {
  568. // Given
  569. let eventMonitor = ClosureEventMonitor()
  570. let session = Session(startRequestsImmediately: false, requestSetup: .eager, eventMonitors: [eventMonitor])
  571. let expect = expectation(description: "request should receive appropriate lifetime events")
  572. expect.expectedFulfillmentCount = 2
  573. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  574. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  575. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  576. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  577. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  578. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  579. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  580. // When
  581. let request = session.request(.default)
  582. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  583. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  584. for _ in 0..<100 {
  585. request.cancel()
  586. }
  587. }
  588. waitForExpectations(timeout: timeout)
  589. // Then
  590. XCTAssertEqual(request.state, .cancelled)
  591. }
  592. @MainActor
  593. func testThatRequestManuallyCancelledManyTimesOnManyQueuesOnlyReceivesAppropriateLifetimeEvents() {
  594. // Given
  595. let eventMonitor = ClosureEventMonitor()
  596. let session = Session(eventMonitors: [eventMonitor])
  597. let expect = expectation(description: "request should receive appropriate lifetime events")
  598. expect.expectedFulfillmentCount = 6
  599. eventMonitor.requestDidCancelTask = { _, _ in expect.fulfill() }
  600. eventMonitor.requestDidCancel = { _ in expect.fulfill() }
  601. eventMonitor.requestDidResume = { _ in expect.fulfill() }
  602. eventMonitor.requestDidResumeTask = { _, _ in expect.fulfill() }
  603. // Fulfill other events that would exceed the expected count. Inverted expectations require the full timeout.
  604. eventMonitor.requestDidSuspend = { _ in expect.fulfill() }
  605. eventMonitor.requestDidSuspendTask = { _, _ in expect.fulfill() }
  606. // When
  607. let request = session.request(.delay(5)).response { _ in expect.fulfill() }
  608. // Cancellation stops task creation, so don't cancel the request until the task has been created.
  609. eventMonitor.requestDidCreateTask = { [unowned request] _, _ in
  610. DispatchQueue.concurrentPerform(iterations: 100) { i in
  611. request.cancel()
  612. if i == 99 { expect.fulfill() }
  613. }
  614. }
  615. waitForExpectations(timeout: timeout)
  616. // Then
  617. XCTAssertEqual(request.state, .cancelled)
  618. }
  619. @MainActor
  620. func testThatRequestTriggersAllAppropriateLifetimeEvents() {
  621. // Given
  622. let eventMonitor = ClosureEventMonitor()
  623. let session = Session(eventMonitors: [eventMonitor])
  624. // Disable event test until Firewalk support HTTPS.
  625. // let didReceiveChallenge = expectation(description: "didReceiveChallenge should fire")
  626. let taskDidFinishCollecting = expectation(description: "taskDidFinishCollecting should fire")
  627. let didReceiveData = expectation(description: "didReceiveData should fire")
  628. let willCacheResponse = expectation(description: "willCacheResponse should fire")
  629. let didCreateURLRequest = expectation(description: "didCreateInitialURLRequest should fire")
  630. let didCreateTask = expectation(description: "didCreateTask should fire")
  631. let didGatherMetrics = expectation(description: "didGatherMetrics should fire")
  632. let didComplete = expectation(description: "didComplete should fire")
  633. let didFinish = expectation(description: "didFinish should fire")
  634. let didResume = expectation(description: "didResume should fire")
  635. let didResumeTask = expectation(description: "didResumeTask should fire")
  636. let didParseResponse = expectation(description: "didParseResponse should fire")
  637. let responseHandler = expectation(description: "responseHandler should fire")
  638. var dataReceived = false
  639. // Disable event test until Firewalk supports HTTPS.
  640. // eventMonitor.taskDidReceiveChallenge = { _, _, _ in didReceiveChallenge.fulfill() }
  641. eventMonitor.taskDidFinishCollectingMetrics = { _, _, _ in taskDidFinishCollecting.fulfill() }
  642. eventMonitor.dataTaskDidReceiveData = { _, _, _ in
  643. guard !dataReceived else { return }
  644. // Data may be received many times, fulfill only once.
  645. dataReceived = true
  646. didReceiveData.fulfill()
  647. }
  648. eventMonitor.dataTaskWillCacheResponse = { _, _, _ in willCacheResponse.fulfill() }
  649. eventMonitor.requestDidCreateInitialURLRequest = { _, _ in didCreateURLRequest.fulfill() }
  650. eventMonitor.requestDidCreateTask = { _, _ in didCreateTask.fulfill() }
  651. eventMonitor.requestDidGatherMetrics = { _, _ in didGatherMetrics.fulfill() }
  652. eventMonitor.requestDidCompleteTaskWithError = { _, _, _ in didComplete.fulfill() }
  653. eventMonitor.requestDidFinish = { _ in didFinish.fulfill() }
  654. eventMonitor.requestDidResume = { _ in didResume.fulfill() }
  655. eventMonitor.requestDidResumeTask = { _, _ in didResumeTask.fulfill() }
  656. eventMonitor.requestDidParseResponse = { _, _ in didParseResponse.fulfill() }
  657. // When
  658. let request = session.request(.default).response { _ in
  659. responseHandler.fulfill()
  660. }
  661. waitForExpectations(timeout: timeout)
  662. // Then
  663. XCTAssertEqual(request.state, .finished)
  664. }
  665. @MainActor
  666. func testThatCancelledRequestTriggersAllAppropriateLifetimeEvents() {
  667. // Given
  668. let eventMonitor = ClosureEventMonitor()
  669. let session = Session(startRequestsImmediately: false, eventMonitors: [eventMonitor])
  670. let taskDidFinishCollecting = expectation(description: "taskDidFinishCollecting should fire")
  671. let didCreateURLRequest = expectation(description: "didCreateInitialURLRequest should fire")
  672. let didCreateTask = expectation(description: "didCreateTask should fire")
  673. let didGatherMetrics = expectation(description: "didGatherMetrics should fire")
  674. let didComplete = expectation(description: "didComplete should fire")
  675. let didFinish = expectation(description: "didFinish should fire")
  676. let didResume = expectation(description: "didResume should fire")
  677. let didResumeTask = expectation(description: "didResumeTask should fire")
  678. let didParseResponse = expectation(description: "didParseResponse should fire")
  679. let didCancel = expectation(description: "didCancel should fire")
  680. let didCancelTask = expectation(description: "didCancelTask should fire")
  681. let responseHandler = expectation(description: "responseHandler should fire")
  682. eventMonitor.taskDidFinishCollectingMetrics = { _, _, _ in taskDidFinishCollecting.fulfill() }
  683. eventMonitor.requestDidCreateInitialURLRequest = { _, _ in didCreateURLRequest.fulfill() }
  684. eventMonitor.requestDidCreateTask = { _, _ in didCreateTask.fulfill() }
  685. eventMonitor.requestDidGatherMetrics = { _, _ in didGatherMetrics.fulfill() }
  686. eventMonitor.requestDidCompleteTaskWithError = { _, _, _ in didComplete.fulfill() }
  687. eventMonitor.requestDidFinish = { _ in didFinish.fulfill() }
  688. eventMonitor.requestDidResume = { _ in didResume.fulfill() }
  689. eventMonitor.requestDidParseResponse = { _, _ in didParseResponse.fulfill() }
  690. eventMonitor.requestDidCancel = { _ in didCancel.fulfill() }
  691. eventMonitor.requestDidCancelTask = { _, _ in didCancelTask.fulfill() }
  692. // When
  693. let request = session.request(.delay(5)).response { _ in
  694. responseHandler.fulfill()
  695. }
  696. eventMonitor.requestDidResumeTask = { [unowned request] _, _ in
  697. request.cancel()
  698. didResumeTask.fulfill()
  699. }
  700. request.resume()
  701. waitForExpectations(timeout: timeout)
  702. // Then
  703. XCTAssertEqual(request.state, .cancelled)
  704. }
  705. @MainActor
  706. func testThatAppendingResponseSerializerToCancelledRequestCallsCompletion() {
  707. // Given
  708. let session = Session()
  709. var response1: DataResponse<TestResponse, AFError>?
  710. var response2: DataResponse<TestResponse, AFError>?
  711. let expect = expectation(description: "both response serializer completions should be called")
  712. expect.expectedFulfillmentCount = 2
  713. // When
  714. let request = session.request(.default)
  715. request.responseDecodable(of: TestResponse.self) { resp in
  716. response1 = resp
  717. expect.fulfill()
  718. request.responseDecodable(of: TestResponse.self) { resp in
  719. response2 = resp
  720. expect.fulfill()
  721. }
  722. }
  723. request.cancel()
  724. waitForExpectations(timeout: timeout)
  725. // Then
  726. XCTAssertEqual(response1?.error?.isExplicitlyCancelledError, true)
  727. XCTAssertEqual(response2?.error?.isExplicitlyCancelledError, true)
  728. }
  729. @MainActor
  730. func testThatAppendingResponseSerializerToCompletedRequestInsideCompletionResumesRequest() {
  731. // Given
  732. let session = Session()
  733. var response1: DataResponse<TestResponse, AFError>?
  734. var response2: DataResponse<TestResponse, AFError>?
  735. var response3: DataResponse<TestResponse, AFError>?
  736. let expect = expectation(description: "all response serializer completions should be called")
  737. expect.expectedFulfillmentCount = 3
  738. // When
  739. let request = session.request(.default)
  740. request.responseDecodable(of: TestResponse.self) { resp in
  741. response1 = resp
  742. expect.fulfill()
  743. request.responseDecodable(of: TestResponse.self) { resp in
  744. response2 = resp
  745. expect.fulfill()
  746. request.responseDecodable(of: TestResponse.self) { resp in
  747. response3 = resp
  748. expect.fulfill()
  749. }
  750. }
  751. }
  752. waitForExpectations(timeout: timeout)
  753. // Then
  754. XCTAssertNotNil(response1?.value)
  755. XCTAssertNotNil(response2?.value)
  756. XCTAssertNotNil(response3?.value)
  757. }
  758. @MainActor
  759. func testThatAppendingResponseSerializerToCompletedRequestOutsideCompletionResumesRequest() {
  760. // Given
  761. let session = Session()
  762. let request = session.request(.default)
  763. var response1: DataResponse<TestResponse, AFError>?
  764. var response2: DataResponse<TestResponse, AFError>?
  765. var response3: DataResponse<TestResponse, AFError>?
  766. // When
  767. let expect1 = expectation(description: "response serializer 1 completion should be called")
  768. request.responseDecodable(of: TestResponse.self) { response1 = $0; expect1.fulfill() }
  769. waitForExpectations(timeout: timeout)
  770. let expect2 = expectation(description: "response serializer 2 completion should be called")
  771. request.responseDecodable(of: TestResponse.self) { response2 = $0; expect2.fulfill() }
  772. waitForExpectations(timeout: timeout)
  773. let expect3 = expectation(description: "response serializer 3 completion should be called")
  774. request.responseDecodable(of: TestResponse.self) { response3 = $0; expect3.fulfill() }
  775. waitForExpectations(timeout: timeout)
  776. // Then
  777. XCTAssertNotNil(response1?.value)
  778. XCTAssertNotNil(response2?.value)
  779. XCTAssertNotNil(response3?.value)
  780. }
  781. }
  782. // MARK: -
  783. final class RequestDescriptionTestCase: BaseTestCase {
  784. @MainActor
  785. func testRequestDescription() {
  786. // Given
  787. let url = Endpoint().url
  788. let manager = Session(startRequestsImmediately: false)
  789. let request = manager.request(url)
  790. let expectation = expectation(description: "Request description should update: \(url)")
  791. var response: HTTPURLResponse?
  792. // When
  793. request.response { resp in
  794. response = resp.response
  795. expectation.fulfill()
  796. }.resume()
  797. waitForExpectations(timeout: timeout)
  798. // Then
  799. XCTAssertEqual(request.description, "GET \(url) (\(response?.statusCode ?? -1))")
  800. }
  801. }
  802. // MARK: -
  803. final class RequestCURLDescriptionTestCase: BaseTestCase {
  804. // MARK: Properties
  805. let session: Session = .init(requestSetup: .eager)
  806. let sessionWithAcceptLanguageHeader: Session = {
  807. var headers = HTTPHeaders.default
  808. headers["Accept-Language"] = "en-US"
  809. let configuration = URLSessionConfiguration.af.default
  810. configuration.headers = headers
  811. return Session(configuration: configuration, requestSetup: .eager)
  812. }()
  813. let sessionWithContentTypeHeader: Session = {
  814. var headers = HTTPHeaders.default
  815. headers["Content-Type"] = "application/json"
  816. let configuration = URLSessionConfiguration.af.default
  817. configuration.headers = headers
  818. return Session(configuration: configuration, requestSetup: .eager)
  819. }()
  820. func sessionWithCookie(_ cookie: HTTPCookie) -> Session {
  821. let configuration = URLSessionConfiguration.af.default
  822. configuration.httpCookieStorage?.setCookie(cookie)
  823. return Session(configuration: configuration, requestSetup: .eager)
  824. }
  825. let sessionDisallowingCookies: Session = {
  826. let configuration = URLSessionConfiguration.af.default
  827. configuration.httpShouldSetCookies = false
  828. return Session(configuration: configuration, requestSetup: .eager)
  829. }()
  830. // MARK: Tests
  831. @MainActor
  832. func testGETRequestCURLDescription() {
  833. // Given
  834. let url = Endpoint().url
  835. let expectation = expectation(description: "request should complete")
  836. var components: [String]?
  837. // When
  838. session.request(url).cURLDescription {
  839. components = self.cURLCommandComponents(from: $0)
  840. expectation.fulfill()
  841. }
  842. // requires eager perform
  843. waitForExpectations(timeout: timeout)
  844. // Then
  845. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  846. XCTAssertTrue(components?.contains("-X") == true)
  847. XCTAssertEqual(components?.last, "\"\(url)\"")
  848. }
  849. @MainActor
  850. func testGETRequestCURLDescriptionOnMainQueue() {
  851. // Given
  852. let url = Endpoint().url
  853. let expectation = expectation(description: "request should complete")
  854. var isMainThread = false
  855. var components: [String]?
  856. // When
  857. session.request(url).cURLDescription(on: .main) {
  858. components = self.cURLCommandComponents(from: $0)
  859. isMainThread = Thread.isMainThread
  860. expectation.fulfill()
  861. }
  862. waitForExpectations(timeout: timeout, handler: nil)
  863. // Then
  864. XCTAssertTrue(isMainThread)
  865. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  866. XCTAssertTrue(components?.contains("-X") == true)
  867. XCTAssertEqual(components?.last, "\"\(url)\"")
  868. }
  869. @MainActor
  870. func testGETRequestCURLDescriptionSynchronous() {
  871. // Given
  872. let url = Endpoint().url
  873. let expectation = expectation(description: "request should complete")
  874. var components: [String]?
  875. var syncComponents: [String]?
  876. // When
  877. let request = session.request(url)
  878. request.cURLDescription {
  879. components = self.cURLCommandComponents(from: $0)
  880. syncComponents = self.cURLCommandComponents(from: request.cURLDescription())
  881. expectation.fulfill()
  882. }
  883. waitForExpectations(timeout: timeout)
  884. // Then
  885. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  886. XCTAssertTrue(components?.contains("-X") == true)
  887. XCTAssertEqual(components?.last, "\"\(url)\"")
  888. XCTAssertEqual(components?.sorted(), syncComponents?.sorted())
  889. }
  890. @MainActor
  891. func testGETRequestCURLDescriptionCanBeRequestedManyTimes() {
  892. // Given
  893. let url = Endpoint().url
  894. let expectation = expectation(description: "request should complete")
  895. var components: [String]?
  896. var secondComponents: [String]?
  897. // When
  898. let request = session.request(url)
  899. request.cURLDescription {
  900. components = self.cURLCommandComponents(from: $0)
  901. request.cURLDescription {
  902. secondComponents = self.cURLCommandComponents(from: $0)
  903. expectation.fulfill()
  904. }
  905. }
  906. waitForExpectations(timeout: timeout)
  907. // Then
  908. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  909. XCTAssertTrue(components?.contains("-X") == true)
  910. XCTAssertEqual(components?.last, "\"\(url)\"")
  911. XCTAssertEqual(components?.sorted(), secondComponents?.sorted())
  912. }
  913. @MainActor
  914. func testGETRequestWithCustomHeaderCURLDescription() {
  915. // Given
  916. let url = Endpoint().url
  917. let expectation = expectation(description: "request should complete")
  918. var cURLDescription: String?
  919. // When
  920. let headers: HTTPHeaders = ["X-Custom-Header": "{\"key\": \"value\"}"]
  921. session.request(url, headers: headers).cURLDescription {
  922. cURLDescription = $0
  923. expectation.fulfill()
  924. }
  925. waitForExpectations(timeout: timeout)
  926. // Then
  927. XCTAssertNotNil(cURLDescription?.range(of: "-H \"X-Custom-Header: {\\\"key\\\": \\\"value\\\"}\""))
  928. }
  929. @MainActor
  930. func testGETRequestWithDuplicateHeadersDebugDescription() {
  931. // Given
  932. let url = Endpoint().url
  933. let expectation = expectation(description: "request should complete")
  934. var cURLDescription: String?
  935. var components: [String]?
  936. // When
  937. let headers: HTTPHeaders = ["Accept-Language": "en-GB"]
  938. sessionWithAcceptLanguageHeader.request(url, headers: headers).cURLDescription {
  939. components = self.cURLCommandComponents(from: $0)
  940. cURLDescription = $0
  941. expectation.fulfill()
  942. }
  943. waitForExpectations(timeout: timeout)
  944. // Then
  945. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  946. XCTAssertTrue(components?.contains("-X") == true)
  947. XCTAssertEqual(components?.last, "\"\(url)\"")
  948. let acceptLanguageCount = components?.count(where: { $0.contains("Accept-Language") })
  949. XCTAssertEqual(acceptLanguageCount, 1, "command should contain a single Accept-Language header")
  950. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Accept-Language: en-GB\""))
  951. }
  952. @MainActor
  953. func testPOSTRequestCURLDescription() {
  954. // Given
  955. let url = Endpoint.method(.post).url
  956. let expectation = expectation(description: "request should complete")
  957. var components: [String]?
  958. // When
  959. session.request(url, method: .post).cURLDescription {
  960. components = self.cURLCommandComponents(from: $0)
  961. expectation.fulfill()
  962. }
  963. waitForExpectations(timeout: timeout)
  964. // Then
  965. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  966. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  967. XCTAssertEqual(components?.last, "\"\(url)\"")
  968. }
  969. @MainActor
  970. func testPOSTRequestWithJSONParametersCURLDescription() {
  971. // Given
  972. let url = Endpoint.method(.post).url
  973. let expectation = expectation(description: "request should complete")
  974. var cURLDescription: String?
  975. var components: [String]?
  976. let parameters = ["foo": "bar",
  977. "fo\"o": "b\"ar",
  978. "f'oo": "ba'r"]
  979. // When
  980. session.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).cURLDescription {
  981. components = self.cURLCommandComponents(from: $0)
  982. cURLDescription = $0
  983. expectation.fulfill()
  984. }
  985. waitForExpectations(timeout: timeout)
  986. // Then
  987. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  988. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  989. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Content-Type: application/json\""))
  990. XCTAssertNotNil(cURLDescription?.range(of: "-d \"{"))
  991. XCTAssertNotNil(cURLDescription?.range(of: "\\\"f'oo\\\":\\\"ba'r\\\""))
  992. XCTAssertNotNil(cURLDescription?.range(of: "\\\"fo\\\\\\\"o\\\":\\\"b\\\\\\\"ar\\\""))
  993. XCTAssertNotNil(cURLDescription?.range(of: "\\\"foo\\\":\\\"bar\\"))
  994. XCTAssertEqual(components?.last, "\"\(url)\"")
  995. }
  996. @MainActor
  997. func testPOSTRequestWithCookieCURLDescription() {
  998. // Given
  999. let url = Endpoint.method(.post).url
  1000. let cookie = HTTPCookie(properties: [.domain: url.host as Any,
  1001. .path: url.path,
  1002. .name: "foo",
  1003. .value: "bar"])!
  1004. let cookieManager = sessionWithCookie(cookie)
  1005. let expectation = expectation(description: "request should complete")
  1006. var components: [String]?
  1007. // When
  1008. cookieManager.request(url, method: .post).cURLDescription {
  1009. components = self.cURLCommandComponents(from: $0)
  1010. expectation.fulfill()
  1011. }
  1012. waitForExpectations(timeout: timeout)
  1013. // Then
  1014. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  1015. XCTAssertEqual(components?[3..<5], ["-X", "POST"])
  1016. XCTAssertEqual(components?.last, "\"\(url)\"")
  1017. XCTAssertEqual(components?[5..<6], ["-b"])
  1018. }
  1019. @MainActor
  1020. func testPOSTRequestWithCookiesDisabledCURLDescriptionHasNoCookies() {
  1021. // Given
  1022. let url = Endpoint.method(.post).url
  1023. let cookie = HTTPCookie(properties: [.domain: url.host as Any,
  1024. .path: url.path,
  1025. .name: "foo",
  1026. .value: "bar"])!
  1027. sessionDisallowingCookies.session.configuration.httpCookieStorage?.setCookie(cookie)
  1028. let expectation = expectation(description: "request should complete")
  1029. var components: [String]?
  1030. // When
  1031. sessionDisallowingCookies.request(url, method: .post).cURLDescription {
  1032. components = self.cURLCommandComponents(from: $0)
  1033. expectation.fulfill()
  1034. }
  1035. waitForExpectations(timeout: timeout)
  1036. // Then
  1037. let cookieComponents = components?.filter { $0 == "-b" }
  1038. XCTAssertTrue(cookieComponents?.isEmpty == true)
  1039. }
  1040. @MainActor
  1041. func testMultipartFormDataRequestWithDuplicateHeadersCURLDescriptionHasOneContentTypeHeader() {
  1042. // Given
  1043. let url = Endpoint.method(.post).url
  1044. let japaneseData = Data("日本語".utf8)
  1045. let expectation = expectation(description: "multipart form data encoding should succeed")
  1046. var cURLDescription: String?
  1047. var components: [String]?
  1048. // When
  1049. sessionWithContentTypeHeader.upload(multipartFormData: { data in
  1050. data.append(japaneseData, withName: "japanese")
  1051. }, to: url).cURLDescription {
  1052. components = self.cURLCommandComponents(from: $0)
  1053. cURLDescription = $0
  1054. expectation.fulfill()
  1055. }
  1056. waitForExpectations(timeout: timeout)
  1057. // Then
  1058. XCTAssertEqual(components?[0..<3], ["$", "curl", "-v"])
  1059. XCTAssertTrue(components?.contains("-X") == true)
  1060. XCTAssertEqual(components?.last, "\"\(url)\"")
  1061. let contentTypeCount = components?.count(where: { $0.contains("Content-Type") })
  1062. XCTAssertEqual(contentTypeCount, 1, "command should contain a single Content-Type header")
  1063. XCTAssertNotNil(cURLDescription?.range(of: "-H \"Content-Type: multipart/form-data;"))
  1064. }
  1065. @MainActor
  1066. func testThatRequestWithInvalidURLDebugDescription() {
  1067. // Given
  1068. let urlString = "invalid_url"
  1069. let expectation = expectation(description: "request should complete")
  1070. var cURLDescription: String?
  1071. // When
  1072. session.request(urlString).cURLDescription {
  1073. cURLDescription = $0
  1074. expectation.fulfill()
  1075. }
  1076. waitForExpectations(timeout: timeout)
  1077. // Then
  1078. XCTAssertNotNil(cURLDescription, "debugDescription should not crash")
  1079. }
  1080. // MARK: Test Helper Methods
  1081. private func cURLCommandComponents(from cURLString: String) -> [String] {
  1082. cURLString.components(separatedBy: .whitespacesAndNewlines)
  1083. .filter { $0 != "" && $0 != "\\" }
  1084. }
  1085. }
  1086. final class RequestLifetimeTests: BaseTestCase {
  1087. @MainActor
  1088. func testThatRequestProvidesURLRequestWhenCreated() {
  1089. // Given
  1090. let didReceiveRequest = expectation(description: "did receive task")
  1091. let didComplete = expectation(description: "request did complete")
  1092. var request: URLRequest?
  1093. // When
  1094. AF.request(.default)
  1095. .onURLRequestCreation { request = $0; didReceiveRequest.fulfill() }
  1096. .responseDecodable(of: TestResponse.self) { _ in didComplete.fulfill() }
  1097. wait(for: [didReceiveRequest, didComplete], timeout: timeout, enforceOrder: true)
  1098. // Then
  1099. XCTAssertNotNil(request)
  1100. }
  1101. @MainActor
  1102. func testThatRequestProvidesTaskWhenCreated() {
  1103. // Given
  1104. let didReceiveTask = expectation(description: "did receive task")
  1105. let didComplete = expectation(description: "request did complete")
  1106. var task: URLSessionTask?
  1107. // When
  1108. AF.request(.default)
  1109. .onURLSessionTaskCreation { task = $0; didReceiveTask.fulfill() }
  1110. .responseDecodable(of: TestResponse.self) { _ in didComplete.fulfill() }
  1111. wait(for: [didReceiveTask, didComplete], timeout: timeout, enforceOrder: true)
  1112. // Then
  1113. XCTAssertNotNil(task)
  1114. }
  1115. }
  1116. // MARK: -
  1117. final class RequestInvalidURLTestCase: BaseTestCase {
  1118. @MainActor
  1119. func testThatDataRequestWithFileURLThrowsError() {
  1120. // Given
  1121. let fileURL = url(forResource: "valid_data", withExtension: "json")
  1122. let expectation = expectation(description: "Request should succeed.")
  1123. var response: DataResponse<Data?, AFError>?
  1124. // When
  1125. AF.request(fileURL)
  1126. .response { resp in
  1127. response = resp
  1128. expectation.fulfill()
  1129. }
  1130. waitForExpectations(timeout: timeout)
  1131. // Then
  1132. XCTAssertEqual(response?.result.isSuccess, true)
  1133. }
  1134. @MainActor
  1135. func testThatDownloadRequestWithFileURLThrowsError() {
  1136. // Given
  1137. let fileURL = url(forResource: "valid_data", withExtension: "json")
  1138. let expectation = expectation(description: "Request should succeed.")
  1139. var response: DownloadResponse<URL?, AFError>?
  1140. // When
  1141. AF.download(fileURL)
  1142. .response { resp in
  1143. response = resp
  1144. expectation.fulfill()
  1145. }
  1146. waitForExpectations(timeout: timeout)
  1147. // Then
  1148. XCTAssertEqual(response?.result.isSuccess, true)
  1149. }
  1150. @MainActor
  1151. func testThatDataStreamRequestWithFileURLThrowsError() {
  1152. // Given
  1153. let fileURL = url(forResource: "valid_data", withExtension: "json")
  1154. let expectation = expectation(description: "Request should succeed.")
  1155. var response: DataStreamRequest.Completion?
  1156. // When
  1157. AF.streamRequest(fileURL)
  1158. .responseStream { stream in
  1159. guard case let .complete(completion) = stream.event else { return }
  1160. response = completion
  1161. expectation.fulfill()
  1162. }
  1163. waitForExpectations(timeout: timeout)
  1164. // Then
  1165. XCTAssertNil(response?.response)
  1166. }
  1167. }
  1168. @Suite
  1169. struct RequestInstanceInterceptorTests {
  1170. @Test
  1171. func instanceAdapterIsCalled() async throws {
  1172. // Given
  1173. let session = Session()
  1174. let adapter = InspectorInterceptor(.adapter { @Sendable request, _, completion in completion(.success(request)) })
  1175. // When
  1176. let response = await session
  1177. .request(.get)
  1178. .adapt(using: adapter)
  1179. .serializingDecodable(TestResponse.self).response
  1180. #expect(response.result.isSuccess)
  1181. #expect(adapter.adaptations.count == 1)
  1182. }
  1183. @Test
  1184. func instanceAdaptersAreCalledInAddedOrder() async throws {
  1185. // Given
  1186. let session = Session()
  1187. let firstAdapter = InspectorInterceptor(.adapter { @Sendable request, _, completion in completion(.success(request)) })
  1188. let secondAdapter = InspectorInterceptor(.adapter { @Sendable request, _, completion in completion(.success(request)) })
  1189. // When
  1190. let response = await session
  1191. .request(.get)
  1192. .adapt(using: firstAdapter)
  1193. .adapt(using: secondAdapter)
  1194. .serializingDecodable(TestResponse.self).response
  1195. #expect(response.result.isSuccess)
  1196. #expect(firstAdapter.adaptations.count == 1)
  1197. #expect(secondAdapter.adaptations.count == 1)
  1198. #expect(firstAdapter.adaptations[0].date < secondAdapter.adaptations[0].date)
  1199. }
  1200. @Test
  1201. func sessionAdapterIsCalledBeforeInstanceAdapter() async throws {
  1202. // Given
  1203. let sessionInterceptor = InspectorInterceptor(.adapter { @Sendable request, _, completion in
  1204. var request = request
  1205. request.headers["session"] = "\(Date.now.timeIntervalSince1970)"
  1206. completion(.success(request))
  1207. })
  1208. let session = Session(interceptor: sessionInterceptor)
  1209. let instanceInterceptor = InspectorInterceptor(.adapter { @Sendable request, _, completion in
  1210. var request = request
  1211. request.headers["instance"] = "\(Date.now.timeIntervalSince1970)"
  1212. completion(.success(request))
  1213. })
  1214. // When
  1215. let response = await session
  1216. .request(.get)
  1217. .adapt(using: instanceInterceptor)
  1218. .serializingDecodable(TestResponse.self).response
  1219. #expect(response.result.isSuccess)
  1220. if let sessionTime = response.request?.headers["session"].flatMap(Double.init),
  1221. let instanceTime = response.request?.headers["instance"].flatMap(Double.init) {
  1222. #expect(sessionTime < instanceTime)
  1223. }
  1224. #expect(sessionInterceptor.adaptations.count == 1)
  1225. #expect(instanceInterceptor.adaptations.count == 1)
  1226. #expect(sessionInterceptor.adaptations[0].date < instanceInterceptor.adaptations[0].date)
  1227. }
  1228. @Test
  1229. func instanceInterceptorIsCalled() async throws {
  1230. // Given
  1231. let session = Session()
  1232. let interceptor = InspectorInterceptor(
  1233. .interceptor { @Sendable request, _, completion in
  1234. completion(.success(request))
  1235. } retrier: { @Sendable _, _, _, completion in
  1236. completion(.retry)
  1237. }
  1238. )
  1239. // When
  1240. let response = await session
  1241. .request(.endpoints(.delay(1).modifying(\.timeout, to: 0.0001), .get))
  1242. .interceptor(interceptor)
  1243. .serializingDecodable(TestResponse.self).response
  1244. #expect(response.result.isSuccess)
  1245. #expect(interceptor.adaptations.count == 2)
  1246. #expect(interceptor.retries.count == 1)
  1247. }
  1248. @Test
  1249. func multipleInstanceInterceptorsAreCalledInAddedOrder() async throws {
  1250. // Given
  1251. let session = Session()
  1252. let firstInterceptor = InspectorInterceptor(
  1253. .interceptor { @Sendable request, _, completion in
  1254. completion(.success(request))
  1255. } retrier: { @Sendable _, _, _, completion in
  1256. completion(.doNotRetry)
  1257. }
  1258. )
  1259. let secondInterceptor = InspectorInterceptor(
  1260. .interceptor { @Sendable request, _, completion in
  1261. completion(.success(request))
  1262. } retrier: { @Sendable _, _, _, completion in
  1263. completion(.retry)
  1264. }
  1265. )
  1266. // When
  1267. let response = await session
  1268. .request(.endpoints(.delay(1).modifying(\.timeout, to: 0.0001), .get))
  1269. .interceptor(firstInterceptor)
  1270. .interceptor(secondInterceptor)
  1271. .serializingDecodable(TestResponse.self).response
  1272. #expect(response.result.isSuccess)
  1273. #expect(firstInterceptor.adaptations.count == 2)
  1274. #expect(firstInterceptor.retries.count == 1)
  1275. #expect(secondInterceptor.adaptations.count == 2)
  1276. #expect(secondInterceptor.retries.count == 1)
  1277. #expect(firstInterceptor.adaptations[0].date < secondInterceptor.adaptations[0].date)
  1278. #expect(firstInterceptor.adaptations[1].date < secondInterceptor.adaptations[1].date)
  1279. #expect(firstInterceptor.retries[0].date < secondInterceptor.retries[0].date)
  1280. }
  1281. @Test
  1282. func instanceRetrierIsCalled() async throws {
  1283. // Given
  1284. let session = Session()
  1285. let interceptor = InspectorInterceptor(.retrier { @Sendable _, _, _, completion in completion(.retry) })
  1286. // When
  1287. let response = await session
  1288. .request(.endpoints(.delay(1).modifying(\.timeout, to: 0.0001), .get))
  1289. .retry(using: interceptor)
  1290. .serializingDecodable(TestResponse.self).response
  1291. #expect(response.result.isSuccess)
  1292. #expect(interceptor.retries.count == 1)
  1293. }
  1294. @Test
  1295. func multipleInstanceRetriersAreCalledInAddedOrder() async throws {
  1296. // Given
  1297. let session = Session()
  1298. let firstRetrier = InspectorInterceptor(.retrier { @Sendable _, _, _, completion in completion(.doNotRetry) })
  1299. let secondRetrier = InspectorInterceptor(.retrier { @Sendable _, _, _, completion in completion(.retry) })
  1300. // When
  1301. let response = await session
  1302. .request(.endpoints(.delay(1).modifying(\.timeout, to: 0.0001), .get))
  1303. .retry(using: firstRetrier)
  1304. .retry(using: secondRetrier)
  1305. .serializingDecodable(TestResponse.self).response
  1306. #expect(response.result.isSuccess)
  1307. #expect(firstRetrier.retries.count == 1)
  1308. #expect(secondRetrier.retries.count == 1)
  1309. #expect(firstRetrier.retries[0].date < secondRetrier.retries[0].date)
  1310. }
  1311. @Test
  1312. func sessionRetrierIsCalledBeforeInstanceRetrier() async throws {
  1313. // Given
  1314. let sessionRetrier = InspectorInterceptor(.retrier { @Sendable _, _, _, completion in completion(.doNotRetry) })
  1315. let session = Session(interceptor: sessionRetrier)
  1316. let instanceRetrier = InspectorInterceptor(.retrier { @Sendable _, _, _, completion in completion(.retry) })
  1317. // When
  1318. let response = await session
  1319. .request(.endpoints(.delay(1).modifying(\.timeout, to: 0.0001), .get))
  1320. .retry(using: instanceRetrier)
  1321. .serializingDecodable(TestResponse.self).response
  1322. #expect(response.result.isSuccess)
  1323. #expect(instanceRetrier.retries.count == 1)
  1324. #expect(sessionRetrier.retries.count == 1)
  1325. #expect(sessionRetrier.retries[0].date < instanceRetrier.retries[0].date)
  1326. }
  1327. @Test
  1328. func instanceEventMonitorIsCalled() async throws {
  1329. // Given
  1330. let queue = DispatchQueue(label: "org.alamofire.\(#function)")
  1331. let monitor = InspectorEventMonitor(queue: queue)
  1332. let session = Session(rootQueue: queue, eventMonitors: [])
  1333. // When
  1334. let response = await session
  1335. .request(.get)
  1336. .eventMonitor(monitor)
  1337. .serializingDecodable(TestResponse.self)
  1338. .response
  1339. await monitor.pendingEvents()
  1340. // Then
  1341. #expect(response.result.isSuccess)
  1342. let expected = ["requestDidResume(_:)",
  1343. "request(_:didCreateInitialURLRequest:)",
  1344. "request(_:didCreateURLRequest:)",
  1345. "request(_:didCreateTask:)",
  1346. "request(_:didResumeTask:)",
  1347. "request(_:didGatherMetrics:)",
  1348. "requestDidFinish(_:)",
  1349. "request(_:didParseResponse:)"]
  1350. #expect(monitor.events == expected, "Events didn't match, actual events: \(monitor.events)")
  1351. }
  1352. @Test
  1353. func multipleInstanceEventMonitorsAreCalledInAddedOrder() async throws {
  1354. // Given
  1355. let queue = DispatchQueue(label: "org.alamofire.\(#function)")
  1356. let firstMonitor = InspectorEventMonitor(queue: queue)
  1357. let secondMonitor = InspectorEventMonitor(queue: queue)
  1358. let session = Session(rootQueue: queue, eventMonitors: [])
  1359. // When
  1360. let response = await session
  1361. .request(.get)
  1362. .eventMonitor(firstMonitor)
  1363. .eventMonitor(secondMonitor)
  1364. .serializingDecodable(TestResponse.self)
  1365. .response
  1366. await firstMonitor.pendingEvents()
  1367. // Then
  1368. #expect(response.result.isSuccess)
  1369. let expected = ["requestDidResume(_:)",
  1370. "request(_:didCreateInitialURLRequest:)",
  1371. "request(_:didCreateURLRequest:)",
  1372. "request(_:didCreateTask:)",
  1373. "request(_:didResumeTask:)",
  1374. "request(_:didGatherMetrics:)",
  1375. "requestDidFinish(_:)",
  1376. "request(_:didParseResponse:)"]
  1377. #expect(firstMonitor.events == expected, "firstMonitor events didn't match, actual events: \(firstMonitor.events)")
  1378. #expect(secondMonitor.events == expected, "secondMonitor events didn't match, actual events: \(firstMonitor.events)")
  1379. for timelines in zip(firstMonitor.timeline, secondMonitor.timeline) {
  1380. #expect(timelines.0.date <= timelines.1.date)
  1381. }
  1382. }
  1383. @Test
  1384. func instanceAndSessionEventMonitorsAreCalledInCorrectOrder() async throws {
  1385. // Given
  1386. let queue = DispatchQueue(label: "org.alamofire.\(#function)")
  1387. let sessionMonitor = InspectorEventMonitor(label: "session", queue: queue)
  1388. let instanceMonitor = InspectorEventMonitor(label: "instance", queue: queue)
  1389. let session = Session(rootQueue: queue, eventMonitors: [sessionMonitor])
  1390. // When
  1391. let response = await session
  1392. .request(.get)
  1393. .eventMonitor(instanceMonitor)
  1394. .serializingDecodable(TestResponse.self)
  1395. .response
  1396. await sessionMonitor.pendingEvents()
  1397. await instanceMonitor.pendingEvents()
  1398. // Then
  1399. #expect(response.result.isSuccess)
  1400. let expectedInstanceEvents = ["requestDidResume(_:)",
  1401. "request(_:didCreateInitialURLRequest:)",
  1402. "request(_:didCreateURLRequest:)",
  1403. "request(_:didCreateTask:)",
  1404. "request(_:didResumeTask:)",
  1405. "request(_:didGatherMetrics:)",
  1406. "requestDidFinish(_:)",
  1407. "request(_:didParseResponse:)"]
  1408. let expectedSessionEvents = ["requestDidResume(_:)",
  1409. "request(_:didCreateInitialURLRequest:)",
  1410. "request(_:didCreateURLRequest:)",
  1411. "request(_:didCreateTask:)",
  1412. "request(_:didResumeTask:)",
  1413. "urlSession(_:dataTask:didReceive:)",
  1414. "urlSession(_:dataTask:willCacheResponse:)",
  1415. "urlSession(_:task:didFinishCollecting:)",
  1416. "request(_:didGatherMetrics:)",
  1417. "urlSession(_:task:didCompleteWithError:)",
  1418. "requestDidFinish(_:)",
  1419. "request(_:didParseResponse:)"]
  1420. #expect(sessionMonitor.events == expectedSessionEvents, "Session events didn't match, actual events: \(sessionMonitor.events)")
  1421. #expect(instanceMonitor.events == expectedInstanceEvents, "Instance events didn't match, actual events: \(instanceMonitor.events)")
  1422. let instanceEvents = instanceMonitor.timeline
  1423. var sessionEvents = sessionMonitor.timeline
  1424. sessionEvents = sessionEvents.filter { session in instanceEvents.contains { $0.event == session.event } }
  1425. #expect(instanceEvents.count == sessionEvents.count)
  1426. for combinedEvent in zip(sessionEvents, instanceEvents) {
  1427. #expect(combinedEvent.0.event == combinedEvent.1.event)
  1428. #expect(combinedEvent.0.date <= combinedEvent.1.date, "session event wasn't before instance event")
  1429. }
  1430. }
  1431. }
  1432. #if canImport(zlib) && !os(Android) // Same condition as `DeflateRequestCompressor`.
  1433. @Suite
  1434. struct RequestCompressionTests {
  1435. @Test
  1436. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1437. func thatRequestsCanBeCompressed() async {
  1438. // Given
  1439. let url = Endpoint.method(.post).url
  1440. let parameters = TestParameters(property: "compressed")
  1441. // When
  1442. let result = await AF.request(url,
  1443. method: .post,
  1444. parameters: parameters,
  1445. encoder: .json,
  1446. interceptor: .deflateCompressor)
  1447. .serializingDecodable(TestResponse.self)
  1448. .result
  1449. // Then
  1450. #expect(result.isSuccess)
  1451. }
  1452. @Test
  1453. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1454. func thatDeflateCompressorThrowsErrorByDefaultWhenRequestAlreadyHasHeader() async {
  1455. // Given
  1456. let url = Endpoint.method(.post).url
  1457. let parameters = TestParameters(property: "compressed")
  1458. // When
  1459. let result = await AF.request(url,
  1460. method: .post,
  1461. parameters: parameters,
  1462. encoder: .json,
  1463. headers: [.contentEncoding("value")],
  1464. interceptor: .deflateCompressor)
  1465. .serializingDecodable(TestResponse.self)
  1466. .result
  1467. // Then
  1468. #expect(result.isFailure)
  1469. #expect(result.failure?.underlyingError as? DeflateRequestCompressor.DuplicateHeaderError != nil)
  1470. }
  1471. @Test
  1472. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1473. func thatDeflateCompressorThrowsErrorWhenConfigured() async {
  1474. // Given
  1475. let url = Endpoint.method(.post).url
  1476. let parameters = TestParameters(property: "compressed")
  1477. // When
  1478. let result = await AF.request(url,
  1479. method: .post,
  1480. parameters: parameters,
  1481. encoder: .json,
  1482. headers: [.contentEncoding("value")],
  1483. interceptor: .deflateCompressor(duplicateHeaderBehavior: .error))
  1484. .serializingDecodable(TestResponse.self)
  1485. .result
  1486. // Then
  1487. #expect(result.isFailure)
  1488. #expect(result.failure?.underlyingError as? DeflateRequestCompressor.DuplicateHeaderError != nil)
  1489. }
  1490. @Test
  1491. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1492. func thatDeflateCompressorReplacesHeaderWhenConfigured() async {
  1493. // Given
  1494. let url = Endpoint.method(.post).url
  1495. let parameters = TestParameters(property: "compressed")
  1496. // When
  1497. let result = await AF.request(url,
  1498. method: .post,
  1499. parameters: parameters,
  1500. encoder: .json,
  1501. headers: [.contentEncoding("value")],
  1502. interceptor: .deflateCompressor(duplicateHeaderBehavior: .replace))
  1503. .serializingDecodable(TestResponse.self)
  1504. .result
  1505. // Then
  1506. #expect(result.isSuccess)
  1507. }
  1508. @Test
  1509. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1510. func thatDeflateCompressorSkipsCompressionWhenConfigured() async {
  1511. // Given
  1512. let url = Endpoint.method(.post).url
  1513. let parameters = TestParameters(property: "compressed")
  1514. // When
  1515. let result = await AF.request(url,
  1516. method: .post,
  1517. parameters: parameters,
  1518. encoder: .json,
  1519. headers: [.contentEncoding("gzip")],
  1520. interceptor: .deflateCompressor(duplicateHeaderBehavior: .skip))
  1521. .serializingDecodable(TestResponse.self)
  1522. .result
  1523. // Then
  1524. // Request fails as the server expects gzip compression.
  1525. #expect(result.isFailure)
  1526. }
  1527. @Test
  1528. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  1529. func thatDeflateCompressorDoesNotCompressDataWhenClosureReturnsFalse() async {
  1530. // Given
  1531. let url = Endpoint.method(.post).url
  1532. let parameters = TestParameters(property: "compressed")
  1533. // When
  1534. let result = await AF.request(url,
  1535. method: .post,
  1536. parameters: parameters,
  1537. encoder: .json,
  1538. interceptor: .deflateCompressor { _ in false })
  1539. .serializingDecodable(TestResponse.self)
  1540. .result
  1541. // Then
  1542. #expect(result.isSuccess)
  1543. // With no compression, request headers reflected from server should have no Content-Encoding.
  1544. #expect(result.success?.headers["Content-Encoding"] == nil)
  1545. }
  1546. }
  1547. #endif