DataStreamTests.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. //
  2. // DataStreamTests.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. import Alamofire
  25. import XCTest
  26. final class DataStreamTests: BaseTestCase {
  27. func testThatDataCanBeStreamedOnMainQueue() {
  28. // Given
  29. let expectedSize = 1000
  30. var accumulatedData = Data()
  31. var response: HTTPURLResponse?
  32. var streamOnMain = false
  33. var completeOnMain = false
  34. let expect = expectation(description: "stream should complete")
  35. // When
  36. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "bytes/\(expectedSize)")).responseStream { stream in
  37. switch stream.event {
  38. case let .stream(result):
  39. streamOnMain = Thread.isMainThread
  40. switch result {
  41. case let .success(data):
  42. accumulatedData.append(data)
  43. }
  44. case let .complete(completion):
  45. completeOnMain = Thread.isMainThread
  46. response = completion.response
  47. expect.fulfill()
  48. }
  49. }
  50. waitForExpectations(timeout: timeout)
  51. // Then
  52. XCTAssertEqual(response?.statusCode, 200)
  53. XCTAssertEqual(accumulatedData.count, expectedSize)
  54. XCTAssertTrue(streamOnMain)
  55. XCTAssertTrue(completeOnMain)
  56. }
  57. func testThatDataCanBeStreamedFromURL() {
  58. // Given
  59. let expectedSize = 1000
  60. var accumulatedData = Data()
  61. var response: HTTPURLResponse?
  62. var streamOnMain = false
  63. var completeOnMain = false
  64. let expect = expectation(description: "stream should complete")
  65. // When
  66. AF.streamRequest("https://httpbin.org/bytes/\(expectedSize)").responseStream { stream in
  67. switch stream.event {
  68. case let .stream(result):
  69. streamOnMain = Thread.isMainThread
  70. switch result {
  71. case let .success(data):
  72. accumulatedData.append(data)
  73. }
  74. case let .complete(completion):
  75. completeOnMain = Thread.isMainThread
  76. response = completion.response
  77. expect.fulfill()
  78. }
  79. }
  80. waitForExpectations(timeout: timeout)
  81. // Then
  82. XCTAssertEqual(response?.statusCode, 200)
  83. XCTAssertEqual(accumulatedData.count, expectedSize)
  84. XCTAssertTrue(streamOnMain)
  85. XCTAssertTrue(completeOnMain)
  86. }
  87. func testThatDataCanBeStreamedManyTimes() {
  88. // Given
  89. let expectedSize = 1000
  90. var firstAccumulatedData = Data()
  91. var firstResponse: HTTPURLResponse?
  92. var firstStreamOnMain = false
  93. var firstCompleteOnMain = false
  94. let firstExpectation = expectation(description: "first stream should complete")
  95. var secondAccumulatedData = Data()
  96. var secondResponse: HTTPURLResponse?
  97. var secondStreamOnMain = false
  98. var secondCompleteOnMain = false
  99. let secondExpectation = expectation(description: "second stream should complete")
  100. // When
  101. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "bytes/\(expectedSize)"))
  102. .responseStream { stream in
  103. switch stream.event {
  104. case let .stream(result):
  105. firstStreamOnMain = Thread.isMainThread
  106. switch result {
  107. case let .success(data):
  108. firstAccumulatedData.append(data)
  109. }
  110. case let .complete(completion):
  111. firstCompleteOnMain = Thread.isMainThread
  112. firstResponse = completion.response
  113. firstExpectation.fulfill()
  114. }
  115. }
  116. .responseStream { stream in
  117. switch stream.event {
  118. case let .stream(result):
  119. secondStreamOnMain = Thread.isMainThread
  120. switch result {
  121. case let .success(data):
  122. secondAccumulatedData.append(data)
  123. }
  124. case let .complete(completion):
  125. secondCompleteOnMain = Thread.isMainThread
  126. secondResponse = completion.response
  127. secondExpectation.fulfill()
  128. }
  129. }
  130. waitForExpectations(timeout: timeout)
  131. // Then
  132. XCTAssertTrue(firstStreamOnMain)
  133. XCTAssertTrue(firstCompleteOnMain)
  134. XCTAssertEqual(firstResponse?.statusCode, 200)
  135. XCTAssertEqual(firstAccumulatedData.count, expectedSize)
  136. XCTAssertTrue(secondStreamOnMain)
  137. XCTAssertTrue(secondCompleteOnMain)
  138. XCTAssertEqual(secondResponse?.statusCode, 200)
  139. XCTAssertEqual(secondAccumulatedData.count, expectedSize)
  140. }
  141. func testThatDataCanBeStreamedAndDecodedAtTheSameTime() {
  142. // Given
  143. var firstAccumulatedData = Data()
  144. var firstResponse: HTTPURLResponse?
  145. var firstStreamOnMain = false
  146. var firstCompleteOnMain = false
  147. let firstExpectation = expectation(description: "first stream should complete")
  148. var decodedResponse: HTTPBinResponse?
  149. var decodingError: AFError?
  150. var secondResponse: HTTPURLResponse?
  151. var secondStreamOnMain = false
  152. var secondCompleteOnMain = false
  153. let secondExpectation = expectation(description: "second stream should complete")
  154. // When
  155. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  156. .responseStream { stream in
  157. switch stream.event {
  158. case let .stream(result):
  159. firstStreamOnMain = Thread.isMainThread
  160. switch result {
  161. case let .success(data):
  162. firstAccumulatedData.append(data)
  163. }
  164. case let .complete(completion):
  165. firstCompleteOnMain = Thread.isMainThread
  166. firstResponse = completion.response
  167. firstExpectation.fulfill()
  168. }
  169. }
  170. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  171. switch stream.event {
  172. case let .stream(result):
  173. secondStreamOnMain = Thread.isMainThread
  174. switch result {
  175. case let .success(value):
  176. decodedResponse = value
  177. case let .failure(error):
  178. decodingError = error
  179. }
  180. case let .complete(completion):
  181. secondCompleteOnMain = Thread.isMainThread
  182. secondResponse = completion.response
  183. secondExpectation.fulfill()
  184. }
  185. }
  186. waitForExpectations(timeout: timeout)
  187. // Then
  188. XCTAssertTrue(firstStreamOnMain)
  189. XCTAssertTrue(firstCompleteOnMain)
  190. XCTAssertEqual(firstResponse?.statusCode, 200)
  191. XCTAssertTrue(!firstAccumulatedData.isEmpty)
  192. XCTAssertTrue(secondStreamOnMain)
  193. XCTAssertTrue(secondCompleteOnMain)
  194. XCTAssertEqual(secondResponse?.statusCode, 200)
  195. XCTAssertNotNil(decodedResponse)
  196. XCTAssertNil(decodingError)
  197. }
  198. func testThatDataStreamRequestProducesWorkingInputStream() {
  199. // Given
  200. let expect = expectation(description: "stream complete")
  201. // When
  202. let stream = AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "xml",
  203. headers: [.contentType("application/xml")]))
  204. .responseStream { stream in
  205. switch stream.event {
  206. case .complete:
  207. expect.fulfill()
  208. default: break
  209. }
  210. }.asInputStream()
  211. waitForExpectations(timeout: timeout)
  212. // Then
  213. let parser = XMLParser(stream: stream!)
  214. let parsed = parser.parse()
  215. XCTAssertTrue(parsed)
  216. XCTAssertNil(parser.parserError)
  217. }
  218. func testThatDataStreamCanBeManuallyResumed() {
  219. // Given
  220. let session = Session(startRequestsImmediately: false)
  221. var response: HTTPURLResponse?
  222. var streamOnMain = false
  223. var completeOnMain = false
  224. let expect = expectation(description: "stream complete")
  225. // When
  226. session.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  227. .responseStream { stream in
  228. switch stream.event {
  229. case .stream:
  230. streamOnMain = Thread.isMainThread
  231. case let .complete(completion):
  232. completeOnMain = Thread.isMainThread
  233. response = completion.response
  234. expect.fulfill()
  235. }
  236. }.resume()
  237. waitForExpectations(timeout: timeout)
  238. // Then
  239. XCTAssertTrue(streamOnMain)
  240. XCTAssertTrue(completeOnMain)
  241. XCTAssertEqual(response?.statusCode, 200)
  242. }
  243. func testThatDataStreamIsAutomaticallyCanceledOnStreamErrorWhenEnabled() {
  244. var response: HTTPURLResponse?
  245. var complete: DataStreamRequest.Completion?
  246. let expect = expectation(description: "stream complete")
  247. // When
  248. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "bytes/50"), automaticallyCancelOnStreamError: true)
  249. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  250. switch stream.event {
  251. case let .complete(completion):
  252. complete = completion
  253. response = completion.response
  254. expect.fulfill()
  255. default: break
  256. }
  257. }
  258. waitForExpectations(timeout: timeout)
  259. // Then
  260. XCTAssertEqual(response?.statusCode, 200)
  261. XCTAssertTrue(complete?.error?.isExplicitlyCancelledError == true)
  262. }
  263. func testThatDataStreamIsAutomaticallyCanceledOnStreamClosureError() {
  264. // Given
  265. enum LocalError: Error { case failed }
  266. var response: HTTPURLResponse?
  267. var complete: DataStreamRequest.Completion?
  268. let expect = expectation(description: "stream complete")
  269. // When
  270. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "bytes/50"))
  271. .responseStream { stream in
  272. switch stream.event {
  273. case .stream: throw LocalError.failed
  274. case let .complete(completion):
  275. complete = completion
  276. response = completion.response
  277. expect.fulfill()
  278. }
  279. }
  280. waitForExpectations(timeout: timeout)
  281. // Then
  282. XCTAssertEqual(response?.statusCode, 200)
  283. XCTAssertTrue(complete?.error?.isExplicitlyCancelledError == false)
  284. }
  285. func testThatDataStreamCanBeCancelledInClosure() {
  286. // Given
  287. let expectedSize = 1000
  288. var error: AFError?
  289. let expect = expectation(description: "stream should complete")
  290. // When
  291. AF.streamRequest("https://httpbin.org/bytes/\(expectedSize)").responseStream { stream in
  292. switch stream.event {
  293. case .stream:
  294. stream.cancel()
  295. case .complete:
  296. error = stream.completion?.error
  297. expect.fulfill()
  298. }
  299. }
  300. waitForExpectations(timeout: timeout)
  301. // Then
  302. XCTAssertTrue(error?.isExplicitlyCancelledError == true)
  303. }
  304. func testThatDataStreamCanBeCancelledByToken() {
  305. // Given
  306. let expectedSize = 1000
  307. var error: AFError?
  308. let expect = expectation(description: "stream should complete")
  309. // When
  310. AF.streamRequest("https://httpbin.org/bytes/\(expectedSize)").responseStream { stream in
  311. switch stream.event {
  312. case .stream:
  313. stream.token.cancel()
  314. case .complete:
  315. error = stream.completion?.error
  316. expect.fulfill()
  317. }
  318. }
  319. waitForExpectations(timeout: timeout)
  320. // Then
  321. XCTAssertTrue(error?.isExplicitlyCancelledError == true)
  322. }
  323. }
  324. // MARK: - Serialization Tests
  325. final class DataStreamSerializationTests: BaseTestCase {
  326. func testThatDataStreamsCanBeAString() {
  327. // Given
  328. var responseString: String?
  329. var streamOnMain = false
  330. var completeOnMain = false
  331. var response: HTTPURLResponse?
  332. let expect = expectation(description: "stream complete")
  333. // When
  334. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  335. .responseStreamString { stream in
  336. switch stream.event {
  337. case let .stream(result):
  338. streamOnMain = Thread.isMainThread
  339. switch result {
  340. case let .success(string):
  341. responseString = string
  342. }
  343. case let .complete(completion):
  344. completeOnMain = Thread.isMainThread
  345. response = completion.response
  346. expect.fulfill()
  347. }
  348. }
  349. waitForExpectations(timeout: timeout)
  350. // Then
  351. XCTAssertTrue(streamOnMain)
  352. XCTAssertTrue(completeOnMain)
  353. XCTAssertNotNil(responseString)
  354. XCTAssertEqual(response?.statusCode, 200)
  355. }
  356. func testThatDataStreamsCanBeDecoded() {
  357. // Given
  358. // Only 1 right now, as multiple responses return invalid JSON from httpbin.org.
  359. let count = 1
  360. var responses: [HTTPBinResponse] = []
  361. var response: HTTPURLResponse?
  362. var decodingError: AFError?
  363. var streamOnMain = false
  364. var completeOnMain = false
  365. let expect = expectation(description: "stream complete")
  366. // When
  367. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/\(count)"))
  368. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  369. switch stream.event {
  370. case let .stream(result):
  371. streamOnMain = Thread.isMainThread
  372. switch result {
  373. case let .success(value):
  374. responses.append(value)
  375. case let .failure(error):
  376. decodingError = error
  377. }
  378. case let .complete(completion):
  379. completeOnMain = Thread.isMainThread
  380. response = completion.response
  381. expect.fulfill()
  382. }
  383. }
  384. waitForExpectations(timeout: timeout)
  385. // Then
  386. XCTAssertTrue(streamOnMain)
  387. XCTAssertTrue(completeOnMain)
  388. XCTAssertEqual(responses.count, count)
  389. XCTAssertEqual(response?.statusCode, 200)
  390. XCTAssertNil(decodingError)
  391. }
  392. func testThatDataStreamSerializerCanBeUsedDirectly() {
  393. // Given
  394. var response: HTTPURLResponse?
  395. var decodedResponse: HTTPBinResponse?
  396. var decodingError: AFError?
  397. var streamOnMain = false
  398. var completeOnMain = false
  399. let serializer = DecodableStreamSerializer<HTTPBinResponse>()
  400. let expect = expectation(description: "stream complete")
  401. // When
  402. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  403. .responseStream(using: serializer) { stream in
  404. switch stream.event {
  405. case let .stream(result):
  406. streamOnMain = Thread.isMainThread
  407. switch result {
  408. case let .success(value):
  409. decodedResponse = value
  410. case let .failure(error):
  411. decodingError = error
  412. }
  413. case let .complete(completion):
  414. completeOnMain = Thread.isMainThread
  415. response = completion.response
  416. expect.fulfill()
  417. }
  418. }
  419. waitForExpectations(timeout: timeout)
  420. // Then
  421. XCTAssertTrue(streamOnMain)
  422. XCTAssertTrue(completeOnMain)
  423. XCTAssertNotNil(decodedResponse)
  424. XCTAssertEqual(response?.statusCode, 200)
  425. XCTAssertNil(decodingError)
  426. }
  427. }
  428. // MARK: - Integration Tests
  429. final class DataStreamIntegrationTests: BaseTestCase {
  430. func testThatDataStreamCanFailValidation() {
  431. // Given
  432. let request = URLRequest.makeHTTPBinRequest(path: "status/401")
  433. var dataSeen = false
  434. var error: AFError?
  435. let expect = expectation(description: "stream should complete")
  436. // When
  437. AF.streamRequest(request).validate().responseStream { stream in
  438. switch stream.event {
  439. case .stream: dataSeen = true
  440. case let .complete(completion):
  441. error = completion.error
  442. expect.fulfill()
  443. }
  444. }
  445. waitForExpectations(timeout: timeout)
  446. // Then
  447. XCTAssertNotNil(error, "error should not be nil")
  448. XCTAssertTrue(error?.isResponseValidationError == true, "error should be response validation error")
  449. XCTAssertFalse(dataSeen, "no data should be seen")
  450. }
  451. func testThatDataStreamsCanBeRetried() {
  452. // Given
  453. final class GoodRetry: RequestInterceptor {
  454. var hasRetried = false
  455. func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  456. if hasRetried {
  457. completion(.success(URLRequest.makeHTTPBinRequest(path: "bytes/1000")))
  458. } else {
  459. completion(.success(urlRequest))
  460. }
  461. }
  462. func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
  463. hasRetried = true
  464. completion(.retry)
  465. }
  466. }
  467. let session = Session(interceptor: GoodRetry())
  468. var accumulatedData = Data()
  469. var streamOnMain = false
  470. var completeOnMain = false
  471. var response: HTTPURLResponse?
  472. let expect = expectation(description: "stream should complete")
  473. // When
  474. session.streamRequest(URLRequest.makeHTTPBinRequest(path: "status/401"))
  475. .validate()
  476. .responseStream { stream in
  477. switch stream.event {
  478. case let .stream(result):
  479. streamOnMain = Thread.isMainThread
  480. switch result {
  481. case let .success(data):
  482. accumulatedData.append(data)
  483. }
  484. case let .complete(completion):
  485. completeOnMain = Thread.isMainThread
  486. response = completion.response
  487. expect.fulfill()
  488. }
  489. }
  490. waitForExpectations(timeout: timeout)
  491. // Then
  492. XCTAssertTrue(streamOnMain)
  493. XCTAssertTrue(completeOnMain)
  494. XCTAssertEqual(accumulatedData.count, 1000)
  495. XCTAssertEqual(response?.statusCode, 200)
  496. }
  497. func testThatDataStreamCanBeRedirected() {
  498. // Given
  499. var response: HTTPURLResponse?
  500. var decodedResponse: HTTPBinResponse?
  501. var decodingError: AFError?
  502. var streamOnMain = false
  503. var completeOnMain = false
  504. let redirected = expectation(description: "stream redirected")
  505. let redirector = Redirector(behavior: .modify { _, _, _ in
  506. redirected.fulfill()
  507. return URLRequest.makeHTTPBinRequest(path: "stream/1")
  508. })
  509. let expect = expectation(description: "stream complete")
  510. // When
  511. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "status/301"))
  512. .redirect(using: redirector)
  513. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  514. switch stream.event {
  515. case let .stream(result):
  516. streamOnMain = Thread.isMainThread
  517. switch result {
  518. case let .success(value):
  519. decodedResponse = value
  520. case let .failure(error):
  521. decodingError = error
  522. }
  523. case let .complete(completion):
  524. completeOnMain = Thread.isMainThread
  525. response = completion.response
  526. expect.fulfill()
  527. }
  528. }
  529. waitForExpectations(timeout: timeout)
  530. // Then
  531. XCTAssertTrue(streamOnMain)
  532. XCTAssertTrue(completeOnMain)
  533. XCTAssertNotNil(decodedResponse)
  534. XCTAssertEqual(response?.statusCode, 200)
  535. XCTAssertNil(decodingError)
  536. }
  537. func testThatDataStreamCallsCachedResponseHandler() {
  538. // Given
  539. var response: HTTPURLResponse?
  540. var decodedResponse: HTTPBinResponse?
  541. var decodingError: AFError?
  542. var streamOnMain = false
  543. var completeOnMain = false
  544. let cached = expectation(description: "stream called cacher")
  545. let cacher = ResponseCacher(behavior: .modify { _, _ in
  546. cached.fulfill()
  547. return nil
  548. })
  549. let expect = expectation(description: "stream complete")
  550. // When
  551. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  552. .cacheResponse(using: cacher)
  553. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  554. switch stream.event {
  555. case let .stream(result):
  556. streamOnMain = Thread.isMainThread
  557. switch result {
  558. case let .success(value):
  559. decodedResponse = value
  560. case let .failure(error):
  561. decodingError = error
  562. }
  563. case let .complete(completion):
  564. completeOnMain = Thread.isMainThread
  565. response = completion.response
  566. expect.fulfill()
  567. }
  568. }
  569. waitForExpectations(timeout: timeout)
  570. // Then
  571. XCTAssertTrue(streamOnMain)
  572. XCTAssertTrue(completeOnMain)
  573. XCTAssertNotNil(decodedResponse)
  574. XCTAssertEqual(response?.statusCode, 200)
  575. XCTAssertNil(decodingError)
  576. }
  577. func testThatDataStreamCanAuthenticate() {
  578. // Given
  579. var response: HTTPURLResponse?
  580. var streamOnMain = false
  581. var completeOnMain = false
  582. let expect = expectation(description: "stream complete")
  583. // When
  584. AF.streamRequest(URLRequest.makeHTTPBinRequest(path: "basic-auth/username/password"))
  585. .authenticate(username: "username", password: "password")
  586. .responseStream { stream in
  587. switch stream.event {
  588. case .stream:
  589. streamOnMain = Thread.isMainThread
  590. case let .complete(completion):
  591. completeOnMain = Thread.isMainThread
  592. response = completion.response
  593. expect.fulfill()
  594. }
  595. }
  596. waitForExpectations(timeout: timeout)
  597. // Then
  598. XCTAssertTrue(streamOnMain)
  599. XCTAssertTrue(completeOnMain)
  600. XCTAssertEqual(response?.statusCode, 200)
  601. }
  602. }
  603. final class DataStreamLifetimeEvents: BaseTestCase {
  604. func testThatDataStreamRequestHasAppropriateLifetimeEvents() {
  605. // Given
  606. final class Monitor: EventMonitor {
  607. var called: (() -> Void)?
  608. func request<Value>(_ request: DataStreamRequest, didParseStream result: Result<Value, AFError>) {
  609. called?()
  610. }
  611. }
  612. let eventMonitor = ClosureEventMonitor()
  613. let parseMonitor = Monitor()
  614. let session = Session(eventMonitors: [eventMonitor, parseMonitor])
  615. let didReceiveChallenge = expectation(description: "didReceiveChallenge should fire")
  616. let taskDidFinishCollecting = expectation(description: "taskDidFinishCollecting should fire")
  617. let didReceiveData = expectation(description: "didReceiveData should fire")
  618. let willCacheResponse = expectation(description: "willCacheResponse should fire")
  619. let didCreateURLRequest = expectation(description: "didCreateInitialURLRequest should fire")
  620. let didCreateTask = expectation(description: "didCreateTask should fire")
  621. let didGatherMetrics = expectation(description: "didGatherMetrics should fire")
  622. let didComplete = expectation(description: "didComplete should fire")
  623. let didFinish = expectation(description: "didFinish should fire")
  624. let didResume = expectation(description: "didResume should fire")
  625. let didResumeTask = expectation(description: "didResumeTask should fire")
  626. let didValidate = expectation(description: "didValidateRequest should fire")
  627. didValidate.expectedFulfillmentCount = 2
  628. let didParse = expectation(description: "streamDidParse should fire")
  629. let responseHandler = expectation(description: "responseHandler should fire")
  630. var dataReceived = false
  631. eventMonitor.taskDidReceiveChallenge = { _, _, _ in didReceiveChallenge.fulfill() }
  632. eventMonitor.taskDidFinishCollectingMetrics = { _, _, _ in taskDidFinishCollecting.fulfill() }
  633. eventMonitor.dataTaskDidReceiveData = { _, _, _ in
  634. guard !dataReceived else { return }
  635. // Data may be received many times, fulfill only once.
  636. dataReceived = true
  637. didReceiveData.fulfill()
  638. }
  639. eventMonitor.dataTaskWillCacheResponse = { _, _, _ in willCacheResponse.fulfill() }
  640. eventMonitor.requestDidCreateInitialURLRequest = { _, _ in didCreateURLRequest.fulfill() }
  641. eventMonitor.requestDidCreateTask = { _, _ in didCreateTask.fulfill() }
  642. eventMonitor.requestDidGatherMetrics = { _, _ in didGatherMetrics.fulfill() }
  643. eventMonitor.requestDidCompleteTaskWithError = { _, _, _ in didComplete.fulfill() }
  644. eventMonitor.requestDidFinish = { _ in didFinish.fulfill() }
  645. eventMonitor.requestDidResume = { _ in didResume.fulfill() }
  646. eventMonitor.requestDidResumeTask = { _, _ in didResumeTask.fulfill() }
  647. eventMonitor.requestDidValidateRequestResponseWithResult = { _, _, _, _ in didValidate.fulfill() }
  648. parseMonitor.called = { didParse.fulfill() }
  649. // When
  650. let request = session.streamRequest(URLRequest.makeHTTPBinRequest(path: "stream/1"))
  651. .validate()
  652. .responseStreamDecodable(of: HTTPBinResponse.self) { stream in
  653. switch stream.event {
  654. case .complete:
  655. responseHandler.fulfill()
  656. default: break
  657. }
  658. }
  659. waitForExpectations(timeout: timeout, handler: nil)
  660. // Then
  661. XCTAssertEqual(request.state, .finished)
  662. }
  663. }