diff --git a/src/state/MediaViewModel.test.ts b/src/state/MediaViewModel.test.ts index f65b7775..c36f9124 100644 --- a/src/state/MediaViewModel.test.ts +++ b/src/state/MediaViewModel.test.ts @@ -14,52 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { RoomMember } from "matrix-js-sdk/src/matrix"; import { expect, test, vi } from "vitest"; -import { LocalParticipant, RemoteParticipant } from "livekit-client"; import { - LocalUserMediaViewModel, - RemoteUserMediaViewModel, -} from "./MediaViewModel"; -import { withTestScheduler } from "../utils/test"; + withLocalMedia, + withRemoteMedia, + withTestScheduler, +} from "../utils/test"; -function withLocal(continuation: (vm: LocalUserMediaViewModel) => void): void { - const member = {} as unknown as RoomMember; - const vm = new LocalUserMediaViewModel( - "a", - member, - {} as unknown as LocalParticipant, - true, - ); - try { - continuation(vm); - } finally { - vm.destroy(); - } -} - -function withRemote( - participant: Partial, - continuation: (vm: RemoteUserMediaViewModel) => void, -): void { - const member = {} as unknown as RoomMember; - const vm = new RemoteUserMediaViewModel( - "a", - member, - { setVolume() {}, ...participant } as RemoteParticipant, - true, - ); - try { - continuation(vm); - } finally { - vm.destroy(); - } -} - -test("set a participant's volume", () => { +test("set a participant's volume", async () => { const setVolumeSpy = vi.fn(); - withRemote({ setVolume: setVolumeSpy }, (vm) => + await withRemoteMedia({}, { setVolume: setVolumeSpy }, async (vm) => withTestScheduler(({ expectObservable, schedule }) => { schedule("-a|", { a() { @@ -72,9 +37,9 @@ test("set a participant's volume", () => { ); }); -test("mute and unmute a participant", () => { +test("mute and unmute a participant", async () => { const setVolumeSpy = vi.fn(); - withRemote({ setVolume: setVolumeSpy }, (vm) => + await withRemoteMedia({}, { setVolume: setVolumeSpy }, async (vm) => withTestScheduler(({ expectObservable, schedule }) => { schedule("-abc|", { a() { @@ -99,8 +64,8 @@ test("mute and unmute a participant", () => { ); }); -test("toggle fit/contain for a participant's video", () => { - withRemote({}, (vm) => +test("toggle fit/contain for a participant's video", async () => { + await withRemoteMedia({}, {}, async (vm) => withTestScheduler(({ expectObservable, schedule }) => { schedule("-ab|", { a: () => vm.toggleFitContain(), @@ -115,15 +80,15 @@ test("toggle fit/contain for a participant's video", () => { ); }); -test("local media remembers whether it should always be shown", () => { - withLocal((vm) => +test("local media remembers whether it should always be shown", async () => { + await withLocalMedia(async (vm) => withTestScheduler(({ expectObservable, schedule }) => { schedule("-a|", { a: () => vm.setAlwaysShow(false) }); expectObservable(vm.alwaysShow).toBe("ab", { a: true, b: false }); }), ); // Next local media should start out *not* always shown - withLocal((vm) => + await withLocalMedia(async (vm) => withTestScheduler(({ expectObservable, schedule }) => { schedule("-a|", { a: () => vm.setAlwaysShow(true) }); expectObservable(vm.alwaysShow).toBe("ab", { a: false, b: true }); diff --git a/src/tile/GridTile.test.tsx b/src/tile/GridTile.test.tsx new file mode 100644 index 00000000..0e181dbf --- /dev/null +++ b/src/tile/GridTile.test.tsx @@ -0,0 +1,52 @@ +/* +Copyright 2024 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { RemoteTrackPublication } from "livekit-client"; +import { test, expect } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { axe } from "vitest-axe"; + +import { GridTile } from "./GridTile"; +import { withRemoteMedia } from "../utils/test"; + +test("GridTile is accessible", async () => { + await withRemoteMedia( + { + rawDisplayName: "Alice", + getMxcAvatarUrl: () => "mxc://adfsg", + }, + { + setVolume() {}, + getTrackPublication: () => + ({}) as Partial as RemoteTrackPublication, + }, + async (vm) => { + const { container } = render( + {}} + targetWidth={300} + targetHeight={200} + showVideo + showSpeakingIndicators + />, + ); + expect(await axe(container)).toHaveNoViolations(); + // Name should be visible + screen.getByText("Alice"); + }, + ); +}); diff --git a/src/utils/test.ts b/src/utils/test.ts index 43329be0..7a640215 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -16,6 +16,13 @@ limitations under the License. import { map } from "rxjs"; import { RunHelpers, TestScheduler } from "rxjs/testing"; import { expect, vi } from "vitest"; +import { RoomMember } from "matrix-js-sdk/src/matrix"; +import { LocalParticipant, RemoteParticipant } from "livekit-client"; + +import { + LocalUserMediaViewModel, + RemoteUserMediaViewModel, +} from "../state/MediaViewModel"; export function withFakeTimers(continuation: () => void): void { vi.useFakeTimers(); @@ -58,3 +65,67 @@ export function withTestScheduler( }), ); } + +export async function withLocalMedia( + continuation: (vm: LocalUserMediaViewModel) => Promise, +): Promise { + const member = {} as unknown as RoomMember; + const vm = new LocalUserMediaViewModel( + "a", + member, + {} as Partial as LocalParticipant, + true, + ); + try { + await continuation(vm); + } finally { + vm.destroy(); + } +} + +export async function withRemoteMedia( + member: Partial, + participant: Partial, + continuation: (vm: RemoteUserMediaViewModel) => Promise, +): Promise { + const vm = new RemoteUserMediaViewModel( + "a", + { + on() { + return this; + }, + off() { + return this; + }, + addListener() { + return this; + }, + removeListener() { + return this; + }, + ...member, + } as RoomMember, + { + setVolume() {}, + on() { + return this; + }, + off() { + return this; + }, + addListener() { + return this; + }, + removeListener() { + return this; + }, + ...participant, + } as RemoteParticipant, + true, + ); + try { + await continuation(vm); + } finally { + vm.destroy(); + } +}