241 lines
7.7 KiB
Swift
241 lines
7.7 KiB
Swift
import XCTest
|
|
@testable import Rosetta
|
|
|
|
@MainActor
|
|
final class CallSoundAndTimeoutTests: XCTestCase {
|
|
private let ownKey = "02-own-sound-test"
|
|
private let peerKey = "02-peer-sound-test"
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
CallManager.shared.resetForSessionEnd()
|
|
CallManager.shared.bindAccount(publicKey: ownKey)
|
|
}
|
|
|
|
override func tearDown() {
|
|
CallManager.shared.resetForSessionEnd()
|
|
super.tearDown()
|
|
}
|
|
|
|
// MARK: - Ring Timeout Tests
|
|
|
|
func testRingTimeoutTaskCreatedOnOutgoingCall() {
|
|
let result = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
|
|
XCTAssertEqual(result, .started)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be set for outgoing call")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .outgoing)
|
|
}
|
|
|
|
func testRingTimeoutTaskCreatedOnIncomingCall() {
|
|
let packet = PacketSignalPeer(
|
|
src: peerKey,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be set for incoming call")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .incoming)
|
|
}
|
|
|
|
func testRingTimeoutCancelledOnAcceptIncoming() {
|
|
// Set up incoming call
|
|
let packet = PacketSignalPeer(
|
|
src: peerKey,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
// Accept
|
|
_ = CallManager.shared.acceptIncomingCall()
|
|
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled on accept")
|
|
}
|
|
|
|
func testRingTimeoutCancelledOnDeclineIncoming() {
|
|
let packet = PacketSignalPeer(
|
|
src: peerKey,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
CallManager.shared.declineIncomingCall()
|
|
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled on decline")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
}
|
|
|
|
func testRingTimeoutCancelledOnEndCall() {
|
|
_ = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
CallManager.shared.endCall()
|
|
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled on endCall")
|
|
}
|
|
|
|
func testRingTimeoutCancelledOnBusySignal() {
|
|
_ = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
let busyPacket = PacketSignalPeer(
|
|
src: "",
|
|
dst: "",
|
|
sharedPublic: "",
|
|
signalType: .endCallBecauseBusy,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(busyPacket)
|
|
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled on busy signal")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
}
|
|
|
|
func testRingTimeoutCancelledOnPeerEndCall() {
|
|
let incomingPacket = PacketSignalPeer(
|
|
src: peerKey,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(incomingPacket)
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
let endPacket = PacketSignalPeer(
|
|
src: "",
|
|
dst: "",
|
|
sharedPublic: "",
|
|
signalType: .endCall,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(endPacket)
|
|
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled when peer ends call")
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
|
|
}
|
|
|
|
// MARK: - Sound Flow Tests (verify phase transitions trigger correct states)
|
|
|
|
func testOutgoingCallSetsCorrectPhaseForSounds() {
|
|
let result = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
|
|
XCTAssertEqual(result, .started)
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .outgoing)
|
|
// playCalling() should have been called (verified by phase)
|
|
}
|
|
|
|
func testIncomingCallSetsCorrectPhaseForSounds() {
|
|
let packet = PacketSignalPeer(
|
|
src: peerKey,
|
|
dst: ownKey,
|
|
sharedPublic: "",
|
|
signalType: .call,
|
|
roomId: ""
|
|
)
|
|
CallManager.shared.testHandleSignalPacket(packet)
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .incoming)
|
|
// playRingtone() should have been called (verified by phase)
|
|
}
|
|
|
|
func testCallActiveTransitionClearsTimeout() {
|
|
CallManager.shared.testSetUiState(
|
|
CallUiState(
|
|
phase: .webRtcExchange,
|
|
peerPublicKey: peerKey,
|
|
statusText: "Connecting..."
|
|
)
|
|
)
|
|
// Manually set timeout to verify it gets cleared
|
|
CallManager.shared.startRingTimeout()
|
|
XCTAssertNotNil(CallManager.shared.ringTimeoutTask)
|
|
|
|
CallManager.shared.setCallActiveIfNeeded()
|
|
|
|
XCTAssertEqual(CallManager.shared.uiState.phase, .active)
|
|
XCTAssertNil(CallManager.shared.ringTimeoutTask, "Ring timeout should be cancelled when call becomes active")
|
|
}
|
|
|
|
// MARK: - Duplicate Call Prevention
|
|
|
|
func testCannotStartSecondCallWhileInCall() {
|
|
_ = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
|
|
let result = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: "02-another-peer",
|
|
title: "Another",
|
|
username: "another"
|
|
)
|
|
|
|
XCTAssertEqual(result, .alreadyInCall)
|
|
XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, peerKey, "Original call should not be replaced")
|
|
}
|
|
|
|
func testCannotAcceptWhenNotIncoming() {
|
|
_ = CallManager.shared.startOutgoingCall(
|
|
toPublicKey: peerKey,
|
|
title: "Peer",
|
|
username: "peer"
|
|
)
|
|
|
|
let result = CallManager.shared.acceptIncomingCall()
|
|
|
|
XCTAssertEqual(result, .notIncoming)
|
|
}
|
|
|
|
// MARK: - CallsViewModel Filter Tests
|
|
|
|
func testCallLogDirectionMapping() {
|
|
// Outgoing with duration > 0 = outgoing
|
|
XCTAssertFalse(CallLogDirection.outgoing.isMissed)
|
|
XCTAssertTrue(CallLogDirection.outgoing.isOutgoing)
|
|
XCTAssertFalse(CallLogDirection.outgoing.isIncoming)
|
|
|
|
// Incoming with duration > 0 = incoming
|
|
XCTAssertFalse(CallLogDirection.incoming.isMissed)
|
|
XCTAssertFalse(CallLogDirection.incoming.isOutgoing)
|
|
XCTAssertTrue(CallLogDirection.incoming.isIncoming)
|
|
|
|
// Duration 0 + incoming = missed
|
|
XCTAssertTrue(CallLogDirection.missed.isMissed)
|
|
XCTAssertTrue(CallLogDirection.missed.isIncoming)
|
|
|
|
// Duration 0 + outgoing = rejected
|
|
XCTAssertFalse(CallLogDirection.rejected.isMissed)
|
|
XCTAssertTrue(CallLogDirection.rejected.isOutgoing)
|
|
}
|
|
}
|