diff --git a/src/state/CallViewModel.test.ts b/src/state/CallViewModel.test.ts index 4b5e603f..b6935a9b 100644 --- a/src/state/CallViewModel.test.ts +++ b/src/state/CallViewModel.test.ts @@ -1291,6 +1291,51 @@ describe("waitForCallPickup$", () => { }); }); + test("ringing -> unknown if we get disconnected", () => { + withTestScheduler(({ behavior, schedule, expectObservable }) => { + const connectionState$ = new BehaviorSubject(ConnectionState.Connected); + // Someone joins at 20ms (both LiveKit participant and MatrixRTC member) + withCallViewModel( + { + remoteParticipants$: behavior("a 19ms b", { + a: [], + b: [aliceParticipant], + }), + rtcMembers$: behavior("a 19ms b", { + a: [localRtcMember], + b: [localRtcMember, aliceRtcMember], + }), + connectionState$, + }, + (vm, rtcSession) => { + // Notify at 5ms so we enter ringing, then get disconnected 5ms later + schedule(" 5ms r 5ms d", { + r: () => { + rtcSession.emit( + MatrixRTCSessionEvent.DidSendCallNotification, + mockRingEvent("$notif2", 100), + mockLegacyRingEvent, + ); + }, + d: () => { + connectionState$.next(ConnectionState.Disconnected); + }, + }); + + expectObservable(vm.callPickupState$).toBe("a 4ms b 5ms c", { + a: "unknown", + b: "ringing", + c: "unknown", + }); + }, + { + waitForCallPickup: true, + encryptionSystem: { kind: E2eeType.PER_PARTICIPANT }, + }, + ); + }); + }); + test("success when someone joins before we notify", () => { withTestScheduler(({ behavior, schedule, expectObservable }) => { // Join at 10ms, notify later at 20ms (state should stay success) diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 368d5b86..2764d45d 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -972,12 +972,12 @@ export class CallViewModel extends ViewModel { this.livekitDisconnected$, this.someoneElseJoined$, ]).pipe( - switchMap(([isDisconnected, someoneElseJoined]) => { - if (isDisconnected) { + switchMap(([disconnected, someoneElseJoined]) => { + if (disconnected) { // Do not ring until we're connected. return of("unknown" as const); } else if (someoneElseJoined) { - of("success" as const); + return of("success" as const); } // Show the ringing state of the most recent ringing attempt. return this.ring$.pipe(switchAll());