From 238d71ed23e075cd363668906eef01be1303a2bd Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Tue, 10 Dec 2024 10:21:26 +0000 Subject: [PATCH] Add test for group call view --- src/room/GroupCallView.test.tsx | 119 ++++++++++++++++++++++++++++++++ src/utils/test.ts | 4 ++ 2 files changed, 123 insertions(+) create mode 100644 src/room/GroupCallView.test.tsx diff --git a/src/room/GroupCallView.test.tsx b/src/room/GroupCallView.test.tsx new file mode 100644 index 00000000..c9e6f366 --- /dev/null +++ b/src/room/GroupCallView.test.tsx @@ -0,0 +1,119 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +import { beforeEach, expect, MockedFunction, test, vitest } from "vitest"; +import { render } from "@testing-library/react"; +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc"; +import { of } from "rxjs"; +import { JoinRule, RoomState } from "matrix-js-sdk/src/matrix"; +import { Router } from "react-router-dom"; +import { createBrowserHistory } from "history"; +import userEvent from "@testing-library/user-event"; + +import { MuteStates } from "./MuteStates"; +import { prefetchSounds } from "../soundUtils"; +import { useAudioContext } from "../useAudioContext"; +import { ActiveCall } from "./InCallView"; +import { + mockMatrixRoom, + mockMatrixRoomMember, + mockRtcMembership, + MockRTCSession, +} from "../utils/test"; +import { GroupCallView } from "./GroupCallView"; + +vitest.mock("../soundUtils"); +vitest.mock("../useAudioContext"); +vitest.mock("./InCallView"); + +let playSound: MockedFunction< + NonNullable>["playSound"] +>; + +const localRtcMember = mockRtcMembership("@carol:example.org", "CCCC"); +const aliceRtcMember = mockRtcMembership("@alice:example.org", "AAAA"); +const bobRtcMember = mockRtcMembership("@bob:example.org", "BBBB"); +const daveRtcMember = mockRtcMembership("@dave:example.org", "DDDD"); + +const alice = mockMatrixRoomMember(aliceRtcMember); +const bob = mockMatrixRoomMember(bobRtcMember); +const carol = mockMatrixRoomMember(localRtcMember); +const dave = mockMatrixRoomMember(daveRtcMember); + +const roomId = "!foo:bar"; + +const roomMembers = new Map( + [alice, bob, carol, dave].map((p) => [p.userId, p]), +); + +beforeEach(() => { + (prefetchSounds as MockedFunction).mockResolvedValue({ + sound: new ArrayBuffer(0), + }); + playSound = vitest.fn().mockResolvedValue(undefined); + (useAudioContext as MockedFunction).mockReturnValue({ + playSound, + }); + // A trivial implementation of Active call to ensure we are testing GroupCallView exclusively here. + (ActiveCall as MockedFunction).mockImplementation( + ({ onLeave }) => { + return ( +
+ +
+ ); + }, + ); +}); + +test("a leave sound should be played when the user leaves the call", async () => { + const user = userEvent.setup(); + const history = createBrowserHistory(); + const client = { + getUser: () => null, + getUserId: () => localRtcMember.sender, + getDeviceId: () => localRtcMember.deviceId, + getRoom: (rId) => (rId === roomId ? room : null), + } as Partial as MatrixClient; + const room = mockMatrixRoom({ + client, + roomId, + getMember: (userId) => roomMembers.get(userId) ?? null, + getMxcAvatarUrl: () => null, + getCanonicalAlias: () => null, + currentState: { + getJoinRule: () => JoinRule.Invite, + } as Partial as RoomState, + }); + const rtcSession = new MockRTCSession( + room, + localRtcMember, + [], + ).withMemberships(of([aliceRtcMember, bobRtcMember])); + const muteState = { + audio: { enabled: false }, + video: { enabled: false }, + } as MuteStates; + const { getByText } = render( + + + , + ); + const leaveButton = getByText("Leave"); + await user.click(leaveButton); + expect(playSound).toHaveBeenCalledWith("left"); +}); diff --git a/src/utils/test.ts b/src/utils/test.ts index 459a252e..01309b10 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -263,6 +263,10 @@ export class MockRTCSession extends TypedEventEmitter< super(); } + public isJoined(): true { + return true; + } + public withMemberships( rtcMembers: Observable[]>, ): MockRTCSession {