CombineTests.swift 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. //
  2. // CombineTests.swift
  3. //
  4. // Copyright (c) 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. #if canImport(Combine)
  25. import Alamofire
  26. import Combine
  27. import XCTest
  28. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  29. final class DataRequestCombineTests: CombineTestCase {
  30. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  31. @MainActor
  32. func testThatDataRequestCanBePublished() {
  33. // Given
  34. let responseReceived = expectation(description: "response should be received")
  35. let completionReceived = expectation(description: "stream should complete")
  36. var response: DataResponse<TestResponse, AFError>?
  37. // When
  38. store {
  39. AF.request(.default)
  40. .publishDecodable(type: TestResponse.self)
  41. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  42. receiveValue: { response = $0; responseReceived.fulfill() })
  43. }
  44. waitForExpectations(timeout: timeout)
  45. // Then
  46. XCTAssertTrue(response?.result.isSuccess == true)
  47. }
  48. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  49. @MainActor
  50. func testThatNonAutomaticDataRequestCanBePublished() {
  51. // Given
  52. let responseReceived = expectation(description: "response should be received")
  53. let completionReceived = expectation(description: "stream should complete")
  54. let session = Session(startRequestsImmediately: false)
  55. var response: DataResponse<TestResponse, AFError>?
  56. // When
  57. store {
  58. session.request(.default)
  59. .publishDecodable(type: TestResponse.self)
  60. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  61. receiveValue: { response = $0; responseReceived.fulfill() })
  62. }
  63. waitForExpectations(timeout: timeout)
  64. // Then
  65. XCTAssertTrue(response?.result.isSuccess == true)
  66. }
  67. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  68. @MainActor
  69. func testThatDataRequestCanPublishData() {
  70. // Given
  71. let responseReceived = expectation(description: "response should be received")
  72. let completionReceived = expectation(description: "stream should complete")
  73. let session = Session(startRequestsImmediately: false)
  74. var response: DataResponse<Data, AFError>?
  75. // When
  76. store {
  77. session.request(.default)
  78. .publishData()
  79. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  80. receiveValue: { response = $0; responseReceived.fulfill() })
  81. }
  82. waitForExpectations(timeout: timeout)
  83. // Then
  84. XCTAssertTrue(response?.result.isSuccess == true)
  85. }
  86. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  87. @MainActor
  88. func testThatDataRequestCanPublishString() {
  89. // Given
  90. let responseReceived = expectation(description: "response should be received")
  91. let completionReceived = expectation(description: "stream should complete")
  92. let session = Session(startRequestsImmediately: false)
  93. var response: DataResponse<String, AFError>?
  94. // When
  95. store {
  96. session.request(.default)
  97. .publishString()
  98. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  99. receiveValue: { response = $0; responseReceived.fulfill() })
  100. }
  101. waitForExpectations(timeout: timeout)
  102. // Then
  103. XCTAssertTrue(response?.result.isSuccess == true)
  104. }
  105. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  106. @MainActor
  107. func testThatDataRequestCanBePublishedUnserialized() {
  108. // Given
  109. let responseReceived = expectation(description: "response should be received")
  110. let completionReceived = expectation(description: "stream should complete")
  111. var response: DataResponse<Data?, AFError>?
  112. // When
  113. store {
  114. AF.request(.default)
  115. .publishUnserialized()
  116. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  117. receiveValue: { response = $0; responseReceived.fulfill() })
  118. }
  119. waitForExpectations(timeout: timeout)
  120. // Then
  121. XCTAssertTrue(response?.result.isSuccess == true)
  122. }
  123. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  124. @MainActor
  125. func testThatDataRequestCanBePublishedWithMultipleHandlers() {
  126. // Given
  127. let handlerResponseReceived = expectation(description: "handler response should be received")
  128. let publishedResponseReceived = expectation(description: "published response should be received")
  129. let completionReceived = expectation(description: "stream should complete")
  130. var handlerResponse: DataResponse<TestResponse, AFError>?
  131. var publishedResponse: DataResponse<TestResponse, AFError>?
  132. // When
  133. store {
  134. AF.request(.default)
  135. .responseDecodable(of: TestResponse.self) { handlerResponse = $0; handlerResponseReceived.fulfill() }
  136. .publishDecodable(type: TestResponse.self)
  137. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  138. receiveValue: { publishedResponse = $0; publishedResponseReceived.fulfill() })
  139. }
  140. waitForExpectations(timeout: timeout)
  141. // Then
  142. XCTAssertTrue(handlerResponse?.result.isSuccess == true)
  143. XCTAssertTrue(publishedResponse?.result.isSuccess == true)
  144. }
  145. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  146. @MainActor
  147. func testThatDataRequestCanPublishResult() {
  148. // Given
  149. let responseReceived = expectation(description: "response should be received")
  150. let completionReceived = expectation(description: "stream should complete")
  151. var result: Result<TestResponse, AFError>?
  152. // When
  153. store {
  154. AF.request(.default)
  155. .publishDecodable(type: TestResponse.self)
  156. .result()
  157. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  158. receiveValue: { result = $0; responseReceived.fulfill() })
  159. }
  160. waitForExpectations(timeout: timeout)
  161. // Then
  162. XCTAssertTrue(result?.isSuccess == true)
  163. }
  164. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  165. @MainActor
  166. func testThatDataRequestCanPublishValue() {
  167. // Given
  168. let responseReceived = expectation(description: "response should be received")
  169. let completionReceived = expectation(description: "stream should complete")
  170. var value: TestResponse?
  171. // When
  172. store {
  173. AF.request(.default)
  174. .publishDecodable(type: TestResponse.self)
  175. .value()
  176. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  177. receiveValue: { value = $0; responseReceived.fulfill() })
  178. }
  179. waitForExpectations(timeout: timeout)
  180. // Then
  181. XCTAssertNotNil(value)
  182. }
  183. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  184. @MainActor
  185. func testThatDataRequestCanPublishValueWithFailure() {
  186. // Given
  187. let completionReceived = expectation(description: "stream should complete")
  188. var error: AFError?
  189. // When
  190. store {
  191. AF.request(Endpoint(path: .delay(interval: 1), timeout: 0.01))
  192. .publishDecodable(type: TestResponse.self)
  193. .value()
  194. .sink(receiveCompletion: { completion in
  195. switch completion {
  196. case let .failure(err):
  197. error = err
  198. case .finished:
  199. error = nil
  200. }
  201. completionReceived.fulfill()
  202. }, receiveValue: { _ in })
  203. }
  204. waitForExpectations(timeout: timeout)
  205. // Then
  206. XCTAssertNotNil(error)
  207. XCTAssertEqual((error?.underlyingError as? URLError)?.code, .timedOut)
  208. }
  209. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  210. @MainActor
  211. func testThatPublishedDataRequestIsNotResumedUnlessSubscribed() {
  212. // Given
  213. let responseReceived = expectation(description: "response should be received")
  214. let completionReceived = expectation(description: "stream should complete")
  215. var response: DataResponse<TestResponse, AFError>?
  216. // When
  217. let request = AF.request(.default)
  218. let publisher = request.publishDecodable(type: TestResponse.self)
  219. let stateAfterPublisher = request.state
  220. store {
  221. publisher.sink(receiveCompletion: { _ in completionReceived.fulfill() },
  222. receiveValue: { response = $0; responseReceived.fulfill() })
  223. }
  224. let stateAfterSubscription = request.state
  225. waitForExpectations(timeout: timeout)
  226. // Then
  227. XCTAssertTrue(response?.result.isSuccess == true)
  228. XCTAssertEqual(stateAfterPublisher, .initialized)
  229. XCTAssertEqual(stateAfterSubscription, .resumed)
  230. }
  231. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  232. @MainActor
  233. func testThatDataRequestCanSubscribedFromNonMainQueueButPublishedOnMainQueue() {
  234. // Given
  235. let responseReceived = expectation(description: "response should be received")
  236. let completionReceived = expectation(description: "stream should complete")
  237. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  238. var receivedOnMain = false
  239. var response: DataResponse<TestResponse, AFError>?
  240. // When
  241. store {
  242. AF.request(.default)
  243. .publishDecodable(type: TestResponse.self)
  244. .subscribe(on: queue)
  245. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  246. receiveValue: {
  247. receivedOnMain = Thread.isMainThread
  248. response = $0
  249. responseReceived.fulfill()
  250. })
  251. }
  252. waitForExpectations(timeout: timeout)
  253. // Then
  254. XCTAssertTrue(response?.result.isSuccess == true)
  255. XCTAssertTrue(receivedOnMain)
  256. }
  257. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  258. @MainActor
  259. func testThatDataRequestPublishedOnSeparateQueueIsReceivedOnThatQueue() {
  260. // Given
  261. let responseReceived = expectation(description: "response should be received")
  262. let completionReceived = expectation(description: "stream should complete")
  263. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  264. var response: DataResponse<TestResponse, AFError>?
  265. // When
  266. store {
  267. AF.request(.default)
  268. .publishDecodable(type: TestResponse.self, queue: queue)
  269. .sink(receiveCompletion: { _ in
  270. dispatchPrecondition(condition: .onQueue(queue))
  271. completionReceived.fulfill()
  272. },
  273. receiveValue: {
  274. dispatchPrecondition(condition: .onQueue(queue))
  275. response = $0
  276. responseReceived.fulfill()
  277. })
  278. }
  279. waitForExpectations(timeout: timeout)
  280. // Then
  281. XCTAssertTrue(response?.result.isSuccess == true)
  282. }
  283. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  284. @MainActor
  285. func testThatDataRequestPublishedOnSeparateQueueCanBeReceivedOntoMainQueue() {
  286. // Given
  287. let responseReceived = expectation(description: "response should be received")
  288. let completionReceived = expectation(description: "stream should complete")
  289. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  290. var receivedOnMain = false
  291. var response: DataResponse<TestResponse, AFError>?
  292. // When
  293. store {
  294. AF.request(.default)
  295. .publishDecodable(type: TestResponse.self, queue: queue)
  296. .receive(on: DispatchQueue.main)
  297. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  298. receiveValue: {
  299. receivedOnMain = Thread.isMainThread
  300. response = $0
  301. responseReceived.fulfill()
  302. })
  303. }
  304. waitForExpectations(timeout: timeout)
  305. // Then
  306. XCTAssertTrue(response?.result.isSuccess == true)
  307. XCTAssertTrue(receivedOnMain)
  308. }
  309. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  310. @MainActor
  311. func testThatPublishedDataRequestCanBeCancelledAutomatically() throws {
  312. if #available(macOS 11, iOS 14, watchOS 7, tvOS 14, *) {
  313. throw XCTSkip("Skip on 2020 OS versions, as Combine cancellation no longer emits a value.")
  314. }
  315. // Given
  316. let responseReceived = expectation(description: "response should be received")
  317. let completionReceived = expectation(description: "stream should complete")
  318. var response: DataResponse<TestResponse, AFError>?
  319. // When
  320. let request = AF.request(.default)
  321. var token: AnyCancellable? = request
  322. .publishDecodable(type: TestResponse.self)
  323. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  324. receiveValue: { response = $0; responseReceived.fulfill() })
  325. token = nil
  326. waitForExpectations(timeout: timeout)
  327. // Then
  328. XCTAssertTrue(response?.result.isFailure == true)
  329. XCTAssertTrue(response?.error?.isExplicitlyCancelledError == true,
  330. "error is not explicitly cancelled but \(response?.error?.localizedDescription ?? "None")")
  331. XCTAssertTrue(request.isCancelled)
  332. XCTAssertNil(token)
  333. }
  334. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  335. @MainActor
  336. func testThatPublishedDataRequestCanBeCancelledManually() {
  337. // Given
  338. let responseReceived = expectation(description: "response should be received")
  339. let completionReceived = expectation(description: "stream should complete")
  340. var response: DataResponse<TestResponse, AFError>?
  341. // When
  342. let request = AF.request(.default)
  343. store {
  344. request
  345. .publishDecodable(type: TestResponse.self)
  346. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  347. receiveValue: { response = $0; responseReceived.fulfill() })
  348. }
  349. request.cancel()
  350. waitForExpectations(timeout: timeout)
  351. // Then
  352. XCTAssertTrue(response?.result.isFailure == true)
  353. XCTAssertTrue(response?.error?.isExplicitlyCancelledError == true,
  354. "error is not explicitly cancelled but \(response?.error?.localizedDescription ?? "None")")
  355. XCTAssertTrue(request.isCancelled)
  356. }
  357. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  358. @MainActor
  359. func testThatMultipleDataRequestPublishersCanBeCombined() {
  360. // Given
  361. let responseReceived = expectation(description: "combined response should be received")
  362. let completionReceived = expectation(description: "combined stream should complete")
  363. var firstResponse: DataResponse<TestResponse, AFError>?
  364. var secondResponse: DataResponse<TestResponse, AFError>?
  365. // When
  366. let first = AF.request(.default)
  367. .publishDecodable(type: TestResponse.self)
  368. let second = AF.request(.default)
  369. .publishDecodable(type: TestResponse.self)
  370. store {
  371. Publishers.CombineLatest(first, second)
  372. .sink(receiveCompletion: { _ in completionReceived.fulfill() }) { first, second in
  373. firstResponse = first
  374. secondResponse = second
  375. responseReceived.fulfill()
  376. }
  377. }
  378. waitForExpectations(timeout: timeout)
  379. // Then
  380. XCTAssertTrue(firstResponse?.result.isSuccess == true)
  381. XCTAssertTrue(secondResponse?.result.isSuccess == true)
  382. }
  383. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  384. @MainActor
  385. func testThatMultipleDataRequestPublishersCanBeChained() {
  386. // Given
  387. let responseReceived = expectation(description: "combined response should be received")
  388. let completionReceived = expectation(description: "combined stream should complete")
  389. let customValue = "CustomValue"
  390. var firstResponse: DataResponse<TestResponse, AFError>?
  391. var secondResponse: DataResponse<TestResponse, AFError>?
  392. // When
  393. store {
  394. AF.request(.default)
  395. .publishDecodable(type: TestResponse.self)
  396. .flatMap { response -> DataResponsePublisher<TestResponse> in
  397. firstResponse = response
  398. let request = Endpoint(headers: ["X-Custom": customValue])
  399. return AF.request(request)
  400. .publishDecodable(type: TestResponse.self)
  401. }
  402. .sink(receiveCompletion: { _ in completionReceived.fulfill() }) { response in
  403. secondResponse = response
  404. responseReceived.fulfill()
  405. }
  406. }
  407. waitForExpectations(timeout: timeout)
  408. // Then
  409. XCTAssertTrue(firstResponse?.result.isSuccess == true)
  410. XCTAssertTrue(secondResponse?.result.isSuccess == true)
  411. XCTAssertEqual(secondResponse?.value?.headers["X-Custom"], customValue)
  412. }
  413. }
  414. // MARK: - DataStreamRequest
  415. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  416. @MainActor
  417. final class DataStreamRequestCombineTests: CombineTestCase {
  418. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  419. func testThatDataStreamRequestCanBePublished() {
  420. // Given
  421. let responseReceived = expectation(description: "response should be received")
  422. let completionReceived = expectation(description: "stream should complete")
  423. var result: Result<TestResponse, AFError>?
  424. // When
  425. store {
  426. AF.streamRequest(.default)
  427. .publishDecodable(type: TestResponse.self)
  428. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  429. receiveValue: { stream in
  430. switch stream.event {
  431. case let .stream(value):
  432. result = value
  433. case .complete:
  434. responseReceived.fulfill()
  435. }
  436. })
  437. }
  438. waitForExpectations(timeout: timeout)
  439. // Then
  440. XCTAssertNotNil(result?.success)
  441. }
  442. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  443. func testThatNonAutomaticDataStreamRequestCanBePublished() {
  444. // Given
  445. let responseReceived = expectation(description: "response should be received")
  446. let completionReceived = expectation(description: "stream should complete")
  447. let session = Session(startRequestsImmediately: false)
  448. var result: Result<TestResponse, AFError>?
  449. // When
  450. store {
  451. session.streamRequest(.default)
  452. .publishDecodable(type: TestResponse.self)
  453. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  454. receiveValue: { stream in
  455. switch stream.event {
  456. case let .stream(value):
  457. result = value
  458. case .complete:
  459. responseReceived.fulfill()
  460. }
  461. })
  462. }
  463. waitForExpectations(timeout: timeout)
  464. // Then
  465. XCTAssertNotNil(result?.success)
  466. }
  467. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  468. func testThatDataStreamRequestCanPublishData() {
  469. // Given
  470. let responseReceived = expectation(description: "response should be received")
  471. let completionReceived = expectation(description: "stream should complete")
  472. var result: Result<Data, AFError>?
  473. // When
  474. store {
  475. AF.streamRequest(.default)
  476. .publishData()
  477. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  478. receiveValue: { stream in
  479. switch stream.event {
  480. case let .stream(value):
  481. result = value
  482. case .complete:
  483. responseReceived.fulfill()
  484. }
  485. })
  486. }
  487. waitForExpectations(timeout: timeout)
  488. // Then
  489. XCTAssertNotNil(result?.success)
  490. }
  491. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  492. func testThatDataStreamRequestCanPublishString() {
  493. // Given
  494. let responseReceived = expectation(description: "response should be received")
  495. let completionReceived = expectation(description: "stream should complete")
  496. var result: Result<String, AFError>?
  497. // When
  498. store {
  499. AF.streamRequest(.default)
  500. .publishString()
  501. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  502. receiveValue: { stream in
  503. switch stream.event {
  504. case let .stream(value):
  505. result = value
  506. case .complete:
  507. responseReceived.fulfill()
  508. }
  509. })
  510. }
  511. waitForExpectations(timeout: timeout)
  512. // Then
  513. XCTAssertNotNil(result?.success)
  514. }
  515. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  516. func testThatDataStreamRequestCanBePublishedWithMultipleHandlers() {
  517. // Given
  518. let handlerResponseReceived = expectation(description: "handler response should be received")
  519. let publishedResponseReceived = expectation(description: "response should be received")
  520. let completionReceived = expectation(description: "stream should complete")
  521. var handlerResult: Result<TestResponse, AFError>?
  522. var publishedResult: Result<TestResponse, AFError>?
  523. // When
  524. store {
  525. AF.streamRequest(.default)
  526. .responseStreamDecodable(of: TestResponse.self) { stream in
  527. switch stream.event {
  528. case let .stream(value):
  529. handlerResult = value
  530. case .complete:
  531. handlerResponseReceived.fulfill()
  532. }
  533. }
  534. .publishDecodable(type: TestResponse.self)
  535. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  536. receiveValue: { stream in
  537. switch stream.event {
  538. case let .stream(value):
  539. publishedResult = value
  540. case .complete:
  541. publishedResponseReceived.fulfill()
  542. }
  543. })
  544. }
  545. waitForExpectations(timeout: timeout)
  546. // Then
  547. XCTAssertNotNil(handlerResult?.success)
  548. XCTAssertNotNil(publishedResult?.success)
  549. }
  550. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  551. func testThatDataStreamRequestCanPublishResult() {
  552. // Given
  553. let responseReceived = expectation(description: "response should be received")
  554. let completionReceived = expectation(description: "stream should complete")
  555. var result: Result<TestResponse, AFError>?
  556. // When
  557. store {
  558. AF.streamRequest(.default)
  559. .publishDecodable(type: TestResponse.self)
  560. .result()
  561. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  562. receiveValue: { received in
  563. result = received
  564. responseReceived.fulfill()
  565. })
  566. }
  567. waitForExpectations(timeout: timeout)
  568. // Then
  569. XCTAssertNotNil(result?.success)
  570. }
  571. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  572. func testThatDataStreamRequestCanPublishResultWithResponseFailure() {
  573. // Given
  574. let responseReceived = expectation(description: "response should be received")
  575. let completionReceived = expectation(description: "stream should complete")
  576. var result: Result<TestResponse, AFError>?
  577. // When
  578. store {
  579. AF.streamRequest(Endpoint.delay(1).modifying(\.timeout, to: 0.1))
  580. .publishDecodable(type: TestResponse.self)
  581. .result()
  582. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  583. receiveValue: { received in
  584. result = received
  585. responseReceived.fulfill()
  586. })
  587. }
  588. waitForExpectations(timeout: timeout)
  589. // Then
  590. XCTAssertNil(result?.success)
  591. XCTAssertEqual((result?.failure?.underlyingError as? URLError)?.code, .timedOut)
  592. }
  593. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  594. func testThatDataStreamRequestCanPublishValue() {
  595. // Given
  596. let responseReceived = expectation(description: "response should be received")
  597. let completionReceived = expectation(description: "stream should complete")
  598. var response: TestResponse?
  599. // When
  600. store {
  601. AF.streamRequest(.default)
  602. .publishDecodable(type: TestResponse.self)
  603. .value()
  604. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  605. receiveValue: { received in
  606. response = received
  607. responseReceived.fulfill()
  608. })
  609. }
  610. waitForExpectations(timeout: timeout)
  611. // Then
  612. XCTAssertNotNil(response)
  613. }
  614. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  615. func testThatDataStreamRequestCanPublishValueWithFailure() {
  616. // Given
  617. let completionReceived = expectation(description: "stream should complete")
  618. var error: AFError?
  619. // When
  620. store {
  621. AF.streamRequest(Endpoint.delay(1).modifying(\.timeout, to: 0.1))
  622. .publishDecodable(type: TestResponse.self)
  623. .value()
  624. .sink(receiveCompletion: { completion in
  625. switch completion {
  626. case let .failure(err):
  627. error = err
  628. case .finished:
  629. error = nil
  630. }
  631. completionReceived.fulfill()
  632. }, receiveValue: { _ in })
  633. }
  634. waitForExpectations(timeout: timeout)
  635. // Then
  636. XCTAssertNotNil(error)
  637. XCTAssertEqual((error?.underlyingError as? URLError)?.code, .timedOut)
  638. }
  639. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  640. func testThatPublishedDataStreamRequestIsNotResumedUnlessSubscribed() {
  641. // Given
  642. let responseReceived = expectation(description: "response should be received")
  643. let completionReceived = expectation(description: "stream should complete")
  644. var result: Result<TestResponse, AFError>?
  645. // When
  646. let request = AF.streamRequest(.default)
  647. let publisher = request.publishDecodable(type: TestResponse.self)
  648. let stateAfterPublisher = request.state
  649. store {
  650. publisher.sink(receiveCompletion: { _ in completionReceived.fulfill() },
  651. receiveValue: { stream in
  652. switch stream.event {
  653. case let .stream(value):
  654. result = value
  655. case .complete:
  656. responseReceived.fulfill()
  657. }
  658. })
  659. }
  660. let stateAfterSubscription = request.state
  661. waitForExpectations(timeout: timeout)
  662. // Then
  663. XCTAssertTrue(result?.isSuccess == true)
  664. XCTAssertEqual(stateAfterPublisher, .initialized)
  665. XCTAssertEqual(stateAfterSubscription, .resumed)
  666. }
  667. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  668. func testThatDataStreamRequestCanSubscribedFromNonMainQueueButPublishedOnMainQueue() {
  669. // Given
  670. let responseReceived = expectation(description: "response should be received")
  671. let completionReceived = expectation(description: "stream should complete")
  672. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  673. var receivedOnMain = false
  674. var result: Result<TestResponse, AFError>?
  675. // When
  676. store {
  677. AF.streamRequest(.default)
  678. .publishDecodable(type: TestResponse.self)
  679. .subscribe(on: queue)
  680. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  681. receiveValue: { stream in
  682. receivedOnMain = Thread.isMainThread
  683. switch stream.event {
  684. case let .stream(value):
  685. result = value
  686. case .complete:
  687. responseReceived.fulfill()
  688. }
  689. })
  690. }
  691. waitForExpectations(timeout: timeout)
  692. // Then
  693. XCTAssertNotNil(result?.success)
  694. XCTAssertTrue(receivedOnMain)
  695. }
  696. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  697. func testThatDataStreamRequestPublishedOnSeparateQueueIsReceivedOnThatQueue() {
  698. // Given
  699. let responseReceived = expectation(description: "response should be received")
  700. let completionReceived = expectation(description: "stream should complete")
  701. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  702. var result: Result<TestResponse, AFError>?
  703. // When
  704. store {
  705. AF.streamRequest(.default)
  706. .publishDecodable(type: TestResponse.self, queue: queue)
  707. .sink(receiveCompletion: { _ in
  708. dispatchPrecondition(condition: .onQueue(queue))
  709. completionReceived.fulfill()
  710. },
  711. receiveValue: { stream in
  712. dispatchPrecondition(condition: .onQueue(queue))
  713. switch stream.event {
  714. case let .stream(value):
  715. result = value
  716. case .complete:
  717. responseReceived.fulfill()
  718. }
  719. })
  720. }
  721. waitForExpectations(timeout: timeout)
  722. // Then
  723. XCTAssertNotNil(result?.success)
  724. }
  725. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  726. func testThatDataStreamRequestPublishedOnSeparateQueueCanBeReceivedOntoMainQueue() {
  727. // Given
  728. let responseReceived = expectation(description: "response should be received")
  729. let completionReceived = expectation(description: "stream should complete")
  730. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  731. var receivedOnMain = false
  732. var result: Result<TestResponse, AFError>?
  733. // When
  734. store {
  735. AF.streamRequest(.default)
  736. .publishDecodable(type: TestResponse.self, queue: queue)
  737. .receive(on: DispatchQueue.main)
  738. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  739. receiveValue: { stream in
  740. receivedOnMain = Thread.isMainThread
  741. switch stream.event {
  742. case let .stream(value):
  743. result = value
  744. case .complete:
  745. responseReceived.fulfill()
  746. }
  747. })
  748. }
  749. waitForExpectations(timeout: timeout)
  750. // Then
  751. XCTAssertNotNil(result?.success)
  752. XCTAssertTrue(receivedOnMain)
  753. }
  754. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  755. func testThatPublishedDataStreamRequestCanBeCancelledAutomatically() throws {
  756. if #available(macOS 11, iOS 14, watchOS 7, tvOS 14, *) {
  757. throw XCTSkip("Skip on 2020 OS versions, as Combine cancellation no longer emits a value.")
  758. }
  759. // Given
  760. let responseReceived = expectation(description: "response should be received")
  761. let completionReceived = expectation(description: "stream should complete")
  762. var error: AFError?
  763. // When
  764. let request = AF.streamRequest(.default)
  765. var token: AnyCancellable? = request
  766. .publishDecodable(type: TestResponse.self)
  767. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  768. receiveValue: { error = $0.completion?.error; responseReceived.fulfill() })
  769. token = nil
  770. waitForExpectations(timeout: timeout)
  771. // Then
  772. XCTAssertNotNil(error)
  773. XCTAssertTrue(error?.isExplicitlyCancelledError == true,
  774. "error is not explicitly cancelled but \(error?.localizedDescription ?? "None")")
  775. XCTAssertTrue(request.isCancelled)
  776. XCTAssertNil(token)
  777. }
  778. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  779. func testThatPublishedDataStreamRequestCanBeCancelledManually() {
  780. // Given
  781. let responseReceived = expectation(description: "response should be received")
  782. let completionReceived = expectation(description: "stream should complete")
  783. var error: AFError?
  784. // When
  785. let request = AF.streamRequest(.default)
  786. store {
  787. request
  788. .publishDecodable(type: TestResponse.self)
  789. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  790. receiveValue: { error = $0.completion?.error; responseReceived.fulfill() })
  791. }
  792. request.cancel()
  793. waitForExpectations(timeout: timeout)
  794. // Then
  795. XCTAssertNotNil(error)
  796. XCTAssertTrue(error?.isExplicitlyCancelledError == true,
  797. "error is not explicitly cancelled but \(error?.localizedDescription ?? "None")")
  798. XCTAssertTrue(request.isCancelled)
  799. }
  800. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  801. func testThatMultipleDataStreamPublishersCanBeCombined() {
  802. // Given
  803. let responseReceived = expectation(description: "combined response should be received")
  804. let completionReceived = expectation(description: "combined stream should complete")
  805. var firstCompletion: DataStreamRequest.Completion?
  806. var secondCompletion: DataStreamRequest.Completion?
  807. // When
  808. let first = AF.streamRequest(.default)
  809. .publishDecodable(type: TestResponse.self)
  810. let second = AF.streamRequest(.default)
  811. .publishDecodable(type: TestResponse.self)
  812. store {
  813. Publishers.CombineLatest(first.compactMap(\.completion), second.compactMap(\.completion))
  814. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  815. receiveValue: { first, second in
  816. firstCompletion = first
  817. secondCompletion = second
  818. responseReceived.fulfill()
  819. })
  820. }
  821. waitForExpectations(timeout: timeout)
  822. // Then
  823. XCTAssertNotNil(firstCompletion)
  824. XCTAssertNotNil(secondCompletion)
  825. }
  826. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  827. func testThatMultipleDataStreamRequestPublishersCanBeChained() {
  828. // Given
  829. let responseReceived = expectation(description: "combined response should be received")
  830. let completionReceived = expectation(description: "combined stream should complete")
  831. var firstCompletion: DataStreamRequest.Completion?
  832. var secondCompletion: DataStreamRequest.Completion?
  833. // When
  834. store {
  835. AF.streamRequest(.default)
  836. .publishDecodable(type: TestResponse.self)
  837. .compactMap(\.completion)
  838. .flatMap { completion -> DataStreamPublisher<TestResponse> in
  839. firstCompletion = completion
  840. return AF.streamRequest(.default)
  841. .publishDecodable(type: TestResponse.self)
  842. }
  843. .compactMap(\.completion)
  844. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  845. receiveValue: { secondCompletion = $0; responseReceived.fulfill() })
  846. }
  847. waitForExpectations(timeout: timeout)
  848. // Then
  849. XCTAssertNotNil(firstCompletion)
  850. XCTAssertNotNil(secondCompletion)
  851. }
  852. }
  853. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  854. final class DownloadRequestCombineTests: CombineTestCase {
  855. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  856. @MainActor
  857. func testThatDownloadRequestCanBePublished() {
  858. // Given
  859. let responseReceived = expectation(description: "response should be received")
  860. let completionReceived = expectation(description: "publisher should complete")
  861. var response: DownloadResponse<TestResponse, AFError>?
  862. // When
  863. store {
  864. AF.download(.default)
  865. .publishDecodable(type: TestResponse.self)
  866. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  867. receiveValue: { response = $0; responseReceived.fulfill() })
  868. }
  869. waitForExpectations(timeout: timeout)
  870. // Then
  871. XCTAssertTrue(response?.result.isSuccess == true)
  872. }
  873. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  874. @MainActor
  875. func testThatNonAutomaticDownloadRequestCanBePublished() {
  876. // Given
  877. let responseReceived = expectation(description: "response should be received")
  878. let completionReceived = expectation(description: "publisher should complete")
  879. let session = Session(startRequestsImmediately: false)
  880. var response: DownloadResponse<TestResponse, AFError>?
  881. // When
  882. store {
  883. session.download(.default)
  884. .publishDecodable(type: TestResponse.self)
  885. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  886. receiveValue: { response = $0; responseReceived.fulfill() })
  887. }
  888. waitForExpectations(timeout: timeout)
  889. // Then
  890. XCTAssertTrue(response?.result.isSuccess == true)
  891. }
  892. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  893. @MainActor
  894. func testThatDownloadRequestCanPublishData() {
  895. // Given
  896. let responseReceived = expectation(description: "response should be received")
  897. let completionReceived = expectation(description: "publisher should complete")
  898. var response: DownloadResponse<Data, AFError>?
  899. // When
  900. store {
  901. AF.download(.default)
  902. .publishData()
  903. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  904. receiveValue: { response = $0; responseReceived.fulfill() })
  905. }
  906. waitForExpectations(timeout: timeout)
  907. // Then
  908. XCTAssertTrue(response?.result.isSuccess == true)
  909. }
  910. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  911. @MainActor
  912. func testThatDownloadRequestCanPublishString() {
  913. // Given
  914. let responseReceived = expectation(description: "response should be received")
  915. let completionReceived = expectation(description: "publisher should complete")
  916. var response: DownloadResponse<String, AFError>?
  917. // When
  918. store {
  919. AF.download(.default)
  920. .publishString()
  921. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  922. receiveValue: { response = $0; responseReceived.fulfill() })
  923. }
  924. waitForExpectations(timeout: timeout)
  925. // Then
  926. XCTAssertTrue(response?.result.isSuccess == true)
  927. }
  928. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  929. @MainActor
  930. func testThatDownloadRequestCanPublishUnserialized() {
  931. // Given
  932. let responseReceived = expectation(description: "response should be received")
  933. let completionReceived = expectation(description: "publisher should complete")
  934. var response: DownloadResponse<URL?, AFError>?
  935. // When
  936. store {
  937. AF.download(.default)
  938. .publishUnserialized()
  939. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  940. receiveValue: { response = $0; responseReceived.fulfill() })
  941. }
  942. waitForExpectations(timeout: timeout)
  943. // Then
  944. XCTAssertTrue(response?.result.isSuccess == true)
  945. }
  946. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  947. @MainActor
  948. func testThatDownloadRequestCanPublishURL() {
  949. // Given
  950. let responseReceived = expectation(description: "response should be received")
  951. let completionReceived = expectation(description: "publisher should complete")
  952. var response: DownloadResponse<URL, AFError>?
  953. // When
  954. store {
  955. AF.download(.default)
  956. .publishURL()
  957. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  958. receiveValue: { response = $0; responseReceived.fulfill() })
  959. }
  960. waitForExpectations(timeout: timeout)
  961. // Then
  962. XCTAssertTrue(response?.result.isSuccess == true)
  963. }
  964. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  965. @MainActor
  966. func testThatDownloadRequestCanPublishWithMultipleHandlers() {
  967. // Given
  968. let handlerResponseReceived = expectation(description: "handler response should be received")
  969. let publishedResponseReceived = expectation(description: "published response should be received")
  970. let completionReceived = expectation(description: "stream should complete")
  971. var handlerResponse: DownloadResponse<TestResponse, AFError>?
  972. var publishedResponse: DownloadResponse<TestResponse, AFError>?
  973. // When
  974. store {
  975. AF.download(.default)
  976. .responseDecodable(of: TestResponse.self) { handlerResponse = $0; handlerResponseReceived.fulfill() }
  977. .publishDecodable(type: TestResponse.self)
  978. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  979. receiveValue: { publishedResponse = $0; publishedResponseReceived.fulfill() })
  980. }
  981. waitForExpectations(timeout: timeout)
  982. // Then
  983. XCTAssertTrue(handlerResponse?.result.isSuccess == true)
  984. XCTAssertTrue(publishedResponse?.result.isSuccess == true)
  985. }
  986. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  987. @MainActor
  988. func testThatDownloadRequestCanPublishResult() {
  989. // Given
  990. let responseReceived = expectation(description: "response should be received")
  991. let completionReceived = expectation(description: "publisher should complete")
  992. var result: Result<TestResponse, AFError>?
  993. // When
  994. store {
  995. AF.download(.default)
  996. .publishDecodable(type: TestResponse.self)
  997. .result()
  998. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  999. receiveValue: { result = $0; responseReceived.fulfill() })
  1000. }
  1001. waitForExpectations(timeout: timeout)
  1002. // Then
  1003. XCTAssertTrue(result?.isSuccess == true)
  1004. }
  1005. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1006. @MainActor
  1007. func testThatDownloadRequestCanPublishValueWithFailure() {
  1008. // Given
  1009. let completionReceived = expectation(description: "stream should complete")
  1010. var error: AFError?
  1011. // When
  1012. store {
  1013. AF.download(Endpoint.delay(1).modifying(\.timeout, to: 0.1))
  1014. .publishDecodable(type: TestResponse.self)
  1015. .value()
  1016. .sink(receiveCompletion: { completion in
  1017. switch completion {
  1018. case let .failure(err):
  1019. error = err
  1020. case .finished:
  1021. error = nil
  1022. }
  1023. completionReceived.fulfill()
  1024. }, receiveValue: { _ in })
  1025. }
  1026. waitForExpectations(timeout: timeout)
  1027. // Then
  1028. XCTAssertNotNil(error)
  1029. XCTAssertEqual((error?.underlyingError as? URLError)?.code, .timedOut)
  1030. }
  1031. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1032. @MainActor
  1033. func testThatPublishedDownloadRequestIsNotResumedUnlessSubscribed() {
  1034. // Given
  1035. let responseReceived = expectation(description: "response should be received")
  1036. let completionReceived = expectation(description: "stream should complete")
  1037. var response: DownloadResponse<TestResponse, AFError>?
  1038. // When
  1039. let request = AF.download(.default)
  1040. let publisher = request.publishDecodable(type: TestResponse.self)
  1041. let stateAfterPublisher = request.state
  1042. store {
  1043. publisher.sink(receiveCompletion: { _ in completionReceived.fulfill() },
  1044. receiveValue: { response = $0; responseReceived.fulfill() })
  1045. }
  1046. let stateAfterSubscription = request.state
  1047. waitForExpectations(timeout: timeout)
  1048. // Then
  1049. XCTAssertTrue(response?.result.isSuccess == true)
  1050. XCTAssertEqual(stateAfterPublisher, .initialized)
  1051. XCTAssertEqual(stateAfterSubscription, .resumed)
  1052. }
  1053. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1054. @MainActor
  1055. func testThatDownloadRequestCanSubscribedFromNonMainQueueButPublishedOnMainQueue() {
  1056. // Given
  1057. let responseReceived = expectation(description: "response should be received")
  1058. let completionReceived = expectation(description: "stream should complete")
  1059. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  1060. var receivedOnMain = false
  1061. var response: DownloadResponse<TestResponse, AFError>?
  1062. // When
  1063. store {
  1064. AF.download(.default)
  1065. .publishDecodable(type: TestResponse.self)
  1066. .subscribe(on: queue)
  1067. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  1068. receiveValue: {
  1069. receivedOnMain = Thread.isMainThread
  1070. response = $0
  1071. responseReceived.fulfill()
  1072. })
  1073. }
  1074. waitForExpectations(timeout: timeout)
  1075. // Then
  1076. XCTAssertTrue(response?.result.isSuccess == true)
  1077. XCTAssertTrue(receivedOnMain)
  1078. }
  1079. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1080. @MainActor
  1081. func testThatDownloadRequestPublishedOnSeparateQueueIsReceivedOnThatQueue() {
  1082. // Given
  1083. let responseReceived = expectation(description: "response should be received")
  1084. let completionReceived = expectation(description: "stream should complete")
  1085. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  1086. var response: DownloadResponse<TestResponse, AFError>?
  1087. // When
  1088. store {
  1089. AF.download(.default)
  1090. .publishDecodable(type: TestResponse.self, queue: queue)
  1091. .sink(receiveCompletion: { _ in
  1092. dispatchPrecondition(condition: .onQueue(queue))
  1093. completionReceived.fulfill()
  1094. },
  1095. receiveValue: {
  1096. dispatchPrecondition(condition: .onQueue(queue))
  1097. response = $0
  1098. responseReceived.fulfill()
  1099. })
  1100. }
  1101. waitForExpectations(timeout: timeout)
  1102. // Then
  1103. XCTAssertTrue(response?.result.isSuccess == true)
  1104. }
  1105. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1106. @MainActor
  1107. func testThatDownloadRequestPublishedOnSeparateQueueCanBeReceivedOntoMainQueue() {
  1108. // Given
  1109. let responseReceived = expectation(description: "response should be received")
  1110. let completionReceived = expectation(description: "stream should complete")
  1111. let queue = DispatchQueue(label: "org.alamofire.tests.combineEventQueue")
  1112. var receivedOnMain = false
  1113. var response: DownloadResponse<TestResponse, AFError>?
  1114. // When
  1115. store {
  1116. AF.download(.default)
  1117. .publishDecodable(type: TestResponse.self, queue: queue)
  1118. .receive(on: DispatchQueue.main)
  1119. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  1120. receiveValue: {
  1121. receivedOnMain = Thread.isMainThread
  1122. response = $0
  1123. responseReceived.fulfill()
  1124. })
  1125. }
  1126. waitForExpectations(timeout: timeout)
  1127. // Then
  1128. XCTAssertTrue(response?.result.isSuccess == true)
  1129. XCTAssertTrue(receivedOnMain)
  1130. }
  1131. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1132. @MainActor
  1133. func testThatPublishedDownloadRequestCanBeCancelledAutomatically() throws {
  1134. if #available(macOS 11, iOS 14, watchOS 7, tvOS 14, *) {
  1135. throw XCTSkip("Skip on 2020 OS versions, as Combine cancellation no longer emits a value.")
  1136. }
  1137. // Given
  1138. let responseReceived = expectation(description: "response should be received")
  1139. let completionReceived = expectation(description: "stream should complete")
  1140. var response: DownloadResponse<TestResponse, AFError>?
  1141. // When
  1142. let request = AF.download(.default)
  1143. var token: AnyCancellable? = request
  1144. .publishDecodable(type: TestResponse.self)
  1145. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  1146. receiveValue: { response = $0; responseReceived.fulfill() })
  1147. token = nil
  1148. waitForExpectations(timeout: timeout)
  1149. // Then
  1150. XCTAssertTrue(response?.result.isFailure == true)
  1151. XCTAssertTrue(response?.error?.isExplicitlyCancelledError == true,
  1152. "error is not explicitly cancelled but \(response?.error?.localizedDescription ?? "None")")
  1153. XCTAssertTrue(request.isCancelled)
  1154. XCTAssertNil(token)
  1155. }
  1156. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1157. @MainActor
  1158. func testThatPublishedDownloadRequestCanBeCancelledManually() {
  1159. // Given
  1160. let responseReceived = expectation(description: "response should be received")
  1161. let completionReceived = expectation(description: "stream should complete")
  1162. var response: DownloadResponse<TestResponse, AFError>?
  1163. // When
  1164. let request = AF.download(.default)
  1165. store {
  1166. request
  1167. .publishDecodable(type: TestResponse.self)
  1168. .sink(receiveCompletion: { _ in completionReceived.fulfill() },
  1169. receiveValue: { response = $0; responseReceived.fulfill() })
  1170. }
  1171. request.cancel()
  1172. waitForExpectations(timeout: timeout)
  1173. // Then
  1174. XCTAssertTrue(response?.result.isFailure == true)
  1175. XCTAssertTrue(response?.error?.isExplicitlyCancelledError == true,
  1176. "error is not explicitly cancelled but \(response?.error?.localizedDescription ?? "None")")
  1177. XCTAssertTrue(request.isCancelled)
  1178. }
  1179. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1180. @MainActor
  1181. func testThatMultipleDownloadRequestPublishersCanBeCombined() {
  1182. // Given
  1183. let responseReceived = expectation(description: "combined response should be received")
  1184. let completionReceived = expectation(description: "combined stream should complete")
  1185. var firstResponse: DownloadResponse<TestResponse, AFError>?
  1186. var secondResponse: DownloadResponse<TestResponse, AFError>?
  1187. // When
  1188. let first = AF.download(.default)
  1189. .publishDecodable(type: TestResponse.self)
  1190. let second = AF.download(.default)
  1191. .publishDecodable(type: TestResponse.self)
  1192. store {
  1193. Publishers.CombineLatest(first, second)
  1194. .sink(receiveCompletion: { _ in completionReceived.fulfill() }) { first, second in
  1195. firstResponse = first
  1196. secondResponse = second
  1197. responseReceived.fulfill()
  1198. }
  1199. }
  1200. waitForExpectations(timeout: timeout)
  1201. // Then
  1202. XCTAssertTrue(firstResponse?.result.isSuccess == true)
  1203. XCTAssertTrue(secondResponse?.result.isSuccess == true)
  1204. }
  1205. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1206. @MainActor
  1207. func testThatMultipleDownloadRequestPublishersCanBeChained() {
  1208. // Given
  1209. let responseReceived = expectation(description: "combined response should be received")
  1210. let completionReceived = expectation(description: "combined stream should complete")
  1211. let customValue = "CustomValue"
  1212. var firstResponse: DownloadResponse<TestResponse, AFError>?
  1213. var secondResponse: DownloadResponse<TestResponse, AFError>?
  1214. // When
  1215. store {
  1216. AF.download(.default)
  1217. .publishDecodable(type: TestResponse.self)
  1218. .flatMap { response -> DownloadResponsePublisher<TestResponse> in
  1219. firstResponse = response
  1220. let request = Endpoint(headers: ["X-Custom": customValue])
  1221. return AF.download(request)
  1222. .publishDecodable(type: TestResponse.self)
  1223. }
  1224. .sink(receiveCompletion: { _ in completionReceived.fulfill() }) { response in
  1225. secondResponse = response
  1226. responseReceived.fulfill()
  1227. }
  1228. }
  1229. waitForExpectations(timeout: timeout)
  1230. // Then
  1231. XCTAssertTrue(firstResponse?.result.isSuccess == true)
  1232. XCTAssertTrue(secondResponse?.result.isSuccess == true)
  1233. XCTAssertEqual(secondResponse?.value?.headers["X-Custom"], customValue)
  1234. }
  1235. }
  1236. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
  1237. class CombineTestCase: BaseTestCase {
  1238. private lazy var storage: Set<AnyCancellable> = .init()
  1239. override func tearDown() {
  1240. storage.removeAll()
  1241. super.tearDown()
  1242. }
  1243. func store(_ toStore: () -> AnyCancellable) {
  1244. storage.insert(toStore())
  1245. }
  1246. }
  1247. #endif