From 3fda0299a5e92882a559a487fbff44f510ffc838 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 16 Aug 2023 09:29:34 +0100 Subject: [PATCH] Move `mediaDevices` mock out of `setupManualMocks` (#11413) * Move `mediaDevices` mock out of `setupManualMocks` This doesn't work well in test suites with multiple tests, because the `mockReturnValue` is reset for subsequent tests. In any case, having it mocked out automagically is *magical*. Let's make it opt-in. * clarify ts-ignore --- test/audio/VoiceRecording-test.ts | 2 ++ test/components/structures/PipContainer-test.tsx | 3 +++ test/components/views/messages/CallEvent-test.tsx | 8 +++++--- test/components/views/rooms/RoomTile-test.tsx | 2 ++ test/components/views/voip/CallView-test.tsx | 5 +++-- test/setup/setupManualMocks.ts | 8 -------- test/stores/room-list/algorithms/Algorithm-test.ts | 9 ++++++++- test/test-utils/utilities.ts | 9 +++++++++ test/utils/media/requestMediaPermissions-test.tsx | 3 ++- 9 files changed, 34 insertions(+), 15 deletions(-) diff --git a/test/audio/VoiceRecording-test.ts b/test/audio/VoiceRecording-test.ts index ba0ff621b2..8c0f8fb59b 100644 --- a/test/audio/VoiceRecording-test.ts +++ b/test/audio/VoiceRecording-test.ts @@ -21,6 +21,7 @@ import Recorder from "opus-recorder/dist/recorder.min.js"; import { VoiceRecording, voiceRecorderOptions, highQualityRecorderOptions } from "../../src/audio/VoiceRecording"; import { createAudioContext } from "../..//src/audio/compat"; import MediaDeviceHandler from "../../src/MediaDeviceHandler"; +import { useMockMediaDevices } from "../test-utils"; jest.mock("opus-recorder/dist/recorder.min.js"); const RecorderMock = mocked(Recorder); @@ -56,6 +57,7 @@ describe("VoiceRecording", () => { }; beforeEach(() => { + useMockMediaDevices(); recording = new VoiceRecording(); // @ts-ignore recording.observable = { diff --git a/test/components/structures/PipContainer-test.tsx b/test/components/structures/PipContainer-test.tsx index 765c7a1dff..4a15abfc30 100644 --- a/test/components/structures/PipContainer-test.tsx +++ b/test/components/structures/PipContainer-test.tsx @@ -35,6 +35,7 @@ import { mkRoomCreateEvent, mockPlatformPeg, flushPromises, + useMockMediaDevices, } from "../../test-utils"; import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; import { CallStore } from "../../../src/stores/CallStore"; @@ -84,6 +85,8 @@ describe("PipContainer", () => { }; beforeEach(async () => { + useMockMediaDevices(); + user = userEvent.setup(); stubClient(); diff --git a/test/components/views/messages/CallEvent-test.tsx b/test/components/views/messages/CallEvent-test.tsx index 8f5c99a2b0..39630e71a9 100644 --- a/test/components/views/messages/CallEvent-test.tsx +++ b/test/components/views/messages/CallEvent-test.tsx @@ -29,6 +29,7 @@ import { setupAsyncStoreWithClient, resetAsyncStoreWithClient, wrapInMatrixClientContext, + useMockMediaDevices, } from "../../../test-utils"; import defaultDispatcher from "../../../../src/dispatcher/dispatcher"; import { Action } from "../../../../src/dispatcher/actions"; @@ -41,9 +42,6 @@ import { ConnectionState } from "../../../../src/models/Call"; const CallEvent = wrapInMatrixClientContext(UnwrappedCallEvent); describe("CallEvent", () => { - useMockedCalls(); - jest.spyOn(HTMLMediaElement.prototype, "play").mockImplementation(async () => {}); - let client: Mocked; let room: Room; let alice: RoomMember; @@ -55,6 +53,10 @@ describe("CallEvent", () => { jest.useFakeTimers(); jest.setSystemTime(0); + useMockMediaDevices(); + useMockedCalls(); + jest.spyOn(HTMLMediaElement.prototype, "play").mockImplementation(async () => {}); + stubClient(); client = mocked(MatrixClientPeg.safeGet()); client.getUserId.mockReturnValue("@alice:example.org"); diff --git a/test/components/views/rooms/RoomTile-test.tsx b/test/components/views/rooms/RoomTile-test.tsx index 88fb465ac7..9be804c754 100644 --- a/test/components/views/rooms/RoomTile-test.tsx +++ b/test/components/views/rooms/RoomTile-test.tsx @@ -38,6 +38,7 @@ import { filterConsole, flushPromises, mkMessage, + useMockMediaDevices, } from "../../../test-utils"; import { CallStore } from "../../../../src/stores/CallStore"; import RoomTile from "../../../../src/components/views/rooms/RoomTile"; @@ -134,6 +135,7 @@ describe("RoomTile", () => { }; beforeEach(() => { + useMockMediaDevices(); sdkContext = new TestSdkContext(); client = mocked(stubClient()); diff --git a/test/components/views/voip/CallView-test.tsx b/test/components/views/voip/CallView-test.tsx index d7ee94ed03..a0615533f3 100644 --- a/test/components/views/voip/CallView-test.tsx +++ b/test/components/views/voip/CallView-test.tsx @@ -30,6 +30,7 @@ import { useMockedCalls, MockedCall, setupAsyncStoreWithClient, + useMockMediaDevices, } from "../../../test-utils"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import { CallView as _CallView } from "../../../../src/components/views/voip/CallView"; @@ -41,7 +42,7 @@ import MediaDeviceHandler from "../../../../src/MediaDeviceHandler"; const CallView = wrapInMatrixClientContext(_CallView); -describe("CallLobby", () => { +describe("CallView", () => { useMockedCalls(); jest.spyOn(HTMLMediaElement.prototype, "play").mockImplementation(async () => {}); @@ -50,7 +51,7 @@ describe("CallLobby", () => { let alice: RoomMember; beforeEach(() => { - mocked(navigator.mediaDevices.enumerateDevices).mockResolvedValue([]); + useMockMediaDevices(); stubClient(); client = mocked(MatrixClientPeg.safeGet()); diff --git a/test/setup/setupManualMocks.ts b/test/setup/setupManualMocks.ts index 2d4d453256..540d699f58 100644 --- a/test/setup/setupManualMocks.ts +++ b/test/setup/setupManualMocks.ts @@ -91,11 +91,3 @@ window.fetch = fetchMock.sandbox(); // @ts-ignore window.Response = Response; - -// set up mediaDevices mock -Object.defineProperty(navigator, "mediaDevices", { - value: { - enumerateDevices: jest.fn().mockResolvedValue([]), - getUserMedia: jest.fn(), - }, -}); diff --git a/test/stores/room-list/algorithms/Algorithm-test.ts b/test/stores/room-list/algorithms/Algorithm-test.ts index d7c5d2614c..a47b364ff6 100644 --- a/test/stores/room-list/algorithms/Algorithm-test.ts +++ b/test/stores/room-list/algorithms/Algorithm-test.ts @@ -20,7 +20,13 @@ import { Widget } from "matrix-widget-api"; import type { MatrixClient } from "matrix-js-sdk/src/matrix"; import type { ClientWidgetApi } from "matrix-widget-api"; -import { stubClient, setupAsyncStoreWithClient, useMockedCalls, MockedCall } from "../../../test-utils"; +import { + stubClient, + setupAsyncStoreWithClient, + useMockedCalls, + MockedCall, + useMockMediaDevices, +} from "../../../test-utils"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import DMRoomMap from "../../../../src/utils/DMRoomMap"; import { DefaultTagID } from "../../../../src/stores/room-list/models"; @@ -37,6 +43,7 @@ describe("Algorithm", () => { let algorithm: Algorithm; beforeEach(() => { + useMockMediaDevices(); stubClient(); client = mocked(MatrixClientPeg.safeGet()); DMRoomMap.makeShared(client); diff --git a/test/test-utils/utilities.ts b/test/test-utils/utilities.ts index 514a9091f1..28cc9de417 100644 --- a/test/test-utils/utilities.ts +++ b/test/test-utils/utilities.ts @@ -225,3 +225,12 @@ export const clearAllModals = async (): Promise => { } } }; + +/** Install a stub object at `navigator.mediaDevices` */ +export function useMockMediaDevices(): void { + // @ts-ignore assignment of a thing that isn't a `MediaDevices` to read-only property + navigator["mediaDevices"] = { + enumerateDevices: jest.fn().mockResolvedValue([]), + getUserMedia: jest.fn(), + }; +} diff --git a/test/utils/media/requestMediaPermissions-test.tsx b/test/utils/media/requestMediaPermissions-test.tsx index 633f6ab9fa..3c9385c413 100644 --- a/test/utils/media/requestMediaPermissions-test.tsx +++ b/test/utils/media/requestMediaPermissions-test.tsx @@ -19,7 +19,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import { screen } from "@testing-library/react"; import { requestMediaPermissions } from "../../../src/utils/media/requestMediaPermissions"; -import { flushPromises } from "../../test-utils"; +import { flushPromises, useMockMediaDevices } from "../../test-utils"; describe("requestMediaPermissions", () => { let error: Error; @@ -34,6 +34,7 @@ describe("requestMediaPermissions", () => { }; beforeEach(() => { + useMockMediaDevices(); error = new Error(); jest.spyOn(logger, "log"); });