Simplify some test helpers that no longer need continuations

This commit is contained in:
Robin
2025-10-17 12:34:06 -04:00
parent d5efba285b
commit 13894aaf3a
4 changed files with 175 additions and 195 deletions

View File

@@ -17,8 +17,8 @@ import {
mockLocalParticipant,
mockMediaDevices,
mockRtcMembership,
withLocalMedia,
withRemoteMedia,
createLocalMedia,
createRemoteMedia,
withTestScheduler,
} from "../utils/test";
import { getValue } from "../utils/observable";
@@ -42,9 +42,9 @@ vi.mock("../Platform", () => ({
const rtcMembership = mockRtcMembership("@alice:example.org", "AAAA");
test("control a participant's volume", async () => {
test("control a participant's volume", () => {
const setVolumeSpy = vi.fn();
await withRemoteMedia(rtcMembership, {}, { setVolume: setVolumeSpy }, (vm) =>
const vm = createRemoteMedia(rtcMembership, {}, { setVolume: setVolumeSpy });
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-ab---c---d|", {
a() {
@@ -84,12 +84,11 @@ test("control a participant's volume", async () => {
f: 0,
g: 0.8,
});
}),
);
});
});
test("toggle fit/contain for a participant's video", async () => {
await withRemoteMedia(rtcMembership, {}, {}, (vm) =>
test("toggle fit/contain for a participant's video", () => {
const vm = createRemoteMedia(rtcMembership, {}, {});
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-ab|", {
a: () => vm.toggleFitContain(),
@@ -100,34 +99,32 @@ test("toggle fit/contain for a participant's video", async () => {
b: false,
c: true,
});
}),
);
});
});
test("local media remembers whether it should always be shown", async () => {
await withLocalMedia(
test("local media remembers whether it should always be shown", () => {
const vm1 = createLocalMedia(
rtcMembership,
{},
mockLocalParticipant({}),
mockMediaDevices({}),
(vm) =>
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-a|", { a: () => vm.setAlwaysShow(false) });
expectObservable(vm.alwaysShow$).toBe("ab", { a: true, b: false });
}),
);
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-a|", { a: () => vm1.setAlwaysShow(false) });
expectObservable(vm1.alwaysShow$).toBe("ab", { a: true, b: false });
});
// Next local media should start out *not* always shown
await withLocalMedia(
const vm2 = createLocalMedia(
rtcMembership,
{},
mockLocalParticipant({}),
mockMediaDevices({}),
(vm) =>
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-a|", { a: () => vm.setAlwaysShow(true) });
expectObservable(vm.alwaysShow$).toBe("ab", { a: false, b: true });
}),
);
withTestScheduler(({ expectObservable, schedule }) => {
schedule("-a|", { a: () => vm2.setAlwaysShow(true) });
expectObservable(vm2.alwaysShow$).toBe("ab", { a: false, b: true });
});
});
test("switch cameras", async () => {
@@ -164,7 +161,7 @@ test("switch cameras", async () => {
const selectVideoInput = vi.fn();
await withLocalMedia(
const vm = createLocalMedia(
rtcMembership,
{},
mockLocalParticipant({
@@ -179,7 +176,8 @@ test("switch cameras", async () => {
select: selectVideoInput,
},
}),
async (vm) => {
);
// Switch to back camera
getValue(vm.switchCamera$)!();
expect(restartTrack).toHaveBeenCalledExactlyOnceWith({
@@ -200,6 +198,4 @@ test("switch cameras", async () => {
expect(selectVideoInput).toHaveBeenLastCalledWith("front camera");
});
expect(deviceId).toBe("front camera");
},
);
});

View File

@@ -12,7 +12,7 @@ import { axe } from "vitest-axe";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
import { GridTile } from "./GridTile";
import { mockRtcMembership, withRemoteMedia } from "../utils/test";
import { mockRtcMembership, createRemoteMedia } from "../utils/test";
import { GridTileViewModel } from "../state/TileViewModel";
import { ReactionsSenderProvider } from "../reactions/useReactionsSender";
import type { CallViewModel } from "../state/CallViewModel";
@@ -25,7 +25,7 @@ global.IntersectionObserver = class MockIntersectionObserver {
} as unknown as typeof IntersectionObserver;
test("GridTile is accessible", async () => {
await withRemoteMedia(
const vm = createRemoteMedia(
mockRtcMembership("@alice:example.org", "AAAA"),
{
rawDisplayName: "Alice",
@@ -36,7 +36,8 @@ test("GridTile is accessible", async () => {
getTrackPublication: () =>
({}) as Partial<RemoteTrackPublication> as RemoteTrackPublication,
},
async (vm) => {
);
const fakeRtcSession = {
on: () => {},
off: () => {},
@@ -71,6 +72,4 @@ test("GridTile is accessible", async () => {
expect(await axe(container)).toHaveNoViolations();
// Name should be visible
screen.getByText("Alice");
},
);
});

View File

@@ -15,8 +15,8 @@ import {
mockLocalParticipant,
mockMediaDevices,
mockRtcMembership,
withLocalMedia,
withRemoteMedia,
createLocalMedia,
createRemoteMedia,
} from "../utils/test";
import { SpotlightTileViewModel } from "../state/TileViewModel";
import { constant } from "../state/Behavior";
@@ -27,15 +27,16 @@ global.IntersectionObserver = class MockIntersectionObserver {
} as unknown as typeof IntersectionObserver;
test("SpotlightTile is accessible", async () => {
await withRemoteMedia(
const vm1 = createRemoteMedia(
mockRtcMembership("@alice:example.org", "AAAA"),
{
rawDisplayName: "Alice",
getMxcAvatarUrl: () => "mxc://adfsg",
},
{},
async (vm1) => {
await withLocalMedia(
);
const vm2 = createLocalMedia(
mockRtcMembership("@bob:example.org", "BBBB"),
{
rawDisplayName: "Bob",
@@ -43,17 +44,13 @@ test("SpotlightTile is accessible", async () => {
},
mockLocalParticipant({}),
mockMediaDevices({}),
async (vm2) => {
);
const user = userEvent.setup();
const toggleExpanded = vi.fn();
const { container } = render(
<SpotlightTile
vm={
new SpotlightTileViewModel(
constant([vm1, vm2]),
constant(false),
)
}
vm={new SpotlightTileViewModel(constant([vm1, vm2]), constant(false))}
targetWidth={300}
targetHeight={200}
expanded={false}
@@ -68,9 +65,7 @@ test("SpotlightTile is accessible", async () => {
// first page
screen.getByText("Alice");
const aliceAvatar = screen.getByRole("img");
expect(screen.queryByRole("button", { name: "common.back" })).toBe(
null,
);
expect(screen.queryByRole("button", { name: "common.back" })).toBe(null);
// Bob should be out of the spotlight, and therefore invisible
expect(isInaccessible(screen.getByText("Bob"))).toBe(true);
// Now navigate to Bob
@@ -81,8 +76,4 @@ test("SpotlightTile is accessible", async () => {
// Can toggle whether the tile is expanded
await user.click(screen.getByRole("button", { name: "Expand" }));
expect(toggleExpanded).toHaveBeenCalled();
},
);
},
);
});

View File

@@ -268,14 +268,13 @@ export function mockLocalParticipant(
} as Partial<LocalParticipant> as LocalParticipant;
}
export async function withLocalMedia(
export function createLocalMedia(
localRtcMember: CallMembership,
roomMember: Partial<RoomMember>,
localParticipant: LocalParticipant,
mediaDevices: MediaDevices,
continuation: (vm: LocalUserMediaViewModel) => void | Promise<void>,
): Promise<void> {
const vm = new LocalUserMediaViewModel(
): LocalUserMediaViewModel {
return new LocalUserMediaViewModel(
testScope(),
"local",
mockMatrixRoomMember(localRtcMember, roomMember),
@@ -290,8 +289,6 @@ export async function withLocalMedia(
constant(null),
constant(null),
);
// TODO: Simplify to just return the view model
await continuation(vm);
}
export function mockRemoteParticipant(
@@ -307,14 +304,13 @@ export function mockRemoteParticipant(
} as RemoteParticipant;
}
export async function withRemoteMedia(
export function createRemoteMedia(
localRtcMember: CallMembership,
roomMember: Partial<RoomMember>,
participant: Partial<RemoteParticipant>,
continuation: (vm: RemoteUserMediaViewModel) => void | Promise<void>,
): Promise<void> {
): RemoteUserMediaViewModel {
const remoteParticipant = mockRemoteParticipant(participant);
const vm = new RemoteUserMediaViewModel(
return new RemoteUserMediaViewModel(
testScope(),
"remote",
mockMatrixRoomMember(localRtcMember, roomMember),
@@ -329,8 +325,6 @@ export async function withRemoteMedia(
constant(null),
constant(null),
);
// TODO: Simplify to just return the view model
await continuation(vm);
}
export function mockConfig(config: Partial<ResolvedConfigOptions> = {}): void {