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
This commit is contained in:
Michael Telatynski
2026-07-03 10:10:04 +00:00
committed by GitHub
parent 78273c569b
commit 275ea25eca
21 changed files with 195 additions and 147 deletions
@@ -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: "<arg>",
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: "<arg>",
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");
});
});
@@ -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",
@@ -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");
});
});
@@ -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 });
@@ -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 });
@@ -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);
});
});
@@ -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 () {
@@ -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";
@@ -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", () => {
@@ -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<Geolocation>;
@@ -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));
@@ -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";
@@ -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<MatrixClient>;
@@ -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"]));
@@ -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(() => {
@@ -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<IConfigOptions> = {
@@ -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", () => {
@@ -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,
@@ -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");
});
@@ -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;
@@ -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;
});
+1 -1
View File
@@ -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.
+10 -5
View File
@@ -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<Geolocation> => {
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<Geolocation>;
// 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;
};
+5
View File
@@ -43,5 +43,10 @@ export default defineProject({
pool: "threads",
globals: false,
setupFiles: ["src/test/setupTests.ts"],
environmentOptions: {
happyDOM: {
url: "http://localhost/",
},
},
},
});