From 1d8204b0f333d7fd3f0505eafbb4abb6daa9078c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 8 Jul 2026 10:40:37 +0100 Subject: [PATCH 1/2] Move more tests from Jest to Vitest --- .../actions/RoomListActions.test.ts} | 30 ++++---- .../rooms/MessageComposerUrlPreview.test.tsx | 21 ++---- .../contexts/SDKContextClass.test.ts} | 10 ++- .../events/EventTileFactory.test.ts} | 73 +++++++++---------- .../forward/getForwardableEvent.test.ts} | 11 ++- .../getShareableLocationEvent.test.ts} | 11 ++- .../room/useRoomThreadNotifications.test.tsx} | 15 ++-- .../hooks/room/useTopic.test.tsx} | 11 ++- .../hooks/useMediaVisible.test.ts} | 25 ++++--- .../hooks/useNotificationSettings.test.ts} | 36 ++++----- .../hooks/useProfileInfo.test.ts} | 11 ++- .../hooks/usePublicRoomDirectory.test.ts} | 11 ++- .../hooks/useRoomCall.test.ts} | 55 +++++++------- .../hooks/useRoomMembers.test.ts} | 11 ++- .../hooks/useUnreadNotifications.test.ts} | 13 ++-- .../hooks/useUserDirectory.test.ts} | 11 ++- .../hooks/useUserStatus.test.ts} | 38 +++++----- apps/web/test/test-utils/index.ts | 1 + .../test/test-utils/vitest-matrix-react.tsx | 16 ++++ apps/web/test/test-utils/wrappers.tsx | 27 +++++++ apps/web/vitest.config.ts | 2 +- 21 files changed, 253 insertions(+), 186 deletions(-) rename apps/web/{test/unit-tests/actions/RoomListActions-test.ts => src/actions/RoomListActions.test.ts} (89%) rename apps/web/{test/unit-tests/contexts/SdkContext-test.ts => src/contexts/SDKContextClass.test.ts} (85%) rename apps/web/{test/unit-tests/events/EventTileFactory-test.ts => src/events/EventTileFactory.test.ts} (85%) rename apps/web/{test/unit-tests/events/forward/getForwardableEvent-test.ts => src/events/forward/getForwardableEvent.test.ts} (92%) rename apps/web/{test/unit-tests/events/location/getShareableLocationEvent-test.ts => src/events/location/getShareableLocationEvent.test.ts} (92%) rename apps/web/{test/unit-tests/hooks/room/useRoomThreadNotifications-test.tsx => src/hooks/room/useRoomThreadNotifications.test.tsx} (82%) rename apps/web/{test/unit-tests/useTopic-test.tsx => src/hooks/room/useTopic.test.tsx} (84%) rename apps/web/{test/unit-tests/hooks/useMediaVisible-test.tsx => src/hooks/useMediaVisible.test.ts} (83%) rename apps/web/{test/unit-tests/hooks/useNotificationSettings-test.tsx => src/hooks/useNotificationSettings.test.ts} (83%) rename apps/web/{test/unit-tests/hooks/useProfileInfo-test.tsx => src/hooks/useProfileInfo.test.ts} (90%) rename apps/web/{test/unit-tests/hooks/usePublicRoomDirectory-test.tsx => src/hooks/usePublicRoomDirectory.test.ts} (89%) rename apps/web/{test/unit-tests/hooks/useRoomCall-test.tsx => src/hooks/useRoomCall.test.ts} (74%) rename apps/web/{test/unit-tests/hooks/useRoomMembers-test.tsx => src/hooks/useRoomMembers.test.ts} (92%) rename apps/web/{test/unit-tests/hooks/useUnreadNotifications-test.ts => src/hooks/useUnreadNotifications.test.ts} (88%) rename apps/web/{test/unit-tests/hooks/useUserDirectory-test.tsx => src/hooks/useUserDirectory.test.ts} (88%) rename apps/web/{test/unit-tests/hooks/useUserStatus-test.tsx => src/hooks/useUserStatus.test.ts} (83%) create mode 100644 apps/web/test/test-utils/vitest-matrix-react.tsx diff --git a/apps/web/test/unit-tests/actions/RoomListActions-test.ts b/apps/web/src/actions/RoomListActions.test.ts similarity index 89% rename from apps/web/test/unit-tests/actions/RoomListActions-test.ts rename to apps/web/src/actions/RoomListActions.test.ts index ecdf6f676d3..6d47737b8e3 100644 --- a/apps/web/test/unit-tests/actions/RoomListActions-test.ts +++ b/apps/web/src/actions/RoomListActions.test.ts @@ -5,33 +5,35 @@ * Please see LICENSE files in the repository root for full details. */ +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; -import { mocked } from "jest-mock"; +import { createTestClient, flushPromises, mkRoom } from "test-utils"; -import RoomListActions from "../../../src/actions/RoomListActions"; -import { DefaultTagID } from "../../../src/stores/room-list-v3/skip-list/tag"; -import Modal from "../../../src/Modal"; -import * as Rooms from "../../../src/Rooms"; -import { createTestClient, flushPromises, mkRoom } from "../../test-utils"; +import RoomListActions from "./RoomListActions"; +import { DefaultTagID } from "../stores/room-list-v3/skip-list/tag"; +import Modal from "../Modal"; +import * as Rooms from "../Rooms"; -jest.mock("../../../src/Modal"); -jest.mock("../../../src/Rooms"); +vi.mock("../Modal"); +vi.mock("../Rooms"); describe("RoomListActions", () => { const ROOM_ID = "!room:example.org"; let client: MatrixClient; let room: Room; - const dispatch = jest.fn(); + const dispatch = vi.fn(); beforeEach(() => { client = createTestClient(); room = mkRoom(client, ROOM_ID); - mocked(Rooms.guessAndSetDMRoom).mockResolvedValue(undefined); + vi.mocked(Rooms.guessAndSetDMRoom).mockResolvedValue(undefined); }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("tagRoom", () => { @@ -81,7 +83,7 @@ describe("RoomListActions", () => { it("opens an ErrorDialog and swallows the error if guessAndSetDMRoom rejects", async () => { const error = new Error("DM tag error"); - mocked(Rooms.guessAndSetDMRoom).mockRejectedValue(error); + vi.mocked(Rooms.guessAndSetDMRoom).mockRejectedValue(error); await invokeTagRoom(undefined, DefaultTagID.DM); @@ -140,7 +142,7 @@ describe("RoomListActions", () => { it("shows an ErrorDialog but still dispatches success when deleteRoomTag fails", async () => { const error = new Error("delete failed"); - jest.spyOn(client, "deleteRoomTag").mockRejectedValue(error); + vi.spyOn(client, "deleteRoomTag").mockRejectedValue(error); await invokeTagRoom(DefaultTagID.Favourite, DefaultTagID.LowPriority); @@ -156,7 +158,7 @@ describe("RoomListActions", () => { it("shows an ErrorDialog and dispatches failure when setRoomTag fails", async () => { const error = new Error("set failed"); - jest.spyOn(client, "setRoomTag").mockRejectedValue(error); + vi.spyOn(client, "setRoomTag").mockRejectedValue(error); await invokeTagRoom(DefaultTagID.Favourite, DefaultTagID.LowPriority); diff --git a/apps/web/src/components/views/rooms/MessageComposerUrlPreview.test.tsx b/apps/web/src/components/views/rooms/MessageComposerUrlPreview.test.tsx index d720f80be98..2795aa5770b 100644 --- a/apps/web/src/components/views/rooms/MessageComposerUrlPreview.test.tsx +++ b/apps/web/src/components/views/rooms/MessageComposerUrlPreview.test.tsx @@ -104,21 +104,16 @@ describe("MessageComposerUrlPreview", () => { (text) => text === "show-fake-preview", () => Fake preview, ); - const { container, getByText, rerender } = wrapComponent( + const { container, getByText, queryByText, rerender } = wrapComponent( , ); - await waitFor( - () => { - expect(getByText("Fake preview")).toBeDefined(); - }, - { timeout: DEBOUNCE_REQUEST_TIMEOUT_MS }, - ); + await waitFor(() => { + expect(getByText("Fake preview")).toBeDefined(); + }); rerender(); - await waitFor( - () => { - expect(container).toMatchInlineSnapshot(`
`); - }, - { timeout: DEBOUNCE_REQUEST_TIMEOUT_MS }, - ); + await waitFor(() => { + expect(queryByText("Fake preview")).toBeNull(); + }); + expect(container).toMatchInlineSnapshot(`
`); }); }); diff --git a/apps/web/test/unit-tests/contexts/SdkContext-test.ts b/apps/web/src/contexts/SDKContextClass.test.ts similarity index 85% rename from apps/web/test/unit-tests/contexts/SdkContext-test.ts rename to apps/web/src/contexts/SDKContextClass.test.ts index 50cb6f0759d..60cdb10295c 100644 --- a/apps/web/test/unit-tests/contexts/SdkContext-test.ts +++ b/apps/web/src/contexts/SDKContextClass.test.ts @@ -6,12 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// @vitest-environment happy-dom + +import { describe, it, expect, beforeAll, beforeEach } from "vitest"; import { type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { createTestClient, TestSDKContext } from "test-utils"; -import { SDKContextClass } from "../../../src/contexts/SDKContextClass"; -import { UserProfilesStore } from "../../../src/stores/UserProfilesStore"; -import { createTestClient } from "../../test-utils"; -import { TestSDKContext } from "../TestSDKContext.ts"; +import { SDKContextClass } from "./SDKContextClass"; +import { UserProfilesStore } from "../stores/UserProfilesStore"; describe("SDKContextClass", () => { let sdkContext: TestSDKContext; diff --git a/apps/web/test/unit-tests/events/EventTileFactory-test.ts b/apps/web/src/events/EventTileFactory.test.ts similarity index 85% rename from apps/web/test/unit-tests/events/EventTileFactory-test.ts rename to apps/web/src/events/EventTileFactory.test.ts index b8ea0af5e49..cc50bc43b2b 100644 --- a/apps/web/test/unit-tests/events/EventTileFactory-test.ts +++ b/apps/web/src/events/EventTileFactory.test.ts @@ -6,10 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import React from "react"; -import { render, screen } from "jest-matrix-react"; -import { mocked } from "jest-mock"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeAll, beforeEach, afterEach } from "vitest"; +import { render } from "test-utils-rtl"; import { EventType, type MatrixClient, MatrixEvent, MsgType, Room, type RoomMember } from "matrix-js-sdk/src/matrix"; +import { createTestClient, mkEvent, withClientContextRenderOptions } from "test-utils"; import { JSONEventFactory, @@ -17,14 +19,12 @@ import { pickFactory, renderTile, RoomCreateEventFactory, -} from "../../../src/events/EventTileFactory"; -import SettingsStore from "../../../src/settings/SettingsStore"; -import { createTestClient, mkEvent } from "../../test-utils"; -import { TimelineRenderingType } from "../../../src/contexts/RoomContext"; -import { ModuleApi } from "../../../src/modules/Api"; -import MatrixClientContext from "../../../src/contexts/MatrixClientContext"; -import DMRoomMap from "../../../src/utils/DMRoomMap"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; +} from "./EventTileFactory"; +import SettingsStore from "../settings/SettingsStore"; +import { TimelineRenderingType } from "../contexts/RoomContext"; +import { ModuleApi } from "../modules/Api"; +import DMRoomMap from "../utils/DMRoomMap"; +import { MatrixClientPeg } from "../MatrixClientPeg"; const roomId = "!room:example.com"; @@ -70,7 +70,7 @@ describe("pickFactory", () => { client = createTestClient(); room = new Room(roomId, client, client.getSafeUserId()); - mocked(client.getRoom).mockImplementation((getRoomId: string): Room | null => { + vi.mocked(client.getRoom).mockImplementation((getRoomId?: string): Room | null => { if (getRoomId === room.roomId) return room; return null; }); @@ -159,7 +159,7 @@ describe("pickFactory", () => { describe("when not showing hidden events", () => { describe("without dynamic predecessor support", () => { beforeEach(() => { - jest.spyOn(SettingsStore, "getValue").mockReset(); + vi.spyOn(SettingsStore, "getValue").mockReset(); }); it("should return undefined for a room without predecessor", () => { @@ -195,7 +195,7 @@ describe("pickFactory", () => { describe("with dynamic predecessor support", () => { beforeEach(() => { - jest.spyOn(SettingsStore, "getValue") + vi.spyOn(SettingsStore, "getValue") .mockReset() .mockImplementation((settingName) => settingName === "feature_dynamic_room_predecessors"); }); @@ -261,11 +261,11 @@ describe("renderTile", () => { afterEach(() => { ModuleApi.instance.customComponents.renderMessage = originalRenderMessage; - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); it("rendering a tile defers to the module API", () => { - ModuleApi.instance.customComponents.renderMessage = jest.fn(); + ModuleApi.instance.customComponents.renderMessage = vi.fn(); const messageEvent = mkEvent({ event: true, @@ -288,7 +288,7 @@ describe("renderTile", () => { }); it("rendering a tile for a message of unknown type defers to the module API", () => { - ModuleApi.instance.customComponents.renderMessage = jest.fn(); + ModuleApi.instance.customComponents.renderMessage = vi.fn(); const messageEvent = mkEvent({ event: true, @@ -310,11 +310,11 @@ describe("renderTile", () => { it("renders an incoming key verification request with the wrapped shared-components view", () => { const sender = "@alice:example.com"; const room = new Room(roomId, client, client.getSafeUserId()); - jest.spyOn(room, "getMember").mockImplementation((userId: string) => { + vi.spyOn(room, "getMember").mockImplementation((userId: string) => { if (userId === sender) return { name: "Alice" } as RoomMember; return null; }); - mocked(client.getRoom).mockReturnValue(room); + vi.mocked(client.getRoom).mockReturnValue(room); const verificationRequestEvent = makeVerificationRequestEvent({ sender, @@ -327,21 +327,20 @@ describe("renderTile", () => { client, ); if (!tile) throw new Error("Expected a key verification request tile"); + const { getByText } = render(tile, withClientContextRenderOptions(client)); - render(React.createElement(MatrixClientContext.Provider, { value: client }, tile)); - - expect(screen.getByText("Alice wants to verify")).toBeInTheDocument(); - expect(screen.getByText("Alice (@alice:example.com)")).toBeInTheDocument(); + expect(getByText("Alice wants to verify")).toBeVisible(); + expect(getByText("Alice (@alice:example.com)")).toBeVisible(); }); it("renders an outgoing key verification request with the wrapped shared-components view", () => { const recipient = "@alice:example.com"; const room = new Room(roomId, client, client.getSafeUserId()); - jest.spyOn(room, "getMember").mockImplementation((userId: string) => { + vi.spyOn(room, "getMember").mockImplementation((userId: string) => { if (userId === recipient) return { name: "Alice" } as RoomMember; return null; }); - mocked(client.getRoom).mockReturnValue(room); + vi.mocked(client.getRoom).mockReturnValue(room); const verificationRequestEvent = makeVerificationRequestEvent({ sender: client.getUserId()!, @@ -354,15 +353,14 @@ describe("renderTile", () => { client, ); if (!tile) throw new Error("Expected a key verification request tile"); + const { getByText } = render(tile, withClientContextRenderOptions(client)); - render(React.createElement(MatrixClientContext.Provider, { value: client }, tile)); - - expect(screen.getByText("You sent a verification request")).toBeInTheDocument(); - expect(screen.getByText("Alice (@alice:example.com)")).toBeInTheDocument(); + expect(getByText("You sent a verification request")).toBeInTheDocument(); + expect(getByText("Alice (@alice:example.com)")).toBeInTheDocument(); }); it("throws when a key verification request tile is rendered without a client context", () => { - jest.spyOn(console, "error").mockImplementation(() => {}); + vi.spyOn(console, "error").mockImplementation(() => {}); const verificationRequestEvent = makeVerificationRequestEvent({ sender: client.getUserId()!, to: "@alice:example.com", @@ -393,11 +391,11 @@ describe("renderTile", () => { }, }), ]); - mocked(client.getRoom).mockReturnValue(room); - jest.spyOn(DMRoomMap, "shared").mockReturnValue({ - getUserIdForRoomId: jest.fn().mockReturnValue(null), + vi.mocked(client.getRoom).mockReturnValue(room); + vi.spyOn(DMRoomMap, "shared").mockReturnValue({ + getUserIdForRoomId: vi.fn().mockReturnValue(null), } as unknown as DMRoomMap); - jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(client); + vi.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(client); const roomAvatarEvent = makeRoomAvatarEvent(); roomAvatarEvent.sender = { name: "Alice" } as MatrixEvent["sender"]; @@ -407,10 +405,9 @@ describe("renderTile", () => { client, ); if (!tile) throw new Error("Expected a room avatar event tile"); + const { getByText, getByRole } = render(tile, withClientContextRenderOptions(client)); - render(React.createElement(MatrixClientContext.Provider, { value: client }, tile)); - - expect(screen.getByText("Alice changed the room avatar to")).toBeInTheDocument(); - expect(screen.getByRole("button", { name: "Alice changed the avatar for General" })).toBeInTheDocument(); + expect(getByText("Alice changed the room avatar to")).toBeInTheDocument(); + expect(getByRole("button", { name: "Alice changed the avatar for General" })).toBeInTheDocument(); }); }); diff --git a/apps/web/test/unit-tests/events/forward/getForwardableEvent-test.ts b/apps/web/src/events/forward/getForwardableEvent.test.ts similarity index 92% rename from apps/web/test/unit-tests/events/forward/getForwardableEvent-test.ts rename to apps/web/src/events/forward/getForwardableEvent.test.ts index 346fb09318c..1f403553154 100644 --- a/apps/web/test/unit-tests/events/forward/getForwardableEvent-test.ts +++ b/apps/web/src/events/forward/getForwardableEvent.test.ts @@ -6,22 +6,25 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { EventType, MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { getForwardableEvent } from "../../../../src/events"; +import { vi, describe, it, expect } from "vitest"; +import { EventType, MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix"; import { getMockClientWithEventEmitter, makeBeaconEvent, makeBeaconInfoEvent, makePollStartEvent, makeRoomWithBeacons, -} from "../../../test-utils"; +} from "test-utils"; + +import { getForwardableEvent } from "./getForwardableEvent"; describe("getForwardableEvent()", () => { const userId = "@alice:server.org"; const roomId = "!room:server.org"; const client = getMockClientWithEventEmitter({ - getRoom: jest.fn(), + getRoom: vi.fn(), }); it("returns the event for a room message", () => { diff --git a/apps/web/test/unit-tests/events/location/getShareableLocationEvent-test.ts b/apps/web/src/events/location/getShareableLocationEvent.test.ts similarity index 92% rename from apps/web/test/unit-tests/events/location/getShareableLocationEvent-test.ts rename to apps/web/src/events/location/getShareableLocationEvent.test.ts index ceea7483024..1f51d89ca14 100644 --- a/apps/web/test/unit-tests/events/location/getShareableLocationEvent-test.ts +++ b/apps/web/src/events/location/getShareableLocationEvent.test.ts @@ -6,22 +6,25 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { EventType, MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { getShareableLocationEvent } from "../../../../src/events"; +import { vi, describe, it, expect } from "vitest"; +import { EventType, MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix"; import { getMockClientWithEventEmitter, makeBeaconEvent, makeBeaconInfoEvent, makeLocationEvent, makeRoomWithBeacons, -} from "../../../test-utils"; +} from "test-utils"; + +import { getShareableLocationEvent } from "./getShareableLocationEvent"; describe("getShareableLocationEvent()", () => { const userId = "@alice:server.org"; const roomId = "!room:server.org"; const client = getMockClientWithEventEmitter({ - getRoom: jest.fn(), + getRoom: vi.fn(), }); it("returns null for a non-location event", () => { diff --git a/apps/web/test/unit-tests/hooks/room/useRoomThreadNotifications-test.tsx b/apps/web/src/hooks/room/useRoomThreadNotifications.test.tsx similarity index 82% rename from apps/web/test/unit-tests/hooks/room/useRoomThreadNotifications-test.tsx rename to apps/web/src/hooks/room/useRoomThreadNotifications.test.tsx index bf1c5de37ac..f450adadef3 100644 --- a/apps/web/test/unit-tests/hooks/room/useRoomThreadNotifications-test.tsx +++ b/apps/web/src/hooks/room/useRoomThreadNotifications.test.tsx @@ -6,14 +6,17 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { renderHook } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { renderHook } from "test-utils-rtl"; import { type MatrixClient, NotificationCountType, Room } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils"; +import { populateThread } from "test-utils/threads"; -import { useRoomThreadNotifications } from "../../../../src/hooks/room/useRoomThreadNotifications"; -import { stubClient } from "../../../test-utils"; -import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; -import { NotificationLevel } from "../../../../src/stores/notifications/NotificationLevel"; -import { populateThread } from "../../../test-utils/threads"; +import { useRoomThreadNotifications } from "../../hooks/room/useRoomThreadNotifications"; +import { MatrixClientPeg } from "../../MatrixClientPeg"; +import { NotificationLevel } from "../../stores/notifications/NotificationLevel"; function render(room: Room) { return renderHook(() => useRoomThreadNotifications(room)); diff --git a/apps/web/test/unit-tests/useTopic-test.tsx b/apps/web/src/hooks/room/useTopic.test.tsx similarity index 84% rename from apps/web/test/unit-tests/useTopic-test.tsx rename to apps/web/src/hooks/room/useTopic.test.tsx index 093bd82658f..c509503ccab 100644 --- a/apps/web/test/unit-tests/useTopic-test.tsx +++ b/apps/web/src/hooks/room/useTopic.test.tsx @@ -6,13 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// @vitest-environment happy-dom + +import { describe, it, expect } from "vitest"; import React from "react"; import { Room } from "matrix-js-sdk/src/matrix"; -import { act, render, screen } from "jest-matrix-react"; +import { act, render, screen } from "test-utils-rtl"; +import { mkEvent, stubClient } from "test-utils"; -import { useTopic } from "../../src/hooks/room/useTopic"; -import { mkEvent, stubClient } from "../test-utils"; -import { MatrixClientPeg } from "../../src/MatrixClientPeg"; +import { useTopic } from "./useTopic"; +import { MatrixClientPeg } from "../../MatrixClientPeg"; describe("useTopic", () => { it("should display the room topic", () => { diff --git a/apps/web/test/unit-tests/hooks/useMediaVisible-test.tsx b/apps/web/src/hooks/useMediaVisible.test.ts similarity index 83% rename from apps/web/test/unit-tests/hooks/useMediaVisible-test.tsx rename to apps/web/src/hooks/useMediaVisible.test.ts index 177573ea9cd..0b8d13fcbf8 100644 --- a/apps/web/test/unit-tests/hooks/useMediaVisible-test.tsx +++ b/apps/web/src/hooks/useMediaVisible.test.ts @@ -5,14 +5,17 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { act, renderHook, waitFor } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; +import { act, renderHook, waitFor } from "test-utils-rtl"; import { JoinRule, MatrixEvent, type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; +import { createTestClient, mkStubRoom, withClientContextRenderOptions } from "test-utils"; -import { useMediaVisible } from "../../../src/hooks/useMediaVisible"; -import { createTestClient, mkStubRoom, withClientContextRenderOptions } from "../../test-utils"; -import { type MediaPreviewConfig, MediaPreviewValue } from "../../../src/@types/media_preview"; -import MediaPreviewConfigController from "../../../src/settings/controllers/MediaPreviewConfigController"; -import SettingsStore from "../../../src/settings/SettingsStore"; +import { useMediaVisible } from "./useMediaVisible"; +import { type MediaPreviewConfig, MediaPreviewValue } from "../@types/media_preview"; +import MediaPreviewConfigController from "../settings/controllers/MediaPreviewConfigController"; +import SettingsStore from "../settings/SettingsStore"; const EVENT_ID = "$fibble:example.org"; const ROOM_ID = "!foobar:example.org"; @@ -43,9 +46,9 @@ describe("useMediaVisible", () => { beforeEach(() => { matrixClient = createTestClient(); room = mkStubRoom(ROOM_ID, undefined, matrixClient); - matrixClient.getRoom = jest.fn().mockReturnValue(room); + matrixClient.getRoom = vi.fn().mockReturnValue(room); const origFn = SettingsStore.getValue; - jest.spyOn(SettingsStore, "getValue").mockImplementation((setting, ...args) => { + vi.spyOn(SettingsStore, "getValue").mockImplementation((setting, ...args) => { if (setting === "mediaPreviewConfig") { return mediaPreviewConfig; } @@ -54,7 +57,7 @@ describe("useMediaVisible", () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); it("should display media by default", () => { @@ -86,7 +89,7 @@ describe("useMediaVisible", () => { "should display media when media previews are Private and the join rule is %s", (rule) => { mediaPreviewConfig.media_previews = MediaPreviewValue.Private; - room.currentState.getJoinRule = jest.fn().mockReturnValue(rule); + room.currentState.getJoinRule = vi.fn().mockReturnValue(rule); const [visible] = render().result.current; expect(visible).toEqual(true); }, @@ -96,7 +99,7 @@ describe("useMediaVisible", () => { "should hide media when media previews are Private and the join rule is %s", (rule) => { mediaPreviewConfig.media_previews = MediaPreviewValue.Private; - room.currentState.getJoinRule = jest.fn().mockReturnValue(rule); + room.currentState.getJoinRule = vi.fn().mockReturnValue(rule); const [visible] = render().result.current; expect(visible).toEqual(false); }, diff --git a/apps/web/test/unit-tests/hooks/useNotificationSettings-test.tsx b/apps/web/src/hooks/useNotificationSettings.test.ts similarity index 83% rename from apps/web/test/unit-tests/hooks/useNotificationSettings-test.tsx rename to apps/web/src/hooks/useNotificationSettings.test.ts index f8d2047e9b2..de4f9d0784c 100644 --- a/apps/web/test/unit-tests/hooks/useNotificationSettings-test.tsx +++ b/apps/web/src/hooks/useNotificationSettings.test.ts @@ -6,18 +6,22 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { waitFor, renderHook } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach } from "vitest"; +import { waitFor, renderHook } from "test-utils-rtl"; import { type IPushRules, type MatrixClient, PushRuleKind, RuleId } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils"; -import { useNotificationSettings } from "../../../src/hooks/useNotificationSettings"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; +import { useNotificationSettings } from "./useNotificationSettings"; +import { MatrixClientPeg } from "../MatrixClientPeg"; import { DefaultNotificationSettings, type NotificationSettings, -} from "../../../src/models/notificationsettings/NotificationSettings"; -import { StandardActions } from "../../../src/notifications/StandardActions"; -import { RoomNotifState } from "../../../src/RoomNotifs"; -import { stubClient } from "../../test-utils"; +} from "../models/notificationsettings/NotificationSettings"; +import { StandardActions } from "../notifications/StandardActions"; +import { RoomNotifState } from "../RoomNotifs"; +import samplePushRules from "../../test/unit-tests/models/notificationsettings/pushrules_sample.json" with { type: "json" }; const expectedModel: NotificationSettings = { globalMute: false, @@ -42,20 +46,16 @@ const expectedModel: NotificationSettings = { }, keywords: ["justjann3", "justj4nn3", "justj4nne", "Janne", "J4nne", "Jann3", "jann3", "j4nne", "janne"], }; +const pushRules = samplePushRules as IPushRules; describe("useNotificationSettings", () => { let cli: MatrixClient; - let pushRules: IPushRules; - - beforeAll(async () => { - pushRules = (await import("../models/notificationsettings/pushrules_sample.json")) as IPushRules; - }); beforeEach(() => { stubClient(); cli = MatrixClientPeg.safeGet(); - cli.getPushRules = jest.fn(cli.getPushRules).mockResolvedValue(pushRules); - cli.supportsIntentionalMentions = jest.fn(cli.supportsIntentionalMentions).mockReturnValue(false); + cli.getPushRules = vi.fn(cli.getPushRules).mockResolvedValue(pushRules); + cli.supportsIntentionalMentions = vi.fn(cli.supportsIntentionalMentions).mockReturnValue(false); }); it("correctly parses model", async () => { @@ -66,13 +66,13 @@ describe("useNotificationSettings", () => { }); it("correctly generates change calls", async () => { - const addPushRule = jest.fn(cli.addPushRule); + const addPushRule = vi.fn(cli.addPushRule); cli.addPushRule = addPushRule; - const deletePushRule = jest.fn(cli.deletePushRule); + const deletePushRule = vi.fn(cli.deletePushRule); cli.deletePushRule = deletePushRule; - const setPushRuleEnabled = jest.fn(cli.setPushRuleEnabled); + const setPushRuleEnabled = vi.fn(cli.setPushRuleEnabled); cli.setPushRuleEnabled = setPushRuleEnabled; - const setPushRuleActions = jest.fn(cli.setPushRuleActions); + const setPushRuleActions = vi.fn(cli.setPushRuleActions); cli.setPushRuleActions = setPushRuleActions; const { result } = renderHook(() => useNotificationSettings(cli)); diff --git a/apps/web/test/unit-tests/hooks/useProfileInfo-test.tsx b/apps/web/src/hooks/useProfileInfo.test.ts similarity index 90% rename from apps/web/test/unit-tests/hooks/useProfileInfo-test.tsx rename to apps/web/src/hooks/useProfileInfo.test.ts index 41e026f1691..e0740c053a0 100644 --- a/apps/web/test/unit-tests/hooks/useProfileInfo-test.tsx +++ b/apps/web/src/hooks/useProfileInfo.test.ts @@ -6,12 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { waitFor, renderHook, act } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { waitFor, renderHook, act } from "test-utils-rtl"; import { type EmptyObject, type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils/test-utils"; -import { useProfileInfo } from "../../../src/hooks/useProfileInfo"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; -import { stubClient } from "../../test-utils/test-utils"; +import { useProfileInfo } from "./useProfileInfo"; +import { MatrixClientPeg } from "../MatrixClientPeg"; function render() { return renderHook(() => useProfileInfo()); diff --git a/apps/web/test/unit-tests/hooks/usePublicRoomDirectory-test.tsx b/apps/web/src/hooks/usePublicRoomDirectory.test.ts similarity index 89% rename from apps/web/test/unit-tests/hooks/usePublicRoomDirectory-test.tsx rename to apps/web/src/hooks/usePublicRoomDirectory.test.ts index 651e5bf7492..51c1936b6e0 100644 --- a/apps/web/test/unit-tests/hooks/usePublicRoomDirectory-test.tsx +++ b/apps/web/src/hooks/usePublicRoomDirectory.test.ts @@ -6,12 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { waitFor, renderHook, act } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { waitFor, renderHook, act } from "test-utils-rtl"; import { type IRoomDirectoryOptions, type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils/test-utils"; -import { usePublicRoomDirectory } from "../../../src/hooks/usePublicRoomDirectory"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; -import { stubClient } from "../../test-utils/test-utils"; +import { usePublicRoomDirectory } from "./usePublicRoomDirectory"; +import { MatrixClientPeg } from "../MatrixClientPeg"; function render() { return renderHook(() => usePublicRoomDirectory()); diff --git a/apps/web/test/unit-tests/hooks/useRoomCall-test.tsx b/apps/web/src/hooks/useRoomCall.test.ts similarity index 74% rename from apps/web/test/unit-tests/hooks/useRoomCall-test.tsx rename to apps/web/src/hooks/useRoomCall.test.ts index 81fbeb39959..638301011db 100644 --- a/apps/web/test/unit-tests/hooks/useRoomCall-test.tsx +++ b/apps/web/src/hooks/useRoomCall.test.ts @@ -5,10 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { renderHook, waitFor } from "jest-matrix-react"; -import React from "react"; +// @vitest-environment happy-dom -import { PlatformCallType, useRoomCall } from "../../../src/hooks/room/useRoomCall"; +import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; +import { renderHook, waitFor } from "test-utils-rtl"; import { getMockClientWithEventEmitter, mkRoom, @@ -17,13 +17,14 @@ import { mockClientMethodsUser, MockEventEmitter, setupAsyncStoreWithClient, -} from "../../test-utils"; -import { ScopedRoomContextProvider } from "../../../src/contexts/ScopedRoomContext"; -import RoomContext, { type RoomContextType } from "../../../src/contexts/RoomContext"; -import { MatrixClientContextProvider } from "../../../src/components/structures/MatrixClientContextProvider"; -import type LegacyCallHandler from "../../../src/LegacyCallHandler"; -import { CallStore } from "../../../src/stores/CallStore"; -import { SDKContextClass } from "../../../src/contexts/SDKContextClass"; + withContexts, +} from "test-utils"; + +import { PlatformCallType, useRoomCall } from "./room/useRoomCall"; +import RoomContext, { type RoomContextType } from "../contexts/RoomContext"; +import type LegacyCallHandler from "../LegacyCallHandler"; +import { CallStore } from "../stores/CallStore"; +import { SDKContextClass } from "../contexts/SDKContextClass"; describe("useRoomCall", () => { const client = getMockClientWithEventEmitter({ @@ -31,16 +32,16 @@ describe("useRoomCall", () => { ...mockClientMethodsServer(), ...mockClientMethodsRooms(), matrixRTC: new MockEventEmitter(), - _unstable_getRTCTransports: jest.fn().mockResolvedValue([]), + _unstable_getRTCTransports: vi.fn().mockResolvedValue([]), getCrypto: () => null, }); const room = mkRoom(client, "!test-room"); // Create a stable room context for this test const mockRoomViewStore = { - isViewingCall: jest.fn().mockReturnValue(false), - on: jest.fn(), - off: jest.fn(), - emit: jest.fn(), + isViewingCall: vi.fn().mockReturnValue(false), + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), }; const roomContext = { @@ -51,30 +52,24 @@ describe("useRoomCall", () => { beforeEach(() => { const callHandler = { - getCallForRoom: jest.fn().mockReturnValue(null), - isCallSidebarShown: jest.fn().mockReturnValue(true), - addListener: jest.fn(), - removeListener: jest.fn(), - on: jest.fn(), - off: jest.fn(), + getCallForRoom: vi.fn().mockReturnValue(null), + isCallSidebarShown: vi.fn().mockReturnValue(true), + addListener: vi.fn(), + removeListener: vi.fn(), + on: vi.fn(), + off: vi.fn(), }; - jest.spyOn(SDKContextClass.instance, "legacyCallHandler", "get").mockReturnValue( + vi.spyOn(SDKContextClass.instance, "legacyCallHandler", "get").mockReturnValue( callHandler as unknown as LegacyCallHandler, ); }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); function render() { - return renderHook(() => useRoomCall(room), { - wrapper: ({ children }) => ( - - {children} - - ), - }); + return renderHook(() => useRoomCall(room), withContexts({ matrixClient: client, roomContext })); } describe("Element Call focus detection", () => { diff --git a/apps/web/test/unit-tests/hooks/useRoomMembers-test.tsx b/apps/web/src/hooks/useRoomMembers.test.ts similarity index 92% rename from apps/web/test/unit-tests/hooks/useRoomMembers-test.tsx rename to apps/web/src/hooks/useRoomMembers.test.ts index dc5bf0e318b..0d12fdd1fab 100644 --- a/apps/web/test/unit-tests/hooks/useRoomMembers-test.tsx +++ b/apps/web/src/hooks/useRoomMembers.test.ts @@ -6,13 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { waitFor, renderHook, act } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { waitFor, renderHook, act } from "test-utils-rtl"; import { type MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; +import { stubClient } from "test-utils"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; -import { stubClient } from "../../test-utils"; -import { useMyRoomMembership, useRoomMemberCount, useRoomMembers } from "../../../src/hooks/useRoomMembers"; +import { MatrixClientPeg } from "../MatrixClientPeg"; +import { useMyRoomMembership, useRoomMemberCount, useRoomMembers } from "./useRoomMembers"; describe("useRoomMembers", () => { function render(room: Room) { diff --git a/apps/web/test/unit-tests/hooks/useUnreadNotifications-test.ts b/apps/web/src/hooks/useUnreadNotifications.test.ts similarity index 88% rename from apps/web/test/unit-tests/hooks/useUnreadNotifications-test.ts rename to apps/web/src/hooks/useUnreadNotifications.test.ts index 6776efa7c04..89af8e6e8c8 100644 --- a/apps/web/test/unit-tests/hooks/useUnreadNotifications-test.ts +++ b/apps/web/src/hooks/useUnreadNotifications.test.ts @@ -6,14 +6,17 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { renderHook } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { renderHook } from "test-utils-rtl"; import { EventStatus, NotificationCountType, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; +import { type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { mkEvent, muteRoom, stubClient } from "test-utils"; -import type { MatrixClient } from "matrix-js-sdk/src/matrix"; -import { useUnreadNotifications } from "../../../src/hooks/useUnreadNotifications"; -import { NotificationLevel } from "../../../src/stores/notifications/NotificationLevel"; -import { mkEvent, muteRoom, stubClient } from "../../test-utils"; +import { useUnreadNotifications } from "./useUnreadNotifications"; +import { NotificationLevel } from "../stores/notifications/NotificationLevel"; describe("useUnreadNotifications", () => { let client: MatrixClient; diff --git a/apps/web/test/unit-tests/hooks/useUserDirectory-test.tsx b/apps/web/src/hooks/useUserDirectory.test.ts similarity index 88% rename from apps/web/test/unit-tests/hooks/useUserDirectory-test.tsx rename to apps/web/src/hooks/useUserDirectory.test.ts index 002b9377b41..53ff24a8f6b 100644 --- a/apps/web/test/unit-tests/hooks/useUserDirectory-test.tsx +++ b/apps/web/src/hooks/useUserDirectory.test.ts @@ -6,12 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { waitFor, renderHook, act } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach } from "vitest"; +import { waitFor, renderHook, act } from "test-utils-rtl"; import { type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils"; -import { useUserDirectory } from "../../../src/hooks/useUserDirectory"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; -import { stubClient } from "../../test-utils"; +import { useUserDirectory } from "./useUserDirectory"; +import { MatrixClientPeg } from "../MatrixClientPeg"; function render() { return renderHook(() => useUserDirectory()); diff --git a/apps/web/test/unit-tests/hooks/useUserStatus-test.tsx b/apps/web/src/hooks/useUserStatus.test.ts similarity index 83% rename from apps/web/test/unit-tests/hooks/useUserStatus-test.tsx rename to apps/web/src/hooks/useUserStatus.test.ts index 6f24a5b3ec5..047977da426 100644 --- a/apps/web/test/unit-tests/hooks/useUserStatus-test.tsx +++ b/apps/web/src/hooks/useUserStatus.test.ts @@ -5,32 +5,34 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import React from "react"; -import { renderHook, waitFor } from "jest-matrix-react"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; +import { renderHook, waitFor } from "test-utils-rtl"; import { ClientEvent } from "matrix-js-sdk/src/matrix"; +import { + getMockClientWithEventEmitter, + mockClientMethodsUser, + mockClientMethodsServer, + withContexts, +} from "test-utils"; -import { useUserStatus } from "../../../src/hooks/useUserStatus"; -import { getMockClientWithEventEmitter, mockClientMethodsUser, mockClientMethodsServer } from "../../test-utils"; -import { MatrixClientContextProvider } from "../../../src/components/structures/MatrixClientContextProvider"; -import SettingsStore from "../../../src/settings/SettingsStore"; -import { userStatusTextWithinMaxLength } from "../../../src/utils/userStatus"; +import { useUserStatus } from "./useUserStatus"; +import SettingsStore from "../settings/SettingsStore"; +import { userStatusTextWithinMaxLength } from "../utils/userStatus"; const userId = "@alice:example.com"; const client = getMockClientWithEventEmitter({ ...mockClientMethodsUser(), ...mockClientMethodsServer(), - getCrypto: jest.fn().mockReturnValue(null), - doesServerSupportExtendedProfiles: jest.fn().mockResolvedValue(true), - getExtendedProfileProperty: jest.fn().mockResolvedValue(undefined), + getCrypto: vi.fn().mockReturnValue(null), + doesServerSupportExtendedProfiles: vi.fn().mockResolvedValue(true), + getExtendedProfileProperty: vi.fn().mockResolvedValue(undefined), }); function render(uid: string | undefined = userId) { - return renderHook(() => useUserStatus(uid), { - wrapper: ({ children }) => ( - {children} - ), - }); + return renderHook(() => useUserStatus(uid), withContexts({ matrixClient: client })); } describe("userStatusTextWithinMaxLength", () => { @@ -49,7 +51,7 @@ describe("userStatusTextWithinMaxLength", () => { describe("useUserStatus", () => { beforeEach(() => { - jest.spyOn(SettingsStore, "getValue").mockImplementation((name): any => { + vi.spyOn(SettingsStore, "getValue").mockImplementation((name): any => { if (name === "feature_user_status") return true; }); client.doesServerSupportExtendedProfiles.mockResolvedValue(true); @@ -57,11 +59,11 @@ describe("useUserStatus", () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); it("returns undefined when feature is disabled", async () => { - jest.spyOn(SettingsStore, "getValue").mockReturnValue(false); + vi.spyOn(SettingsStore, "getValue").mockReturnValue(false); const { result } = render(); expect(result.current).toBeUndefined(); }); diff --git a/apps/web/test/test-utils/index.ts b/apps/web/test/test-utils/index.ts index 87aeeb98c53..860b736b028 100644 --- a/apps/web/test/test-utils/index.ts +++ b/apps/web/test/test-utils/index.ts @@ -21,6 +21,7 @@ export * from "./utilities"; export * from "./date"; export * from "./relations"; export * from "./console"; +export * from "../unit-tests/TestSDKContext.ts"; // wait for loading page export async function waitForLoadingSpinner(): Promise { diff --git a/apps/web/test/test-utils/vitest-matrix-react.tsx b/apps/web/test/test-utils/vitest-matrix-react.tsx new file mode 100644 index 00000000000..f52fe4c4942 --- /dev/null +++ b/apps/web/test/test-utils/vitest-matrix-react.tsx @@ -0,0 +1,16 @@ +/* +Copyright 2024 New Vector Ltd. +Copyright 2022 The Matrix.org Foundation C.I.C. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import "@testing-library/jest-dom/vitest"; +// eslint-disable-next-line no-restricted-imports +import { cleanup } from "@testing-library/react"; +import { afterEach } from "vitest"; + +afterEach(cleanup); + +export * from "./jest-matrix-react.tsx"; diff --git a/apps/web/test/test-utils/wrappers.tsx b/apps/web/test/test-utils/wrappers.tsx index 25ad33b0f89..95ef5d9da4e 100644 --- a/apps/web/test/test-utils/wrappers.tsx +++ b/apps/web/test/test-utils/wrappers.tsx @@ -14,6 +14,8 @@ import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg"; import MatrixClientContext from "../../src/contexts/MatrixClientContext"; import { SDKContext } from "../../src/contexts/SDKContext"; import { type SDKContextClass } from "../../src/contexts/SDKContextClass"; +import { RoomContextType } from "../../src/contexts/RoomContext.ts"; +import { ScopedRoomContextProvider } from "../../src/contexts/ScopedRoomContext.tsx"; type WrapperProps = { wrappedRef?: Ref> } & T; @@ -73,3 +75,28 @@ export function clientAndSDKContextRenderOptions(client: MatrixClient, sdkContex ), }; } +export function withContexts({ + sdkContext, + matrixClient, + roomContext, +}: { + sdkContext?: SDKContextClass; + matrixClient?: MatrixClient; + roomContext?: RoomContextType; +}): RenderOptions { + return { + wrapper: ({ children }) => { + const client = matrixClient || sdkContext?.client; + if (client) { + children = {children}; + } + if (sdkContext) { + children = {children}; + } + if (roomContext) { + children = {children}; + } + return children; + }, + }; +} diff --git a/apps/web/vitest.config.ts b/apps/web/vitest.config.ts index a8a8792b1c7..70c9d593813 100644 --- a/apps/web/vitest.config.ts +++ b/apps/web/vitest.config.ts @@ -11,7 +11,7 @@ import { resolve } from "node:path"; export default defineProject({ resolve: { alias: [ - { find: "test-utils-rtl", replacement: resolve(__dirname, "./test/test-utils/jest-matrix-react") }, + { find: "test-utils-rtl", replacement: resolve(__dirname, "./test/test-utils/vitest-matrix-react") }, { find: "test-utils", replacement: resolve(__dirname, "./test/test-utils") }, // Stub out workers as they do not play well under test { From 62273c6989aa9c2952aa5a3f86abc217368d71be Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 8 Jul 2026 12:49:46 +0100 Subject: [PATCH 2/2] Iterate --- apps/web/test/test-utils/wrappers.tsx | 2 +- .../test/viewmodels/timeline/DateSeparatorViewModel-test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/test/test-utils/wrappers.tsx b/apps/web/test/test-utils/wrappers.tsx index 95ef5d9da4e..8dd0761c577 100644 --- a/apps/web/test/test-utils/wrappers.tsx +++ b/apps/web/test/test-utils/wrappers.tsx @@ -14,7 +14,7 @@ import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg"; import MatrixClientContext from "../../src/contexts/MatrixClientContext"; import { SDKContext } from "../../src/contexts/SDKContext"; import { type SDKContextClass } from "../../src/contexts/SDKContextClass"; -import { RoomContextType } from "../../src/contexts/RoomContext.ts"; +import { type RoomContextType } from "../../src/contexts/RoomContext.ts"; import { ScopedRoomContextProvider } from "../../src/contexts/ScopedRoomContext.tsx"; type WrapperProps = { wrappedRef?: Ref> } & T; diff --git a/apps/web/test/viewmodels/timeline/DateSeparatorViewModel-test.tsx b/apps/web/test/viewmodels/timeline/DateSeparatorViewModel-test.tsx index 224a205e47d..a8682009271 100644 --- a/apps/web/test/viewmodels/timeline/DateSeparatorViewModel-test.tsx +++ b/apps/web/test/viewmodels/timeline/DateSeparatorViewModel-test.tsx @@ -18,7 +18,7 @@ import SettingsStore from "../../../src/settings/SettingsStore"; import { UIFeature } from "../../../src/settings/UIFeature"; import { SDKContextClass } from "../../../src/contexts/SDKContextClass"; import { DateSeparatorViewModel } from "../../../src/viewmodels/room/timeline/DateSeparatorViewModel"; -import { flushPromisesWithFakeTimers } from "../../test-utils"; +import { flushPromisesWithFakeTimers } from "../../test-utils/utilities"; jest.mock("../../../src/settings/SettingsStore"); jest.mock("../../../src/contexts/SDKContextClass", () => ({