From 275ea25ecae952332c98ab36c6cb8f3faff6e7a1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 3 Jul 2026 11:10:04 +0100 Subject: [PATCH] Migrate batch of tests to vitest (#34106) * Migrate autocomplete tests to vitest * Migrate utils/beacon tests to vitest * Migrate utils/device tests to vitest * Migrate utils/crypto tests to vitest * Migrate utils/localRoom tests to vitest * Migrate notifications tests to vitest * Fix types * Make jest test happy * Make sonar happier --- .../autocomplete/CommandProvider.test.ts} | 23 ++++---- .../autocomplete/EmojiProvider.test.ts} | 13 +++-- .../autocomplete/QueryMatcher.test.ts} | 14 ++--- .../autocomplete/RoomProvider.test.ts} | 28 +++++----- .../autocomplete/SpaceProvider.test.ts} | 28 +++++----- .../notifications/ContentRules.test.ts} | 11 ++-- .../PushRuleVectorState.test.ts} | 3 +- .../utils/beacon/bounds.test.ts} | 9 ++-- .../utils/beacon/duration.test.ts} | 13 +++-- .../utils/beacon/geolocation.test.ts} | 52 +++++++++---------- .../utils/beacon/timeline.test.ts} | 9 ++-- .../utils/crypto/deviceInfo.test.ts} | 24 +++++---- .../shouldForceDisableEncryption.test.ts} | 10 ++-- .../utils/device/clientInformation.test.ts} | 29 ++++++----- .../utils/device/parseUserAgent.test.ts} | 8 ++- ...noozeBulkUnverifiedDeviceReminder.test.ts} | 19 ++++--- .../utils/localRoom/isLocalRoom.test.ts} | 11 ++-- .../utils/localRoom/isRoomReady.test.ts} | 16 +++--- apps/web/test/setup/adapter.ts | 2 +- apps/web/test/test-utils/beacon.ts | 15 ++++-- apps/web/vitest.config.ts | 5 ++ 21 files changed, 195 insertions(+), 147 deletions(-) rename apps/web/{test/unit-tests/autocomplete/CommandProvider-test.ts => src/autocomplete/CommandProvider.test.ts} (82%) rename apps/web/{test/unit-tests/autocomplete/EmojiProvider-test.ts => src/autocomplete/EmojiProvider.test.ts} (92%) rename apps/web/{test/unit-tests/autocomplete/QueryMatcher-test.ts => src/autocomplete/QueryMatcher.test.ts} (95%) rename apps/web/{test/unit-tests/autocomplete/RoomProvider-test.ts => src/autocomplete/RoomProvider.test.ts} (83%) rename apps/web/{test/unit-tests/autocomplete/SpaceProvider-test.ts => src/autocomplete/SpaceProvider.test.ts} (83%) rename apps/web/{test/unit-tests/notifications/ContentRules-test.ts => src/notifications/ContentRules.test.ts} (90%) rename apps/web/{test/unit-tests/notifications/PushRuleVectorState-test.ts => src/notifications/PushRuleVectorState.test.ts} (94%) rename apps/web/{test/unit-tests/utils/beacon/bounds-test.ts => src/utils/beacon/bounds.test.ts} (94%) rename apps/web/{test/unit-tests/utils/beacon/duration-test.ts => src/utils/beacon/duration.test.ts} (92%) rename apps/web/{test/unit-tests/utils/beacon/geolocation-test.ts => src/utils/beacon/geolocation.test.ts} (83%) rename apps/web/{test/unit-tests/utils/beacon/timeline-test.ts => src/utils/beacon/timeline.test.ts} (87%) rename apps/web/{test/unit-tests/utils/crypto/deviceInfo-test.ts => src/utils/crypto/deviceInfo.test.ts} (76%) rename apps/web/{test/unit-tests/utils/crypto/shouldForceDisableEncryption-test.ts => src/utils/crypto/shouldForceDisableEncryption.test.ts} (87%) rename apps/web/{test/unit-tests/utils/device/clientInformation-test.ts => src/utils/device/clientInformation.test.ts} (84%) rename apps/web/{test/unit-tests/utils/device/parseUserAgent-test.ts => src/utils/device/parseUserAgent.test.ts} (98%) rename apps/web/{test/unit-tests/utils/device/snoozeBulkUnverifiedDeviceReminder-test.ts => src/utils/device/snoozeBulkUnverifiedDeviceReminder.test.ts} (83%) rename apps/web/{test/unit-tests/utils/localRoom/isLocalRoom-test.ts => src/utils/localRoom/isLocalRoom.test.ts} (80%) rename apps/web/{test/unit-tests/utils/localRoom/isRoomReady-test.ts => src/utils/localRoom/isRoomReady.test.ts} (91%) diff --git a/apps/web/test/unit-tests/autocomplete/CommandProvider-test.ts b/apps/web/src/autocomplete/CommandProvider.test.ts similarity index 82% rename from apps/web/test/unit-tests/autocomplete/CommandProvider-test.ts rename to apps/web/src/autocomplete/CommandProvider.test.ts index ed02dd1adf..268487f8c6 100644 --- a/apps/web/test/unit-tests/autocomplete/CommandProvider-test.ts +++ b/apps/web/src/autocomplete/CommandProvider.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 { type Room } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import CommandProvider from "../../../src/autocomplete/CommandProvider"; -import { stubClient } from "../../test-utils"; -import { Command } from "../../../src/slash-commands/command"; -import { CommandCategories } from "../../../src/slash-commands/interface"; -import { _td } from "../../../src/languageHandler"; -import * as SlashCommands from "../../../src/slash-commands/SlashCommands"; +import { vi, describe, it, expect, beforeEach } from "vitest"; +import { type Room } from "matrix-js-sdk/src/matrix"; +import { stubClient } from "test-utils"; + +import CommandProvider from "./CommandProvider"; +import { Command } from "../slash-commands/command"; +import { CommandCategories } from "../slash-commands/interface"; +import { _td } from "../languageHandler"; +import * as SlashCommands from "../slash-commands/SlashCommands"; describe("CommandProvider", () => { let room: Room; @@ -30,7 +33,7 @@ describe("CommandProvider", () => { command: "disabled", args: "", description: _td("slash_command|spoiler"), - runFn: jest.fn(), + runFn: vi.fn(), category: CommandCategories.messages, isEnabled: () => false, }); @@ -40,7 +43,7 @@ describe("CommandProvider", () => { command: "enabled", args: "", description: _td("slash_command|shrug"), - runFn: jest.fn(), + runFn: vi.fn(), category: CommandCategories.messages, isEnabled: () => true, }); @@ -81,7 +84,7 @@ describe("CommandProvider", () => { // Then we should get the completion because the command is enabled // The completion preserves the arguments when the command matches - expect(enabledCompletions.length).toBe(1); + expect(enabledCompletions).toHaveLength(1); expect(enabledCompletions[0].completion).toBe("/enabled test"); }); }); diff --git a/apps/web/test/unit-tests/autocomplete/EmojiProvider-test.ts b/apps/web/src/autocomplete/EmojiProvider.test.ts similarity index 92% rename from apps/web/test/unit-tests/autocomplete/EmojiProvider-test.ts rename to apps/web/src/autocomplete/EmojiProvider.test.ts index c2c42691b7..6d8ee5f611 100644 --- a/apps/web/test/unit-tests/autocomplete/EmojiProvider-test.ts +++ b/apps/web/src/autocomplete/EmojiProvider.test.ts @@ -6,11 +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. */ -import EmojiProvider from "../../../src/autocomplete/EmojiProvider"; -import { mkStubRoom } from "../../test-utils/test-utils"; -import { add } from "../../../src/emojipicker/recent"; -import { stubClient } from "../../test-utils"; -import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; +// @vitest-environment happy-dom + +import { describe, it, expect } from "vitest"; +import { stubClient, mkStubRoom } from "test-utils"; + +import EmojiProvider from "./EmojiProvider"; +import { add } from "../emojipicker/recent"; +import { MatrixClientPeg } from "../MatrixClientPeg"; const EMOJI_SHORTCODES = [ ":+1", diff --git a/apps/web/test/unit-tests/autocomplete/QueryMatcher-test.ts b/apps/web/src/autocomplete/QueryMatcher.test.ts similarity index 95% rename from apps/web/test/unit-tests/autocomplete/QueryMatcher-test.ts rename to apps/web/src/autocomplete/QueryMatcher.test.ts index 22ae71004c..94ac52be1d 100644 --- a/apps/web/test/unit-tests/autocomplete/QueryMatcher-test.ts +++ b/apps/web/src/autocomplete/QueryMatcher.test.ts @@ -5,7 +5,9 @@ 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 QueryMatcher from "../../../src/autocomplete/QueryMatcher"; +import { describe, it, expect } from "vitest"; + +import QueryMatcher from "./QueryMatcher"; const OBJECTS = [ { name: "Mel B", nick: "Scary" }, @@ -22,7 +24,7 @@ describe("QueryMatcher", function () { const qm = new QueryMatcher(OBJECTS, { keys: ["name"] }); const results = qm.match("Geri"); - expect(results.length).toBe(1); + expect(results).toHaveLength(1); expect(results[0].name).toBe("Geri"); }); @@ -30,7 +32,7 @@ describe("QueryMatcher", function () { const qm = new QueryMatcher(OBJECTS, { keys: ["name"] }); const results = qm.match("Ge"); - expect(results.length).toBe(1); + expect(results).toHaveLength(1); expect(results[0].name).toBe("Geri"); }); @@ -38,7 +40,7 @@ describe("QueryMatcher", function () { const qm = new QueryMatcher(OBJECTS, { keys: ["name"] }); const results = qm.match("geri"); - expect(results.length).toBe(1); + expect(results).toHaveLength(1); expect(results[0].name).toBe("Geri"); }); @@ -46,7 +48,7 @@ describe("QueryMatcher", function () { const qm = new QueryMatcher([{ name: "Gëri", foo: 46 }], { keys: ["name"] }); const results = qm.match("geri"); - expect(results.length).toBe(1); + expect(results).toHaveLength(1); expect(results[0].foo).toBe(46); }); @@ -159,7 +161,7 @@ describe("QueryMatcher", function () { }); const results = qm.match("bob"); - expect(results.length).toBe(1); + expect(results).toHaveLength(1); expect(results[0].name).toBe("bob"); }); }); diff --git a/apps/web/test/unit-tests/autocomplete/RoomProvider-test.ts b/apps/web/src/autocomplete/RoomProvider.test.ts similarity index 83% rename from apps/web/test/unit-tests/autocomplete/RoomProvider-test.ts rename to apps/web/src/autocomplete/RoomProvider.test.ts index 3da37528ed..8353ed020d 100644 --- a/apps/web/test/unit-tests/autocomplete/RoomProvider-test.ts +++ b/apps/web/src/autocomplete/RoomProvider.test.ts @@ -6,19 +6,21 @@ 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 { mocked } from "jest-mock"; -import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import RoomProvider from "../../../src/autocomplete/RoomProvider"; -import SettingsStore from "../../../src/settings/SettingsStore"; -import { mkRoom, mkSpace, stubClient } from "../../test-utils"; +import { vi, describe, it, expect, beforeEach } from "vitest"; +import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; +import { mkRoom, mkSpace, stubClient } from "test-utils"; + +import RoomProvider from "./RoomProvider"; +import SettingsStore from "../settings/SettingsStore"; describe("RoomProvider", () => { it("suggests a room whose alias matches a prefix", async () => { // Given a room const client = stubClient(); const room = makeRoom(client, "room:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([room]); + vi.mocked(client.getVisibleRooms).mockReturnValue([room]); // When we search for rooms starting with its prefix const roomProvider = new RoomProvider(room); @@ -45,7 +47,7 @@ describe("RoomProvider", () => { const room2 = makeRoom(client, "room2:e.com"); const other = makeRoom(client, "other:e.com"); const space = makeSpace(client, "room3:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([room1, room2, other, space]); + vi.mocked(client.getVisibleRooms).mockReturnValue([room1, room2, other, space]); // When we search for rooms starting with a prefix const roomProvider = new RoomProvider(room1); @@ -76,14 +78,14 @@ describe("RoomProvider", () => { describe("If the feature_dynamic_room_predecessors is not enabled", () => { beforeEach(() => { - jest.spyOn(SettingsStore, "getValue").mockReturnValue(false); + vi.spyOn(SettingsStore, "getValue").mockReturnValue(false); }); it("Passes through the dynamic predecessor setting", async () => { const client = stubClient(); const room = makeRoom(client, "room:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([room]); - mocked(client.getVisibleRooms).mockClear(); + vi.mocked(client.getVisibleRooms).mockReturnValue([room]); + vi.mocked(client.getVisibleRooms).mockClear(); const roomProvider = new RoomProvider(room); await roomProvider.getCompletions("#ro", { beginning: true, start: 0, end: 3 }); @@ -95,7 +97,7 @@ describe("RoomProvider", () => { describe("If the feature_dynamic_room_predecessors is enabled", () => { beforeEach(() => { // Turn on feature_dynamic_room_predecessors setting - jest.spyOn(SettingsStore, "getValue").mockImplementation( + vi.spyOn(SettingsStore, "getValue").mockImplementation( (settingName) => settingName === "feature_dynamic_room_predecessors", ); }); @@ -103,8 +105,8 @@ describe("RoomProvider", () => { it("Passes through the dynamic predecessor setting", async () => { const client = stubClient(); const room = makeRoom(client, "room:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([room]); - mocked(client.getVisibleRooms).mockClear(); + vi.mocked(client.getVisibleRooms).mockReturnValue([room]); + vi.mocked(client.getVisibleRooms).mockClear(); const roomProvider = new RoomProvider(room); await roomProvider.getCompletions("#ro", { beginning: true, start: 0, end: 3 }); diff --git a/apps/web/test/unit-tests/autocomplete/SpaceProvider-test.ts b/apps/web/src/autocomplete/SpaceProvider.test.ts similarity index 83% rename from apps/web/test/unit-tests/autocomplete/SpaceProvider-test.ts rename to apps/web/src/autocomplete/SpaceProvider.test.ts index 9769d55660..68cc517e34 100644 --- a/apps/web/test/unit-tests/autocomplete/SpaceProvider-test.ts +++ b/apps/web/src/autocomplete/SpaceProvider.test.ts @@ -6,19 +6,21 @@ 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 { mocked } from "jest-mock"; -import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import SpaceProvider from "../../../src/autocomplete/SpaceProvider"; -import SettingsStore from "../../../src/settings/SettingsStore"; -import { mkRoom, mkSpace, stubClient } from "../../test-utils"; +import { vi, describe, it, expect, beforeEach } from "vitest"; +import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; +import { mkRoom, mkSpace, stubClient } from "test-utils"; + +import SpaceProvider from "./SpaceProvider"; +import SettingsStore from "../settings/SettingsStore"; describe("SpaceProvider", () => { it("suggests a space whose alias matches a prefix", async () => { // Given a space const client = stubClient(); const space = makeSpace(client, "space:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([space]); + vi.mocked(client.getVisibleRooms).mockReturnValue([space]); // When we search for spaces starting with its prefix const spaceProvider = new SpaceProvider(space); @@ -45,7 +47,7 @@ describe("SpaceProvider", () => { const space2 = makeSpace(client, "space2:e.com"); const other = makeSpace(client, "other:e.com"); const room = makeRoom(client, "space3:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([space1, space2, other, room]); + vi.mocked(client.getVisibleRooms).mockReturnValue([space1, space2, other, room]); // When we search for spaces starting with a prefix const spaceProvider = new SpaceProvider(space1); @@ -76,14 +78,14 @@ describe("SpaceProvider", () => { describe("If the feature_dynamic_room_predecessors is not enabled", () => { beforeEach(() => { - jest.spyOn(SettingsStore, "getValue").mockReturnValue(false); + vi.spyOn(SettingsStore, "getValue").mockReturnValue(false); }); it("Passes through the dynamic predecessor setting", async () => { const client = stubClient(); const space = makeSpace(client, "space:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([space]); - mocked(client.getVisibleRooms).mockClear(); + vi.mocked(client.getVisibleRooms).mockReturnValue([space]); + vi.mocked(client.getVisibleRooms).mockClear(); const spaceProvider = new SpaceProvider(space); await spaceProvider.getCompletions("#ro", { beginning: true, start: 0, end: 3 }); @@ -95,7 +97,7 @@ describe("SpaceProvider", () => { describe("If the feature_dynamic_room_predecessors is enabled", () => { beforeEach(() => { // Turn on feature_dynamic_space_predecessors setting - jest.spyOn(SettingsStore, "getValue").mockImplementation( + vi.spyOn(SettingsStore, "getValue").mockImplementation( (settingName) => settingName === "feature_dynamic_room_predecessors", ); }); @@ -103,8 +105,8 @@ describe("SpaceProvider", () => { it("Passes through the dynamic predecessor setting", async () => { const client = stubClient(); const space = makeSpace(client, "space:e.com"); - mocked(client.getVisibleRooms).mockReturnValue([space]); - mocked(client.getVisibleRooms).mockClear(); + vi.mocked(client.getVisibleRooms).mockReturnValue([space]); + vi.mocked(client.getVisibleRooms).mockClear(); const spaceProvider = new SpaceProvider(space); await spaceProvider.getCompletions("#ro", { beginning: true, start: 0, end: 3 }); diff --git a/apps/web/test/unit-tests/notifications/ContentRules-test.ts b/apps/web/src/notifications/ContentRules.test.ts similarity index 90% rename from apps/web/test/unit-tests/notifications/ContentRules-test.ts rename to apps/web/src/notifications/ContentRules.test.ts index 7f900b1d08..b1dc504629 100644 --- a/apps/web/test/unit-tests/notifications/ContentRules-test.ts +++ b/apps/web/src/notifications/ContentRules.test.ts @@ -7,9 +7,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 { describe, it, expect } from "vitest"; import { TweakName, PushRuleActionName, type TweakHighlight, type TweakSound } from "matrix-js-sdk/src/matrix"; -import { ContentRules, PushRuleVectorState } from "../../../src/notifications"; +import { ContentRules, PushRuleVectorState } from "."; const NORMAL_RULE = { actions: [PushRuleActionName.Notify, { set_tweak: TweakName.Highlight, value: false } as TweakHighlight], @@ -57,7 +58,7 @@ describe("ContentRules", function () { const rules = { global: { content: [NORMAL_RULE, USERNAME_RULE] } }; const parsed = ContentRules.parseContentRules(rules); - expect(parsed.rules.length).toEqual(1); + expect(parsed.rules).toHaveLength(1); expect(parsed.rules[0]).toEqual(NORMAL_RULE); expect(parsed.vectorState).toEqual(PushRuleVectorState.ON); expect(parsed.externalRules).toEqual([]); @@ -67,7 +68,7 @@ describe("ContentRules", function () { const rules = { global: { content: [LOUD_RULE, USERNAME_RULE] } }; const parsed = ContentRules.parseContentRules(rules); - expect(parsed.rules.length).toEqual(1); + expect(parsed.rules).toHaveLength(1); expect(parsed.rules[0]).toEqual(LOUD_RULE); expect(parsed.vectorState).toEqual(PushRuleVectorState.LOUD); expect(parsed.externalRules).toEqual([]); @@ -77,10 +78,10 @@ describe("ContentRules", function () { const rules = { global: { content: [LOUD_RULE, NORMAL_RULE, USERNAME_RULE] } }; const parsed = ContentRules.parseContentRules(rules); - expect(parsed.rules.length).toEqual(1); + expect(parsed.rules).toHaveLength(1); expect(parsed.rules[0]).toEqual(LOUD_RULE); expect(parsed.vectorState).toEqual(PushRuleVectorState.LOUD); - expect(parsed.externalRules.length).toEqual(1); + expect(parsed.externalRules).toHaveLength(1); expect(parsed.externalRules[0]).toEqual(NORMAL_RULE); }); }); diff --git a/apps/web/test/unit-tests/notifications/PushRuleVectorState-test.ts b/apps/web/src/notifications/PushRuleVectorState.test.ts similarity index 94% rename from apps/web/test/unit-tests/notifications/PushRuleVectorState-test.ts rename to apps/web/src/notifications/PushRuleVectorState.test.ts index 8179bde13e..14a6cb8694 100644 --- a/apps/web/test/unit-tests/notifications/PushRuleVectorState-test.ts +++ b/apps/web/src/notifications/PushRuleVectorState.test.ts @@ -7,9 +7,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 { describe, it, expect } from "vitest"; import { PushRuleActionName, type TweakHighlight, TweakName, type TweakSound } from "matrix-js-sdk/src/matrix"; -import { PushRuleVectorState } from "../../../src/notifications"; +import { PushRuleVectorState } from "./PushRuleVectorState"; describe("PushRuleVectorState", function () { describe("contentRuleVectorStateKind", function () { diff --git a/apps/web/test/unit-tests/utils/beacon/bounds-test.ts b/apps/web/src/utils/beacon/bounds.test.ts similarity index 94% rename from apps/web/test/unit-tests/utils/beacon/bounds-test.ts rename to apps/web/src/utils/beacon/bounds.test.ts index 0a9876d237..90c5b44eb5 100644 --- a/apps/web/test/unit-tests/utils/beacon/bounds-test.ts +++ b/apps/web/src/utils/beacon/bounds.test.ts @@ -6,10 +6,13 @@ 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 { Beacon } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { type Bounds, getBeaconBounds } from "../../../../src/utils/beacon/bounds"; -import { makeBeaconEvent, makeBeaconInfoEvent } from "../../../test-utils"; +import { describe, it, expect } from "vitest"; +import { Beacon } from "matrix-js-sdk/src/matrix"; +import { makeBeaconEvent, makeBeaconInfoEvent } from "test-utils"; + +import { type Bounds, getBeaconBounds } from "./bounds"; describe("getBeaconBounds()", () => { const userId = "@user:server"; diff --git a/apps/web/test/unit-tests/utils/beacon/duration-test.ts b/apps/web/src/utils/beacon/duration.test.ts similarity index 92% rename from apps/web/test/unit-tests/utils/beacon/duration-test.ts rename to apps/web/src/utils/beacon/duration.test.ts index da17d6cbb4..b6fe56938b 100644 --- a/apps/web/test/unit-tests/utils/beacon/duration-test.ts +++ b/apps/web/src/utils/beacon/duration.test.ts @@ -6,10 +6,13 @@ 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 { M_TIMESTAMP, Beacon } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { msUntilExpiry, sortBeaconsByLatestExpiry, sortBeaconsByLatestCreation } from "../../../../src/utils/beacon"; -import { makeBeaconInfoEvent } from "../../../test-utils"; +import { vi, describe, it, expect, afterAll, beforeEach } from "vitest"; +import { M_TIMESTAMP, Beacon } from "matrix-js-sdk/src/matrix"; +import { makeBeaconInfoEvent } from "test-utils"; + +import { msUntilExpiry, sortBeaconsByLatestExpiry, sortBeaconsByLatestCreation } from "./duration"; describe("beacon utils", () => { // 14.03.2022 16:15 @@ -17,11 +20,11 @@ describe("beacon utils", () => { const HOUR_MS = 3600000; beforeEach(() => { - jest.spyOn(global.Date, "now").mockReturnValue(now); + vi.spyOn(global.Date, "now").mockReturnValue(now); }); afterAll(() => { - jest.spyOn(global.Date, "now").mockRestore(); + vi.spyOn(global.Date, "now").mockRestore(); }); describe("msUntilExpiry", () => { diff --git a/apps/web/test/unit-tests/utils/beacon/geolocation-test.ts b/apps/web/src/utils/beacon/geolocation.test.ts similarity index 83% rename from apps/web/test/unit-tests/utils/beacon/geolocation-test.ts rename to apps/web/src/utils/beacon/geolocation.test.ts index 822022fe6a..c4014f7c4a 100644 --- a/apps/web/test/unit-tests/utils/beacon/geolocation-test.ts +++ b/apps/web/src/utils/beacon/geolocation.test.ts @@ -6,8 +6,11 @@ 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 { vi, describe, it, expect, beforeEach, afterEach, type Mocked } from "vitest"; import { logger } from "matrix-js-sdk/src/logger"; -import { type Mocked } from "jest-mock-vitest-adapter"; +import { makeGeolocationPosition, mockGeolocation, getMockGeolocationPositionError } from "test-utils"; import { type GenericPosition, @@ -16,9 +19,8 @@ import { mapGeolocationError, mapGeolocationPositionToTimedGeo, watchPosition, -} from "../../../../src/utils/beacon"; -import { getCurrentPosition } from "../../../../src/utils/beacon/geolocation"; -import { makeGeolocationPosition, mockGeolocation, getMockGeolocationPositionError } from "../../../test-utils"; + getCurrentPosition, +} from "./geolocation"; describe("geolocation utilities", () => { let geolocation: Mocked; @@ -29,12 +31,12 @@ describe("geolocation utilities", () => { beforeEach(() => { geolocation = mockGeolocation(); - jest.spyOn(Date, "now").mockReturnValue(now); + vi.spyOn(Date, "now").mockReturnValue(now); }); afterEach(() => { - jest.spyOn(Date, "now").mockRestore(); - jest.spyOn(logger, "error").mockRestore(); + vi.spyOn(Date, "now").mockRestore(); + vi.spyOn(logger, "error").mockRestore(); }); describe("getGeoUri", () => { @@ -97,7 +99,7 @@ describe("geolocation utilities", () => { describe("mapGeolocationError", () => { beforeEach(() => { // suppress expected errors from test log - jest.spyOn(logger, "error").mockImplementation(() => {}); + vi.spyOn(logger, "error").mockImplementation(() => {}); }); it("returns default for other error", () => { @@ -138,21 +140,20 @@ describe("geolocation utilities", () => { describe("watchPosition()", () => { it("throws with unavailable error when geolocation is not available", () => { // suppress expected errors from test log - jest.spyOn(logger, "error").mockImplementation(() => {}); + vi.spyOn(logger, "error").mockImplementation(() => {}); // remove the mock we added - // @ts-ignore illegal assignment to readonly property - navigator.geolocation = undefined; + vi.spyOn(navigator, "geolocation", "get").mockRestore(); - const positionHandler = jest.fn(); - const errorHandler = jest.fn(); + const positionHandler = vi.fn(); + const errorHandler = vi.fn(); expect(() => watchPosition(positionHandler, errorHandler)).toThrow(GeolocationError.Unavailable); }); it("sets up position handler with correct options", () => { - const positionHandler = jest.fn(); - const errorHandler = jest.fn(); + const positionHandler = vi.fn(); + const errorHandler = vi.fn(); watchPosition(positionHandler, errorHandler); const [, , options] = geolocation.watchPosition.mock.calls[0]; @@ -165,8 +166,8 @@ describe("geolocation utilities", () => { it("returns clearWatch function", () => { const watchId = 1; geolocation.watchPosition.mockReturnValue(watchId); - const positionHandler = jest.fn(); - const errorHandler = jest.fn(); + const positionHandler = vi.fn(); + const errorHandler = vi.fn(); const clearWatch = watchPosition(positionHandler, errorHandler); clearWatch(); @@ -175,8 +176,8 @@ describe("geolocation utilities", () => { }); it("calls position handler with position", () => { - const positionHandler = jest.fn(); - const errorHandler = jest.fn(); + const positionHandler = vi.fn(); + const errorHandler = vi.fn(); watchPosition(positionHandler, errorHandler); expect(positionHandler).toHaveBeenCalledWith(defaultPosition); @@ -184,13 +185,13 @@ describe("geolocation utilities", () => { it("maps geolocation position error and calls error handler", () => { // suppress expected errors from test log - jest.spyOn(logger, "error").mockImplementation(() => {}); + vi.spyOn(logger, "error").mockImplementation(() => {}); geolocation.watchPosition.mockImplementation((_callback, error) => { error!(getMockGeolocationPositionError(1, "message")); return -1; }); - const positionHandler = jest.fn(); - const errorHandler = jest.fn(); + const positionHandler = vi.fn(); + const errorHandler = vi.fn(); watchPosition(positionHandler, errorHandler); expect(errorHandler).toHaveBeenCalledWith(GeolocationError.PermissionDenied); @@ -200,18 +201,17 @@ describe("geolocation utilities", () => { describe("getCurrentPosition()", () => { it("throws with unavailable error when geolocation is not available", async () => { // suppress expected errors from test log - jest.spyOn(logger, "error").mockImplementation(() => {}); + vi.spyOn(logger, "error").mockImplementation(() => {}); // remove the mock we added - // @ts-ignore illegal assignment to readonly property - navigator.geolocation = undefined; + vi.spyOn(navigator, "geolocation", "get").mockRestore(); await expect(() => getCurrentPosition()).rejects.toThrow(GeolocationError.Unavailable); }); it("throws with geolocation error when geolocation.getCurrentPosition fails", async () => { // suppress expected errors from test log - jest.spyOn(logger, "error").mockImplementation(() => {}); + vi.spyOn(logger, "error").mockImplementation(() => {}); const timeoutError = getMockGeolocationPositionError(3, "message"); geolocation.getCurrentPosition.mockImplementation((callback, error) => error!(timeoutError)); diff --git a/apps/web/test/unit-tests/utils/beacon/timeline-test.ts b/apps/web/src/utils/beacon/timeline.test.ts similarity index 87% rename from apps/web/test/unit-tests/utils/beacon/timeline-test.ts rename to apps/web/src/utils/beacon/timeline.test.ts index 0c7306bf4f..0ccbe472f4 100644 --- a/apps/web/test/unit-tests/utils/beacon/timeline-test.ts +++ b/apps/web/src/utils/beacon/timeline.test.ts @@ -6,10 +6,13 @@ 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, Room } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { shouldDisplayAsBeaconTile } from "../../../../src/utils/beacon/timeline"; -import { makeBeaconInfoEvent, stubClient } from "../../../test-utils"; +import { describe, it, expect } from "vitest"; +import { EventType, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; +import { makeBeaconInfoEvent, stubClient } from "test-utils"; + +import { shouldDisplayAsBeaconTile } from "./timeline"; describe("shouldDisplayAsBeaconTile", () => { const userId = "@user:server"; diff --git a/apps/web/test/unit-tests/utils/crypto/deviceInfo-test.ts b/apps/web/src/utils/crypto/deviceInfo.test.ts similarity index 76% rename from apps/web/test/unit-tests/utils/crypto/deviceInfo-test.ts rename to apps/web/src/utils/crypto/deviceInfo.test.ts index ee31e51459..6d81add5b1 100644 --- a/apps/web/test/unit-tests/utils/crypto/deviceInfo-test.ts +++ b/apps/web/src/utils/crypto/deviceInfo.test.ts @@ -6,11 +6,13 @@ 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 { type Mocked, mocked } from "jest-mock-vitest-adapter"; -import { type Device, type MatrixClient } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { getDeviceCryptoInfo, getUserDeviceIds } from "../../../../src/utils/crypto/deviceInfo"; -import { getMockClientWithEventEmitter, mockClientMethodsCrypto } from "../../../test-utils"; +import { vi, describe, it, expect, beforeEach, type Mocked } from "vitest"; +import { type Device, type MatrixClient } from "matrix-js-sdk/src/matrix"; +import { getMockClientWithEventEmitter, mockClientMethodsCrypto } from "test-utils"; + +import { getDeviceCryptoInfo, getUserDeviceIds } from "./deviceInfo"; describe("getDeviceCryptoInfo()", () => { let mockClient: Mocked; @@ -20,23 +22,23 @@ describe("getDeviceCryptoInfo()", () => { }); it("should return undefined on clients with no crypto", async () => { - jest.spyOn(mockClient, "getCrypto").mockReturnValue(undefined); + vi.spyOn(mockClient, "getCrypto").mockReturnValue(undefined); await expect(getDeviceCryptoInfo(mockClient, "@user:id", "device_id")).resolves.toBeUndefined(); }); it("should return undefined for unknown users", async () => { - mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map()); + vi.mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map()); await expect(getDeviceCryptoInfo(mockClient, "@user:id", "device_id")).resolves.toBeUndefined(); }); it("should return undefined for unknown devices", async () => { - mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map([["@user:id", new Map()]])); + vi.mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map([["@user:id", new Map()]])); await expect(getDeviceCryptoInfo(mockClient, "@user:id", "device_id")).resolves.toBeUndefined(); }); it("should return the right result for known devices", async () => { const mockDevice = { deviceId: "device_id" } as Device; - mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue( + vi.mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue( new Map([["@user:id", new Map([["device_id", mockDevice]])]]), ); await expect(getDeviceCryptoInfo(mockClient, "@user:id", "device_id")).resolves.toBe(mockDevice); @@ -52,18 +54,18 @@ describe("getUserDeviceIds", () => { }); it("should return empty set on clients with no crypto", async () => { - jest.spyOn(mockClient, "getCrypto").mockReturnValue(undefined); + vi.spyOn(mockClient, "getCrypto").mockReturnValue(undefined); await expect(getUserDeviceIds(mockClient, "@user:id")).resolves.toEqual(new Set()); }); it("should return empty set for unknown users", async () => { - mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map()); + vi.mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue(new Map()); await expect(getUserDeviceIds(mockClient, "@user:id")).resolves.toEqual(new Set()); }); it("should return the right result for known users", async () => { const mockDevice = { deviceId: "device_id" } as Device; - mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue( + vi.mocked(mockClient.getCrypto()!.getUserDeviceInfo).mockResolvedValue( new Map([["@user:id", new Map([["device_id", mockDevice]])]]), ); await expect(getUserDeviceIds(mockClient, "@user:id")).resolves.toEqual(new Set(["device_id"])); diff --git a/apps/web/test/unit-tests/utils/crypto/shouldForceDisableEncryption-test.ts b/apps/web/src/utils/crypto/shouldForceDisableEncryption.test.ts similarity index 87% rename from apps/web/test/unit-tests/utils/crypto/shouldForceDisableEncryption-test.ts rename to apps/web/src/utils/crypto/shouldForceDisableEncryption.test.ts index f4a3048f51..dd173bce51 100644 --- a/apps/web/test/unit-tests/utils/crypto/shouldForceDisableEncryption-test.ts +++ b/apps/web/src/utils/crypto/shouldForceDisableEncryption.test.ts @@ -6,12 +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 { shouldForceDisableEncryption } from "../../../../src/utils/crypto/shouldForceDisableEncryption"; -import { getMockClientWithEventEmitter } from "../../../test-utils"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach } from "vitest"; +import { getMockClientWithEventEmitter } from "test-utils"; + +import { shouldForceDisableEncryption } from "./shouldForceDisableEncryption"; describe("shouldForceDisableEncryption()", () => { const mockClient = getMockClientWithEventEmitter({ - getClientWellKnown: jest.fn(), + getClientWellKnown: vi.fn(), }); beforeEach(() => { diff --git a/apps/web/test/unit-tests/utils/device/clientInformation-test.ts b/apps/web/src/utils/device/clientInformation.test.ts similarity index 84% rename from apps/web/test/unit-tests/utils/device/clientInformation-test.ts rename to apps/web/src/utils/device/clientInformation.test.ts index 18478dbdaf..e79ce79fad 100644 --- a/apps/web/test/unit-tests/utils/device/clientInformation-test.ts +++ b/apps/web/src/utils/device/clientInformation.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 { MatrixEvent } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import type BasePlatform from "../../../../src/BasePlatform"; -import { type IConfigOptions } from "../../../../src/IConfigOptions"; -import { getDeviceClientInformation, recordClientInformation } from "../../../../src/utils/device/clientInformation"; -import { getMockClientWithEventEmitter } from "../../../test-utils"; -import { DEFAULTS } from "../../../../src/SdkConfig"; -import { type DeepReadonly } from "../../../../src/@types/common"; +import { vi, describe, it, expect, afterAll, beforeEach } from "vitest"; +import { MatrixEvent } from "matrix-js-sdk/src/matrix"; +import { getMockClientWithEventEmitter } from "test-utils"; + +import type BasePlatform from "../../BasePlatform"; +import { type IConfigOptions } from "../../IConfigOptions"; +import { getDeviceClientInformation, recordClientInformation } from "./clientInformation"; +import { DEFAULTS } from "../../SdkConfig"; +import { type DeepReadonly } from "../../@types/common"; describe("recordClientInformation()", () => { const deviceId = "my-device-id"; @@ -21,8 +24,8 @@ describe("recordClientInformation()", () => { const isElectron = window.electron; const mockClient = getMockClientWithEventEmitter({ - getDeviceId: jest.fn().mockReturnValue(deviceId), - setAccountData: jest.fn(), + getDeviceId: vi.fn().mockReturnValue(deviceId), + setAccountData: vi.fn(), }); const sdkConfig: DeepReadonly = { @@ -32,11 +35,11 @@ describe("recordClientInformation()", () => { }; const platform = { - getAppVersion: jest.fn().mockResolvedValue(version), + getAppVersion: vi.fn().mockResolvedValue(version), } as unknown as BasePlatform; beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); window.electron = undefined; }); @@ -72,11 +75,11 @@ describe("getDeviceClientInformation()", () => { const deviceId = "my-device-id"; const mockClient = getMockClientWithEventEmitter({ - getAccountData: jest.fn(), + getAccountData: vi.fn(), }); beforeEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); }); it("returns an empty object when no event exists for the device", () => { diff --git a/apps/web/test/unit-tests/utils/device/parseUserAgent-test.ts b/apps/web/src/utils/device/parseUserAgent.test.ts similarity index 98% rename from apps/web/test/unit-tests/utils/device/parseUserAgent-test.ts rename to apps/web/src/utils/device/parseUserAgent.test.ts index 87f27031cb..1c7b080843 100644 --- a/apps/web/test/unit-tests/utils/device/parseUserAgent-test.ts +++ b/apps/web/src/utils/device/parseUserAgent.test.ts @@ -6,11 +6,9 @@ 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 { - DeviceType, - type ExtendedDeviceInformation, - parseUserAgent, -} from "../../../../src/utils/device/parseUserAgent"; +import { describe, it, expect } from "vitest"; + +import { DeviceType, type ExtendedDeviceInformation, parseUserAgent } from "./parseUserAgent"; const makeDeviceExtendedInfo = ( deviceType: DeviceType, diff --git a/apps/web/test/unit-tests/utils/device/snoozeBulkUnverifiedDeviceReminder-test.ts b/apps/web/src/utils/device/snoozeBulkUnverifiedDeviceReminder.test.ts similarity index 83% rename from apps/web/test/unit-tests/utils/device/snoozeBulkUnverifiedDeviceReminder-test.ts rename to apps/web/src/utils/device/snoozeBulkUnverifiedDeviceReminder.test.ts index 268176df29..1a6e8430ee 100644 --- a/apps/web/test/unit-tests/utils/device/snoozeBulkUnverifiedDeviceReminder-test.ts +++ b/apps/web/src/utils/device/snoozeBulkUnverifiedDeviceReminder.test.ts @@ -6,19 +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. */ +// @vitest-environment happy-dom + +import { vi, describe, it, expect, afterAll, beforeEach } from "vitest"; import { logger } from "matrix-js-sdk/src/logger"; import { isBulkUnverifiedDeviceReminderSnoozed, snoozeBulkUnverifiedDeviceReminder, -} from "../../../../src/utils/device/snoozeBulkUnverifiedDeviceReminder"; +} from "./snoozeBulkUnverifiedDeviceReminder"; const SNOOZE_KEY = "mx_snooze_bulk_unverified_device_nag"; describe("snooze bulk unverified device nag", () => { - const localStorageSetSpy = jest.spyOn(localStorage.__proto__, "setItem"); - const localStorageGetSpy = jest.spyOn(localStorage.__proto__, "getItem"); - const localStorageRemoveSpy = jest.spyOn(localStorage.__proto__, "removeItem"); + const localStorageSetSpy = vi.spyOn(localStorage.__proto__, "setItem"); + const localStorageGetSpy = vi.spyOn(localStorage.__proto__, "getItem"); + const localStorageRemoveSpy = vi.spyOn(localStorage.__proto__, "removeItem"); // 14.03.2022 16:15 const now = 1647270879403; @@ -28,11 +31,11 @@ describe("snooze bulk unverified device nag", () => { localStorageGetSpy.mockClear().mockReturnValue(null); localStorageRemoveSpy.mockClear().mockImplementation(() => {}); - jest.spyOn(Date, "now").mockReturnValue(now); + vi.spyOn(Date, "now").mockReturnValue(now); }); afterAll(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); describe("snoozeBulkUnverifiedDeviceReminder()", () => { @@ -43,7 +46,7 @@ describe("snooze bulk unverified device nag", () => { }); it("catches an error from localstorage", () => { - const loggerErrorSpy = jest.spyOn(logger, "error"); + const loggerErrorSpy = vi.spyOn(logger, "error"); localStorageSetSpy.mockImplementation(() => { throw new Error("oups"); }); @@ -60,7 +63,7 @@ describe("snooze bulk unverified device nag", () => { }); it("catches an error from localstorage and returns false", () => { - const loggerErrorSpy = jest.spyOn(logger, "error"); + const loggerErrorSpy = vi.spyOn(logger, "error"); localStorageGetSpy.mockImplementation(() => { throw new Error("oups"); }); diff --git a/apps/web/test/unit-tests/utils/localRoom/isLocalRoom-test.ts b/apps/web/src/utils/localRoom/isLocalRoom.test.ts similarity index 80% rename from apps/web/test/unit-tests/utils/localRoom/isLocalRoom-test.ts rename to apps/web/src/utils/localRoom/isLocalRoom.test.ts index 2d11f4e523..f03f69033c 100644 --- a/apps/web/test/unit-tests/utils/localRoom/isLocalRoom-test.ts +++ b/apps/web/src/utils/localRoom/isLocalRoom.test.ts @@ -6,11 +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. */ -import { Room } from "matrix-js-sdk/src/matrix"; +// @vitest-environment happy-dom -import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../../../src/models/LocalRoom"; -import { isLocalRoom } from "../../../../src/utils/localRoom/isLocalRoom"; -import { createTestClient } from "../../../test-utils"; +import { describe, it, expect, beforeEach } from "vitest"; +import { Room } from "matrix-js-sdk/src/matrix"; +import { createTestClient } from "test-utils"; + +import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../models/LocalRoom"; +import { isLocalRoom } from "./isLocalRoom"; describe("isLocalRoom", () => { let room: Room; diff --git a/apps/web/test/unit-tests/utils/localRoom/isRoomReady-test.ts b/apps/web/src/utils/localRoom/isRoomReady.test.ts similarity index 91% rename from apps/web/test/unit-tests/utils/localRoom/isRoomReady-test.ts rename to apps/web/src/utils/localRoom/isRoomReady.test.ts index d257f1e2a2..2da89c7bdb 100644 --- a/apps/web/test/unit-tests/utils/localRoom/isRoomReady-test.ts +++ b/apps/web/src/utils/localRoom/isRoomReady.test.ts @@ -6,14 +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 { mocked } from "jest-mock"; +// @vitest-environment happy-dom + +import { vi, describe, it, expect, beforeEach } from "vitest"; import { EventType, type MatrixClient, Room } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; +import { createTestClient, makeMembershipEvent, mkEvent } from "test-utils"; -import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../../../src/models/LocalRoom"; -import { DirectoryMember } from "../../../../src/utils/direct-messages"; -import { isRoomReady } from "../../../../src/utils/localRoom/isRoomReady"; -import { createTestClient, makeMembershipEvent, mkEvent } from "../../../test-utils"; +import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../models/LocalRoom"; +import { DirectoryMember } from "../direct-messages"; +import { isRoomReady } from "./isRoomReady"; describe("isRoomReady", () => { const userId1 = "@user1:example.com"; @@ -41,7 +43,7 @@ describe("isRoomReady", () => { describe("for a room with an actual room id", () => { beforeEach(() => { localRoom.actualRoomId = room1.roomId; - mocked(client.getRoom).mockReturnValue(null); + vi.mocked(client.getRoom).mockReturnValue(null); }); it("should return false", () => { @@ -50,7 +52,7 @@ describe("isRoomReady", () => { describe("and the room is known to the client", () => { beforeEach(() => { - mocked(client.getRoom).mockImplementation((roomId: string) => { + vi.mocked(client.getRoom).mockImplementation((roomId?: string) => { if (roomId === room1.roomId) return room1; return null; }); diff --git a/apps/web/test/setup/adapter.ts b/apps/web/test/setup/adapter.ts index 13d892bac3..40b6ea9328 100644 --- a/apps/web/test/setup/adapter.ts +++ b/apps/web/test/setup/adapter.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { vi } from "vitest"; import { mocked as jestMocked } from "jest-mock"; -const isJest = typeof jest !== "undefined"; +export const isJest = typeof jest !== "undefined"; /** * Subset of the vitest API surface, with jest equivalents for the same functions when running under jest. diff --git a/apps/web/test/test-utils/beacon.ts b/apps/web/test/test-utils/beacon.ts index 71e748926c..54a0b825fc 100644 --- a/apps/web/test/test-utils/beacon.ts +++ b/apps/web/test/test-utils/beacon.ts @@ -20,6 +20,7 @@ import { import { getMockGeolocationPositionError } from "./location"; import { makeRoomWithStateEvents } from "./room"; +import { vi, isJest } from "../setup/adapter.ts"; type InfoContentProps = { timeout: number; @@ -132,14 +133,18 @@ export const makeGeolocationPosition = ({ */ export const mockGeolocation = (): MockedObject => { const mockGeolocation = { - clearWatch: jest.fn(), - getCurrentPosition: jest.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))), - watchPosition: jest.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))), + clearWatch: vi.fn(), + getCurrentPosition: vi.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))), + watchPosition: vi.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))), } as unknown as MockedObject; // jest jsdom does not provide geolocation - // @ts-ignore illegal assignment to readonly property - navigator.geolocation = mockGeolocation; + if (isJest) { + // @ts-ignore illegal assignment to readonly property + navigator.geolocation = mockGeolocation; + } else { + vi.spyOn(navigator, "geolocation", "get").mockReturnValue(mockGeolocation); + } return mockGeolocation; }; diff --git a/apps/web/vitest.config.ts b/apps/web/vitest.config.ts index 70cab9943f..9676745a69 100644 --- a/apps/web/vitest.config.ts +++ b/apps/web/vitest.config.ts @@ -43,5 +43,10 @@ export default defineProject({ pool: "threads", globals: false, setupFiles: ["src/test/setupTests.ts"], + environmentOptions: { + happyDOM: { + url: "http://localhost/", + }, + }, }, });