CombineTests.swift 55 KB

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