Test: Fix mocking to fix failing tests

This commit is contained in:
Valere
2025-10-10 11:09:41 +02:00
parent a500915c43
commit 6710f4c72a
8 changed files with 50 additions and 37 deletions

View File

@@ -10,7 +10,6 @@ import { expect, test } from "vitest";
import { TooltipProvider } from "@vector-im/compound-web"; import { TooltipProvider } from "@vector-im/compound-web";
import { userEvent } from "@testing-library/user-event"; import { userEvent } from "@testing-library/user-event";
import { type ReactNode } from "react"; import { type ReactNode } from "react";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
import { ReactionToggleButton } from "./ReactionToggleButton"; import { ReactionToggleButton } from "./ReactionToggleButton";
import { ElementCallReactionEventType } from "../reactions"; import { ElementCallReactionEventType } from "../reactions";
@@ -33,7 +32,7 @@ function TestComponent({
<TooltipProvider> <TooltipProvider>
<ReactionsSenderProvider <ReactionsSenderProvider
vm={vm} vm={vm}
rtcSession={rtcSession as unknown as MatrixRTCSession} rtcSession={rtcSession.asMockedSession()}
> >
<ReactionToggleButton vm={vm} identifier={localIdent} /> <ReactionToggleButton vm={vm} identifier={localIdent} />
</ReactionsSenderProvider> </ReactionsSenderProvider>

View File

@@ -7,7 +7,6 @@ Please see LICENSE in the repository root for full details.
import { renderHook } from "@testing-library/react"; import { renderHook } from "@testing-library/react";
import { afterEach, test, vitest } from "vitest"; import { afterEach, test, vitest } from "vitest";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
import { import {
RoomEvent as MatrixRoomEvent, RoomEvent as MatrixRoomEvent,
MatrixEvent, MatrixEvent,
@@ -38,7 +37,7 @@ test("handles a hand raised reaction", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { raisedHands$ } = new ReactionsReader( const { raisedHands$ } = new ReactionsReader(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
); );
schedule("ab", { schedule("ab", {
a: () => {}, a: () => {},
@@ -86,7 +85,7 @@ test("handles a redaction", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { raisedHands$ } = new ReactionsReader( const { raisedHands$ } = new ReactionsReader(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
); );
schedule("abc", { schedule("abc", {
a: () => {}, a: () => {},
@@ -149,7 +148,7 @@ test("handles waiting for event decryption", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { raisedHands$ } = new ReactionsReader( const { raisedHands$ } = new ReactionsReader(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
); );
schedule("abc", { schedule("abc", {
a: () => {}, a: () => {},
@@ -218,7 +217,7 @@ test("hands rejecting events without a proper membership", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { raisedHands$ } = new ReactionsReader( const { raisedHands$ } = new ReactionsReader(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
); );
schedule("ab", { schedule("ab", {
a: () => {}, a: () => {},
@@ -262,9 +261,7 @@ test("handles a reaction", () => {
withTestScheduler(({ schedule, time, expectObservable }) => { withTestScheduler(({ schedule, time, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { reactions$ } = new ReactionsReader( const { reactions$ } = new ReactionsReader(rtcSession.asMockedSession());
rtcSession as unknown as MatrixRTCSession,
);
schedule(`abc`, { schedule(`abc`, {
a: () => {}, a: () => {},
b: () => { b: () => {
@@ -320,9 +317,7 @@ test("ignores bad reaction events", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { reactions$ } = new ReactionsReader( const { reactions$ } = new ReactionsReader(rtcSession.asMockedSession());
rtcSession as unknown as MatrixRTCSession,
);
schedule("ab", { schedule("ab", {
a: () => {}, a: () => {},
b: () => { b: () => {
@@ -444,9 +439,7 @@ test("that reactions cannot be spammed", () => {
withTestScheduler(({ schedule, expectObservable }) => { withTestScheduler(({ schedule, expectObservable }) => {
renderHook(() => { renderHook(() => {
const { reactions$ } = new ReactionsReader( const { reactions$ } = new ReactionsReader(rtcSession.asMockedSession());
rtcSession as unknown as MatrixRTCSession,
);
schedule("abcd", { schedule("abcd", {
a: () => {}, a: () => {},
b: () => { b: () => {

View File

@@ -117,7 +117,7 @@ function createGroupCallView(
widget: WidgetHelpers | null, widget: WidgetHelpers | null,
joined = true, joined = true,
): { ): {
rtcSession: MockRTCSession; rtcSession: MatrixRTCSession;
getByText: ReturnType<typeof render>["getByText"]; getByText: ReturnType<typeof render>["getByText"];
} { } {
const client = { const client = {
@@ -164,7 +164,7 @@ function createGroupCallView(
preload={false} preload={false}
skipLobby={false} skipLobby={false}
header={HeaderStyle.Standard} header={HeaderStyle.Standard}
rtcSession={rtcSession as unknown as MatrixRTCSession} rtcSession={rtcSession.asMockedSession()}
muteStates={muteState} muteStates={muteState}
widget={widget} widget={widget}
// TODO-MULTI-SFU: Make joined and setJoined work // TODO-MULTI-SFU: Make joined and setJoined work
@@ -178,7 +178,7 @@ function createGroupCallView(
); );
return { return {
getByText, getByText,
rtcSession, rtcSession: rtcSession.asMockedSession(),
}; };
} }

View File

@@ -15,7 +15,6 @@ import {
} from "vitest"; } from "vitest";
import { act, render, type RenderResult } from "@testing-library/react"; import { act, render, type RenderResult } from "@testing-library/react";
import { type MatrixClient, JoinRule, type RoomState } from "matrix-js-sdk"; import { type MatrixClient, JoinRule, type RoomState } from "matrix-js-sdk";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container"; import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container";
import { type LocalParticipant } from "livekit-client"; import { type LocalParticipant } from "livekit-client";
import { of } from "rxjs"; import { of } from "rxjs";
@@ -154,14 +153,14 @@ function createInCallView(): RenderResult & {
<MediaDevicesContext value={mockMediaDevices({})}> <MediaDevicesContext value={mockMediaDevices({})}>
<ReactionsSenderProvider <ReactionsSenderProvider
vm={vm} vm={vm}
rtcSession={rtcSession as unknown as MatrixRTCSession} rtcSession={rtcSession.asMockedSession()}
> >
<TooltipProvider> <TooltipProvider>
<RoomContext value={livekitRoom}> <RoomContext value={livekitRoom}>
<InCallView <InCallView
client={client} client={client}
header={HeaderStyle.Standard} header={HeaderStyle.Standard}
rtcSession={rtcSession as unknown as MatrixRTCSession} rtcSession={rtcSession.asMockedSession()}
muteStates={muteState} muteStates={muteState}
vm={vm} vm={vm}
matrixInfo={{ matrixInfo={{

View File

@@ -40,7 +40,6 @@ import * as ComponentsCore from "@livekit/components-core";
import { import {
Status, Status,
type CallMembership, type CallMembership,
type MatrixRTCSession,
type IRTCNotificationContent, type IRTCNotificationContent,
type ICallNotifyContent, type ICallNotifyContent,
MatrixRTCSessionEvent, MatrixRTCSessionEvent,
@@ -345,7 +344,7 @@ function withCallViewModel(
const reactions$ = new BehaviorSubject<Record<string, ReactionInfo>>({}); const reactions$ = new BehaviorSubject<Record<string, ReactionInfo>>({});
const vm = new CallViewModel( const vm = new CallViewModel(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
room, room,
mediaDevices, mediaDevices,
muteStates, muteStates,

View File

@@ -541,7 +541,9 @@ export class CallViewModel extends ViewModel {
const oldest = this.matrixRTCSession.getOldestMembership(); const oldest = this.matrixRTCSession.getOldestMembership();
if (oldest !== undefined) { if (oldest !== undefined) {
const selection = oldest.getTransport(oldest); const selection = oldest.getTransport(oldest);
if (isLivekitTransport(selection)) local = ready(selection); // TODO selection can be null if no transport is configured should we report an error?
if (selection && isLivekitTransport(selection))
local = ready(selection);
} }
} }
return { local, remote }; return { local, remote };
@@ -721,8 +723,8 @@ export class CallViewModel extends ViewModel {
), ),
); );
private readonly userId = this.matrixRoom.client.getUserId(); private readonly userId = this.matrixRoom.client.getUserId()!;
private readonly deviceId = this.matrixRoom.client.getDeviceId(); private readonly deviceId = this.matrixRoom.client.getDeviceId()!;
private readonly matrixConnected$ = this.scope.behavior( private readonly matrixConnected$ = this.scope.behavior(
// To consider ourselves connected to MatrixRTC, we check the following: // To consider ourselves connected to MatrixRTC, we check the following:
@@ -906,7 +908,11 @@ export class CallViewModel extends ViewModel {
], ],
(memberships, _displaynames) => { (memberships, _displaynames) => {
const displaynameMap = new Map<string, string>([ const displaynameMap = new Map<string, string>([
["local", this.matrixRoom.getMember(this.userId!)!.rawDisplayName], [
"local",
this.matrixRoom.getMember(this.userId)?.rawDisplayName ??
this.userId,
],
]); ]);
const room = this.matrixRoom; const room = this.matrixRoom;

View File

@@ -5,10 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details. Please see LICENSE in the repository root for full details.
*/ */
import { import { type CallMembership } from "matrix-js-sdk/lib/matrixrtc";
type CallMembership,
type MatrixRTCSession,
} from "matrix-js-sdk/lib/matrixrtc";
import { BehaviorSubject, of } from "rxjs"; import { BehaviorSubject, of } from "rxjs";
import { vitest } from "vitest"; import { vitest } from "vitest";
import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container"; import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container";
@@ -99,12 +96,12 @@ export function getBasicRTCSession(
initialRtcMemberships, initialRtcMemberships,
); );
const rtcSession = new MockRTCSession(matrixRoom).withMemberships( const fakeRtcSession = new MockRTCSession(matrixRoom).withMemberships(
rtcMemberships$, rtcMemberships$,
); );
return { return {
rtcSession, rtcSession: fakeRtcSession,
matrixRoom, matrixRoom,
rtcMemberships$, rtcMemberships$,
}; };
@@ -137,7 +134,7 @@ export function getBasicCallViewModelEnvironment(
// const remoteParticipants$ = of([aliceParticipant]); // const remoteParticipants$ = of([aliceParticipant]);
const vm = new CallViewModel( const vm = new CallViewModel(
rtcSession as unknown as MatrixRTCSession, rtcSession.asMockedSession(),
matrixRoom, matrixRoom,
mockMediaDevices({}), mockMediaDevices({}),
mockMuteStates(), mockMuteStates(),

View File

@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/ */
import { map, type Observable, of, type SchedulerLike } from "rxjs"; import { map, type Observable, of, type SchedulerLike } from "rxjs";
import { type RunHelpers, TestScheduler } from "rxjs/testing"; import { type RunHelpers, TestScheduler } from "rxjs/testing";
import { expect, vi, vitest } from "vitest"; import { expect, type MockedObject, vi, vitest } from "vitest";
import { import {
type RoomMember, type RoomMember,
type Room as MatrixRoom, type Room as MatrixRoom,
@@ -23,6 +23,7 @@ import {
type SessionMembershipData, type SessionMembershipData,
Status, Status,
type LivekitFocusSelection, type LivekitFocusSelection,
type MatrixRTCSession,
} from "matrix-js-sdk/lib/matrixrtc"; } from "matrix-js-sdk/lib/matrixrtc";
import { type MembershipManagerEventHandlerMap } from "matrix-js-sdk/lib/matrixrtc/IMembershipManager"; import { type MembershipManagerEventHandlerMap } from "matrix-js-sdk/lib/matrixrtc/IMembershipManager";
import { import {
@@ -193,7 +194,9 @@ export function mockRtcMembership(
sender: typeof user === "string" ? user : user.userId, sender: typeof user === "string" ? user : user.userId,
event_id: `$-ev-${randomUUID()}:example.org`, event_id: `$-ev-${randomUUID()}:example.org`,
}); });
return new CallMembership(event, data); const cms = new CallMembership(event, data);
vi.mocked(cms).getTransport = vi.fn().mockReturnValue(fociPreferred[0]);
return cms;
} }
// Maybe it'd be good to move this to matrix-js-sdk? Our testing needs are // Maybe it'd be good to move this to matrix-js-sdk? Our testing needs are
@@ -209,6 +212,7 @@ export function mockMatrixRoomMember(
getMxcAvatarUrl(): string | undefined { getMxcAvatarUrl(): string | undefined {
return undefined; return undefined;
}, },
rawDisplayName: rtcMembership.sender,
...member, ...member,
} as RoomMember; } as RoomMember;
} }
@@ -335,6 +339,22 @@ export class MockRTCSession extends TypedEventEmitter<
RoomAndToDeviceEventsHandlerMap & RoomAndToDeviceEventsHandlerMap &
MembershipManagerEventHandlerMap MembershipManagerEventHandlerMap
> { > {
public asMockedSession(): MockedObject<MatrixRTCSession> {
const session = this as unknown as MockedObject<MatrixRTCSession>;
vi.mocked(session).reemitEncryptionKeys = vi
.fn<() => void>()
.mockReturnValue(undefined);
vi.mocked(session).resolveActiveFocus = vi
.fn<(member?: CallMembership) => Transport | undefined>()
.mockReturnValue(undefined);
vi.mocked(session).getOldestMembership = vi
.fn<() => CallMembership | undefined>()
.mockReturnValue(this.memberships[0]);
return session;
}
public readonly statistics = { public readonly statistics = {
counters: {}, counters: {},
}; };