Темизация: adaptive цвета чата, context menu, attachment picker, auth + instant отклик DarkMode кнопки
This commit is contained in:
@@ -2,12 +2,23 @@ import XCTest
|
||||
@testable import Rosetta
|
||||
|
||||
final class CallPacketParityTests: XCTestCase {
|
||||
func testSignalPeerRoundTripForCallKeyExchangeAndCreateRoom() throws {
|
||||
func testSignalPeerRoundTripForLegacyCallAcceptEndCallAndKeyExchange() throws {
|
||||
let call = PacketSignalPeer(
|
||||
src: "02caller",
|
||||
dst: "02callee",
|
||||
sharedPublic: "",
|
||||
signalType: .call,
|
||||
callId: "call-123",
|
||||
joinToken: "join-123",
|
||||
roomId: ""
|
||||
)
|
||||
let accept = PacketSignalPeer(
|
||||
src: "02callee",
|
||||
dst: "02caller",
|
||||
sharedPublic: "",
|
||||
signalType: .accept,
|
||||
callId: "call-123",
|
||||
joinToken: "join-123",
|
||||
roomId: ""
|
||||
)
|
||||
let keyExchange = PacketSignalPeer(
|
||||
@@ -15,14 +26,18 @@ final class CallPacketParityTests: XCTestCase {
|
||||
dst: "02caller",
|
||||
sharedPublic: "abcdef012345",
|
||||
signalType: .keyExchange,
|
||||
callId: "",
|
||||
joinToken: "",
|
||||
roomId: ""
|
||||
)
|
||||
let createRoom = PacketSignalPeer(
|
||||
let endCall = PacketSignalPeer(
|
||||
src: "02caller",
|
||||
dst: "02callee",
|
||||
sharedPublic: "",
|
||||
signalType: .createRoom,
|
||||
roomId: "room-42"
|
||||
signalType: .endCall,
|
||||
callId: "call-123",
|
||||
joinToken: "join-123",
|
||||
roomId: ""
|
||||
)
|
||||
|
||||
let decodedCall = try decodeSignal(call)
|
||||
@@ -30,29 +45,67 @@ final class CallPacketParityTests: XCTestCase {
|
||||
XCTAssertEqual(decodedCall.src, "02caller")
|
||||
XCTAssertEqual(decodedCall.dst, "02callee")
|
||||
XCTAssertEqual(decodedCall.sharedPublic, "")
|
||||
XCTAssertEqual(decodedCall.callId, "call-123")
|
||||
XCTAssertEqual(decodedCall.joinToken, "join-123")
|
||||
XCTAssertEqual(decodedCall.roomId, "")
|
||||
|
||||
let decodedAccept = try decodeSignal(accept)
|
||||
XCTAssertEqual(decodedAccept.signalType, .accept)
|
||||
XCTAssertEqual(decodedAccept.callId, "call-123")
|
||||
XCTAssertEqual(decodedAccept.joinToken, "join-123")
|
||||
|
||||
let decodedKeyExchange = try decodeSignal(keyExchange)
|
||||
XCTAssertEqual(decodedKeyExchange.signalType, .keyExchange)
|
||||
XCTAssertEqual(decodedKeyExchange.src, "02callee")
|
||||
XCTAssertEqual(decodedKeyExchange.dst, "02caller")
|
||||
XCTAssertEqual(decodedKeyExchange.sharedPublic, "abcdef012345")
|
||||
XCTAssertEqual(decodedKeyExchange.callId, "")
|
||||
XCTAssertEqual(decodedKeyExchange.joinToken, "")
|
||||
XCTAssertEqual(decodedKeyExchange.roomId, "")
|
||||
|
||||
let decodedEndCall = try decodeSignal(endCall)
|
||||
XCTAssertEqual(decodedEndCall.signalType, .endCall)
|
||||
XCTAssertEqual(decodedEndCall.callId, "call-123")
|
||||
XCTAssertEqual(decodedEndCall.joinToken, "join-123")
|
||||
}
|
||||
|
||||
func testSignalCodeFourRoundTripForLegacyActiveAndCreateRoomFallback() throws {
|
||||
let legacyActive = PacketSignalPeer(
|
||||
src: "02caller",
|
||||
dst: "02callee",
|
||||
sharedPublic: "",
|
||||
signalType: .createRoom,
|
||||
callId: "",
|
||||
joinToken: "",
|
||||
roomId: ""
|
||||
)
|
||||
let createRoom = PacketSignalPeer(
|
||||
src: "02caller",
|
||||
dst: "02callee",
|
||||
sharedPublic: "",
|
||||
signalType: .createRoom,
|
||||
callId: "",
|
||||
joinToken: "",
|
||||
roomId: "room-42"
|
||||
)
|
||||
|
||||
let decodedLegacyActive = try decodeSignal(legacyActive)
|
||||
XCTAssertEqual(decodedLegacyActive.signalType, .createRoom)
|
||||
XCTAssertEqual(decodedLegacyActive.roomId, "")
|
||||
|
||||
let decodedCreateRoom = try decodeSignal(createRoom)
|
||||
XCTAssertEqual(decodedCreateRoom.signalType, .createRoom)
|
||||
XCTAssertEqual(decodedCreateRoom.src, "02caller")
|
||||
XCTAssertEqual(decodedCreateRoom.dst, "02callee")
|
||||
XCTAssertEqual(decodedCreateRoom.sharedPublic, "")
|
||||
XCTAssertEqual(decodedCreateRoom.roomId, "room-42")
|
||||
}
|
||||
|
||||
func testSignalPeerRoundTripForBusyAndPeerDisconnectedShortFormat() throws {
|
||||
func testSignalPeerRoundTripForBusyPeerDisconnectedAndRingingTimeoutShortFormat() throws {
|
||||
let busy = PacketSignalPeer(
|
||||
src: "02should-not-be-sent",
|
||||
dst: "02should-not-be-sent",
|
||||
sharedPublic: "ignored",
|
||||
signalType: .endCallBecauseBusy,
|
||||
callId: "ignored",
|
||||
joinToken: "ignored",
|
||||
roomId: "ignored-room"
|
||||
)
|
||||
let disconnected = PacketSignalPeer(
|
||||
@@ -60,6 +113,17 @@ final class CallPacketParityTests: XCTestCase {
|
||||
dst: "02should-not-be-sent",
|
||||
sharedPublic: "ignored",
|
||||
signalType: .endCallBecausePeerDisconnected,
|
||||
callId: "ignored",
|
||||
joinToken: "ignored",
|
||||
roomId: "ignored-room"
|
||||
)
|
||||
let ringingTimeout = PacketSignalPeer(
|
||||
src: "02should-not-be-sent",
|
||||
dst: "02should-not-be-sent",
|
||||
sharedPublic: "ignored",
|
||||
signalType: .ringingTimeout,
|
||||
callId: "ignored",
|
||||
joinToken: "ignored",
|
||||
roomId: "ignored-room"
|
||||
)
|
||||
|
||||
@@ -68,6 +132,8 @@ final class CallPacketParityTests: XCTestCase {
|
||||
XCTAssertEqual(decodedBusy.src, "")
|
||||
XCTAssertEqual(decodedBusy.dst, "")
|
||||
XCTAssertEqual(decodedBusy.sharedPublic, "")
|
||||
XCTAssertEqual(decodedBusy.callId, "")
|
||||
XCTAssertEqual(decodedBusy.joinToken, "")
|
||||
XCTAssertEqual(decodedBusy.roomId, "")
|
||||
|
||||
let decodedDisconnected = try decodeSignal(disconnected)
|
||||
@@ -75,7 +141,18 @@ final class CallPacketParityTests: XCTestCase {
|
||||
XCTAssertEqual(decodedDisconnected.src, "")
|
||||
XCTAssertEqual(decodedDisconnected.dst, "")
|
||||
XCTAssertEqual(decodedDisconnected.sharedPublic, "")
|
||||
XCTAssertEqual(decodedDisconnected.callId, "")
|
||||
XCTAssertEqual(decodedDisconnected.joinToken, "")
|
||||
XCTAssertEqual(decodedDisconnected.roomId, "")
|
||||
|
||||
let decodedTimeout = try decodeSignal(ringingTimeout)
|
||||
XCTAssertEqual(decodedTimeout.signalType, .ringingTimeout)
|
||||
XCTAssertEqual(decodedTimeout.src, "")
|
||||
XCTAssertEqual(decodedTimeout.dst, "")
|
||||
XCTAssertEqual(decodedTimeout.sharedPublic, "")
|
||||
XCTAssertEqual(decodedTimeout.callId, "")
|
||||
XCTAssertEqual(decodedTimeout.joinToken, "")
|
||||
XCTAssertEqual(decodedTimeout.roomId, "")
|
||||
}
|
||||
|
||||
func testWebRtcRoundTripForOfferAnswerAndIceCandidate() throws {
|
||||
|
||||
@@ -97,12 +97,14 @@ struct SignalPeerCallFlowTests {
|
||||
let caller = "02a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
|
||||
let callee = "03f0e1d2c3b4a5968778695a4b3c2d1e0f9e8d7c6b5a49382716051a2b3c4d5e6f"
|
||||
let packet = PacketSignalPeer(src: caller, dst: callee, sharedPublic: "",
|
||||
signalType: .call, roomId: "")
|
||||
signalType: .call, callId: "call-1", joinToken: "join-1", roomId: "")
|
||||
let decoded = try decode(packet)
|
||||
#expect(decoded.signalType == .call)
|
||||
#expect(decoded.src == caller)
|
||||
#expect(decoded.dst == callee)
|
||||
#expect(decoded.sharedPublic == "")
|
||||
#expect(decoded.callId == "call-1")
|
||||
#expect(decoded.joinToken == "join-1")
|
||||
#expect(decoded.roomId == "")
|
||||
}
|
||||
|
||||
@@ -153,6 +155,19 @@ struct SignalPeerCallFlowTests {
|
||||
#expect(decoded.signalType == .endCallBecausePeerDisconnected)
|
||||
}
|
||||
|
||||
@Test("RINGING_TIMEOUT short format — 3 bytes wire size")
|
||||
func ringingTimeoutShortFormat() throws {
|
||||
let packet = PacketSignalPeer(src: "ignored", dst: "ignored", sharedPublic: "ignored",
|
||||
signalType: .ringingTimeout, roomId: "ignored")
|
||||
let data = PacketRegistry.encode(packet)
|
||||
#expect(data.count == 3)
|
||||
|
||||
let decoded = try decode(packet)
|
||||
#expect(decoded.signalType == .ringingTimeout)
|
||||
#expect(decoded.src == "")
|
||||
#expect(decoded.dst == "")
|
||||
}
|
||||
|
||||
private func decode(_ packet: PacketSignalPeer) throws -> PacketSignalPeer {
|
||||
let data = PacketRegistry.encode(packet)
|
||||
guard let result = PacketRegistry.decode(from: data),
|
||||
@@ -171,7 +186,8 @@ struct CallPushEnumParityTests {
|
||||
arguments: [
|
||||
(SignalType.call, 0), (SignalType.keyExchange, 1), (SignalType.activeCall, 2),
|
||||
(SignalType.endCall, 3), (SignalType.createRoom, 4),
|
||||
(SignalType.endCallBecausePeerDisconnected, 5), (SignalType.endCallBecauseBusy, 6)
|
||||
(SignalType.endCallBecausePeerDisconnected, 5), (SignalType.endCallBecauseBusy, 6),
|
||||
(SignalType.accept, 7), (SignalType.ringingTimeout, 8)
|
||||
])
|
||||
func signalTypeEnumValues(pair: (SignalType, Int)) {
|
||||
#expect(pair.0.rawValue == pair.1)
|
||||
@@ -222,12 +238,12 @@ struct CallPushWireFormatTests {
|
||||
#expect(data[14] == 0x00); #expect(data[15] == 0x42)
|
||||
}
|
||||
|
||||
@Test("SignalPeer call byte layout: signalType→src→dst")
|
||||
@Test("SignalPeer call byte layout: signalType→src→dst→callId→joinToken")
|
||||
func signalPeerCallByteLayout() {
|
||||
let packet = PacketSignalPeer(src: "S", dst: "D", sharedPublic: "",
|
||||
signalType: .call, roomId: "")
|
||||
let data = PacketRegistry.encode(packet)
|
||||
#expect(data.count == 15)
|
||||
#expect(data.count == 23)
|
||||
|
||||
// packetId = 0x001A
|
||||
#expect(data[0] == 0x00); #expect(data[1] == 0x1A)
|
||||
@@ -241,6 +257,12 @@ struct CallPushWireFormatTests {
|
||||
#expect(data[9] == 0x00); #expect(data[10] == 0x00)
|
||||
#expect(data[11] == 0x00); #expect(data[12] == 0x01)
|
||||
#expect(data[13] == 0x00); #expect(data[14] == 0x44)
|
||||
// callId "": length=0
|
||||
#expect(data[15] == 0x00); #expect(data[16] == 0x00)
|
||||
#expect(data[17] == 0x00); #expect(data[18] == 0x00)
|
||||
// joinToken "": length=0
|
||||
#expect(data[19] == 0x00); #expect(data[20] == 0x00)
|
||||
#expect(data[21] == 0x00); #expect(data[22] == 0x00)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import CryptoKit
|
||||
import XCTest
|
||||
@testable import Rosetta
|
||||
|
||||
@@ -101,4 +102,127 @@ final class CallRoutingTests: XCTestCase {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user