229 lines
7.3 KiB
Swift
229 lines
7.3 KiB
Swift
import CryptoKit
|
|
import XCTest
|
|
@testable import Rosetta
|
|
|
|
@MainActor
|
|
final class CallRoutingTests: XCTestCase {
|
|
private let ownKey = "02-own"
|
|
private let peerA = "02-peer-a"
|
|
private let peerB = "02-peer-b"
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
CallManager.shared.resetForSessionEnd()
|
|
CallManager.shared.bindAccount(publicKey: ownKey)
|
|
}
|
|
|
|
override func tearDown() {
|
|
CallManager.shared.resetForSessionEnd()
|
|
super.tearDown()
|
|
}
|
|
|
|
func testIncomingCallMovesToIncomingPhase() {
|
|
let packet = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .incoming)
|
|
XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, peerA)
|
|
}
|
|
|
|
func testBusySignalEndsCurrentCallStateWithoutCrosstalk() {
|
|
CallManager.shared.testSetUiState(
|
|
CallUiState(
|
|
phase: .outgoing,
|
|
peerPublicKey: peerA,
|
|
statusText: "Calling..."
|
|
)
|
|
)
|
|
|
|
let packet = PacketSignalPeer(
|
|
src: "",
|
|
dst: "",
|
|
sharedPublic: "",
|
|
signalType: .endCallBecauseBusy,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
XCTAssertEqual(CallManager.shared.uiState.statusText, "User is busy")
|
|
XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, "")
|
|
}
|
|
|
|
func testPeerDisconnectedSignalEndsCurrentCallState() {
|
|
CallManager.shared.testSetUiState(
|
|
CallUiState(
|
|
phase: .active,
|
|
peerPublicKey: peerA,
|
|
statusText: "Call active"
|
|
)
|
|
)
|
|
|
|
let packet = PacketSignalPeer(
|
|
src: "",
|
|
dst: "",
|
|
sharedPublic: "",
|
|
signalType: .endCallBecausePeerDisconnected,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
XCTAssertEqual(CallManager.shared.uiState.statusText, "Peer disconnected")
|
|
XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, "")
|
|
}
|
|
|
|
func testInterleavingForeignSignalDoesNotOverrideActivePeer() {
|
|
CallManager.shared.testSetUiState(
|
|
CallUiState(
|
|
phase: .outgoing,
|
|
peerPublicKey: peerA,
|
|
statusText: "Calling..."
|
|
)
|
|
)
|
|
|
|
let foreignPacket = PacketSignalPeer(
|
|
src: peerB,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(foreignPacket)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .outgoing)
|
|
XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, peerA)
|
|
XCTAssertEqual(CallManager.shared.uiState.statusText, "Calling...")
|
|
}
|
|
|
|
func testLegacyOutgoingFlowCallAcceptKeyExchangeActive() {
|
|
let start = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerA,
|
|
title: "Peer A",
|
|
username: "peer_a"
|
|
)
|
|
XCTAssertEqual(start, .started)
|
|
|
|
let accept = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .accept,
|
|
callId: "call-legacy-1",
|
|
joinToken: "join-legacy-1",
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(accept)
|
|
|
|
XCTAssertEqual(CallManager.shared.signalingMode, .legacy)
|
|
XCTAssertEqual(CallManager.shared.callId, "call-legacy-1")
|
|
XCTAssertEqual(CallManager.shared.joinToken, "join-legacy-1")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .keyExchange)
|
|
|
|
let keyExchange = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: makePeerPublicHex(),
|
|
signalType: .keyExchange,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(keyExchange)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .keyExchange)
|
|
|
|
// Legacy ACTIVE arrives as signal code 4 with empty roomId.
|
|
let active = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .createRoom,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(active)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .webRtcExchange)
|
|
}
|
|
|
|
func testCreateRoomFallbackOutgoingFlowKeyExchangeBeforeAccept() {
|
|
let start = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerA,
|
|
title: "Peer A",
|
|
username: "peer_a"
|
|
)
|
|
XCTAssertEqual(start, .started)
|
|
|
|
let keyExchange = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: makePeerPublicHex(),
|
|
signalType: .keyExchange,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(keyExchange)
|
|
|
|
XCTAssertEqual(CallManager.shared.signalingMode, .createRoom)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .webRtcExchange)
|
|
}
|
|
|
|
func testDeferredAcceptCompletesWhenMetadataArrivesLater() {
|
|
CallManager.shared.setupIncomingCallFromPush(
|
|
callerKey: peerA,
|
|
callerName: "Peer A"
|
|
)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .incoming)
|
|
|
|
let acceptResult = CallManager.shared.acceptIncomingCall()
|
|
XCTAssertEqual(acceptResult, .started)
|
|
XCTAssertTrue(CallManager.shared.pendingIncomingAccept)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .keyExchange)
|
|
XCTAssertEqual(CallManager.shared.signalingMode, .undecided)
|
|
|
|
let delayedCall = PacketSignalPeer(
|
|
src: peerA,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
callId: "call-delayed-1",
|
|
joinToken: "join-delayed-1",
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(delayedCall)
|
|
|
|
XCTAssertEqual(CallManager.shared.signalingMode, .legacy)
|
|
XCTAssertFalse(CallManager.shared.pendingIncomingAccept)
|
|
XCTAssertEqual(CallManager.shared.callId, "call-delayed-1")
|
|
XCTAssertEqual(CallManager.shared.joinToken, "join-delayed-1")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .keyExchange)
|
|
}
|
|
|
|
func testRingingTimeoutSignalTearsDownCall() {
|
|
let start = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerA,
|
|
title: "Peer A",
|
|
username: "peer_a"
|
|
)
|
|
XCTAssertEqual(start, .started)
|
|
|
|
let timeoutPacket = PacketSignalPeer(
|
|
src: "",
|
|
dst: "",
|
|
sharedPublic: "",
|
|
signalType: .ringingTimeout,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(timeoutPacket)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
XCTAssertEqual(CallManager.shared.uiState.statusText, "No answer")
|
|
}
|
|
|
|
private func makePeerPublicHex() -> String {
|
|
Curve25519.KeyAgreement.PrivateKey().publicKey.rawRepresentation.hexString
|
|
}
|
|
}
|