|
|
@@ -64,6 +64,7 @@ final class WebSocketTests: BaseTestCase {
|
|
|
func testThatWebSocketsCanReceiveAMessage() {
|
|
|
// Given
|
|
|
let didReceiveMessage = expectation(description: "didReceiveMessage")
|
|
|
+ let didComplete = expectation(description: "didComplete")
|
|
|
|
|
|
let session = stored(Session())
|
|
|
|
|
|
@@ -74,6 +75,9 @@ final class WebSocketTests: BaseTestCase {
|
|
|
receivedMessage = message
|
|
|
didReceiveMessage.fulfill()
|
|
|
}
|
|
|
+ .onCompletion {
|
|
|
+ didComplete.fulfill()
|
|
|
+ }
|
|
|
|
|
|
waitForExpectations(timeout: timeout)
|
|
|
|
|
|
@@ -132,6 +136,7 @@ final class WebSocketTests: BaseTestCase {
|
|
|
func testThatWebSocketsCanReceiveADecodableValue() {
|
|
|
// Given
|
|
|
let didReceiveValue = expectation(description: "didReceiveMessage")
|
|
|
+ let didComplete = expectation(description: "didComplete")
|
|
|
|
|
|
let session = stored(Session())
|
|
|
|
|
|
@@ -142,6 +147,9 @@ final class WebSocketTests: BaseTestCase {
|
|
|
receivedValue = value
|
|
|
didReceiveValue.fulfill()
|
|
|
}
|
|
|
+ .onCompletion {
|
|
|
+ didComplete.fulfill()
|
|
|
+ }
|
|
|
|
|
|
waitForExpectations(timeout: timeout)
|
|
|
|
|
|
@@ -392,7 +400,7 @@ final class WebSocketTests: BaseTestCase {
|
|
|
XCTAssertEqual(closeCode, .normalClosure)
|
|
|
XCTAssertNil(closeReason)
|
|
|
XCTAssertNotNil(receivedCompletion)
|
|
|
-// XCTAssertNil(receivedCompletion?.error)
|
|
|
+ XCTAssertNil(receivedCompletion?.error)
|
|
|
XCTAssertNotNil(receivedPong)
|
|
|
}
|
|
|
|
|
|
@@ -511,6 +519,94 @@ final class WebSocketTests: BaseTestCase {
|
|
|
XCTAssertNil(closeReason)
|
|
|
XCTAssertNil(receivedCompletion?.error)
|
|
|
}
|
|
|
+
|
|
|
+ func testThatWebSocketsCanHaveMultipleHandlers() {
|
|
|
+ // Given
|
|
|
+ let didConnect = expectation(description: "didConnect")
|
|
|
+ didConnect.expectedFulfillmentCount = 2
|
|
|
+ let didReceiveMessage = expectation(description: "didReceiveMessage")
|
|
|
+ didReceiveMessage.expectedFulfillmentCount = 2
|
|
|
+ let didDisconnect = expectation(description: "didDisconnect")
|
|
|
+ didDisconnect.expectedFulfillmentCount = 2
|
|
|
+ let didComplete = expectation(description: "didComplete")
|
|
|
+ didComplete.expectedFulfillmentCount = 2
|
|
|
+ let session = stored(Session())
|
|
|
+
|
|
|
+ var firstConnectedProtocol: String?
|
|
|
+ var firstMessage: URLSessionWebSocketTask.Message?
|
|
|
+ var firstCloseCode: URLSessionWebSocketTask.CloseCode?
|
|
|
+ var firstCloseReason: Data?
|
|
|
+ var firstReceivedCompletion: WebSocketRequest.Completion?
|
|
|
+ var secondConnectedProtocol: String?
|
|
|
+ var secondMessage: URLSessionWebSocketTask.Message?
|
|
|
+ var secondCloseCode: URLSessionWebSocketTask.CloseCode?
|
|
|
+ var secondCloseReason: Data?
|
|
|
+ var secondReceivedCompletion: WebSocketRequest.Completion?
|
|
|
+
|
|
|
+ // When
|
|
|
+ session.websocketRequest(.websocket(closeCode: .goingAway)).streamMessageEvents { event in
|
|
|
+ switch event.kind {
|
|
|
+ case let .connected(`protocol`):
|
|
|
+ firstConnectedProtocol = `protocol`
|
|
|
+ didConnect.fulfill()
|
|
|
+ case let .receivedMessage(receivedMessage):
|
|
|
+ firstMessage = receivedMessage
|
|
|
+ didReceiveMessage.fulfill()
|
|
|
+ case let .disconnected(code, reason):
|
|
|
+ firstCloseCode = code
|
|
|
+ firstCloseReason = reason
|
|
|
+ didDisconnect.fulfill()
|
|
|
+ case let .completed(completion):
|
|
|
+ firstReceivedCompletion = completion
|
|
|
+ didComplete.fulfill()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .streamMessageEvents { event in
|
|
|
+ switch event.kind {
|
|
|
+ case let .connected(`protocol`):
|
|
|
+ secondConnectedProtocol = `protocol`
|
|
|
+ didConnect.fulfill()
|
|
|
+ case let .receivedMessage(receivedMessage):
|
|
|
+ secondMessage = receivedMessage
|
|
|
+ didReceiveMessage.fulfill()
|
|
|
+ case let .disconnected(code, reason):
|
|
|
+ secondCloseCode = code
|
|
|
+ secondCloseReason = reason
|
|
|
+ didDisconnect.fulfill()
|
|
|
+ case let .completed(completion):
|
|
|
+ secondReceivedCompletion = completion
|
|
|
+ didComplete.fulfill()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ wait(for: [didConnect, didReceiveMessage, didDisconnect, didComplete],
|
|
|
+ timeout: timeout,
|
|
|
+ enforceOrder: false)
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertNil(firstConnectedProtocol)
|
|
|
+ XCTAssertEqual(firstConnectedProtocol, secondConnectedProtocol)
|
|
|
+ XCTAssertNotNil(firstMessage)
|
|
|
+ XCTAssertEqual(firstMessage, secondMessage)
|
|
|
+ XCTAssertEqual(firstCloseCode, .goingAway)
|
|
|
+ XCTAssertEqual(firstCloseCode, secondCloseCode)
|
|
|
+ XCTAssertNil(firstCloseReason)
|
|
|
+ XCTAssertEqual(firstCloseReason, secondCloseReason)
|
|
|
+ XCTAssertNil(firstReceivedCompletion?.error)
|
|
|
+ XCTAssertNil(secondReceivedCompletion?.error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
|
+extension WebSocketRequest {
|
|
|
+ @discardableResult
|
|
|
+ func onCompletion(_ handler: @escaping () -> Void) -> Self {
|
|
|
+ streamMessageEvents { event in
|
|
|
+ guard case .completed = event.kind else { return }
|
|
|
+
|
|
|
+ handler()
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|