Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,16 @@ describe("MessageComposerUrlPreview", () => {
(text) => text === "show-fake-preview",
() => <strong>Fake preview</strong>,
);
const { container, getByText, rerender } = wrapComponent(
const { container, getByText, queryByText, rerender } = wrapComponent(
<MessageComposerUrlPreviewWrapper content="show-fake-preview" moduleApi={modApi} />,
);
await waitFor(
() => {
expect(getByText("Fake preview")).toBeDefined();
},
{ timeout: DEBOUNCE_REQUEST_TIMEOUT_MS },
);
await waitFor(() => {
expect(getByText("Fake preview")).toBeDefined();
});
rerender(<MessageComposerUrlPreviewWrapper content="other-text" moduleApi={modApi} />);
await waitFor(
() => {
expect(container).toMatchInlineSnapshot(`<div />`);
},
{ timeout: DEBOUNCE_REQUEST_TIMEOUT_MS },
);
await waitFor(() => {
expect(queryByText("Fake preview")).toBeNull();
});
expect(container).toMatchInlineSnapshot(`<div />`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +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 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,
MessageEventFactory,
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";

Expand Down Expand Up @@ -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;
});
Expand Down Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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");
});
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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()!,
Expand All @@ -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",
Expand Down Expand Up @@ -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"];

Expand All @@ -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();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@
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", () => {
Expand All @@ -41,7 +44,7 @@
it("returns null for a poll start event", () => {
const pollStartEvent = makePollStartEvent("test?", userId);

expect(getForwardableEvent(pollStartEvent, client)).toBe(null);

Check warning on line 47 in apps/web/src/events/forward/getForwardableEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getForwardableEvent(pollStartEvent, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI2WrrHxBc4qECHE&open=AZ9BHI2WrrHxBc4qECHE&pullRequest=34181
});

describe("beacons", () => {
Expand All @@ -49,14 +52,14 @@
const notLiveBeacon = makeBeaconInfoEvent(userId, roomId, { isLive: false });
makeRoomWithBeacons(roomId, client, [notLiveBeacon]);

expect(getForwardableEvent(notLiveBeacon, client)).toBe(null);

Check warning on line 55 in apps/web/src/events/forward/getForwardableEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getForwardableEvent(notLiveBeacon, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI2WrrHxBc4qECHF&open=AZ9BHI2WrrHxBc4qECHF&pullRequest=34181
});

it("returns null for a live beacon that does not have a location", () => {
const liveBeacon = makeBeaconInfoEvent(userId, roomId, { isLive: true });
makeRoomWithBeacons(roomId, client, [liveBeacon]);

expect(getForwardableEvent(liveBeacon, client)).toBe(null);

Check warning on line 62 in apps/web/src/events/forward/getForwardableEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getForwardableEvent(liveBeacon, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI2WrrHxBc4qECHG&open=AZ9BHI2WrrHxBc4qECHG&pullRequest=34181
});

it("returns the latest location event for a live beacon with location", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@
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", () => {
Expand All @@ -35,7 +38,7 @@
},
});

expect(getShareableLocationEvent(alicesMessageEvent, client)).toBe(null);

Check warning on line 41 in apps/web/src/events/location/getShareableLocationEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getShareableLocationEvent(alicesMessageEvent, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI0VrrHxBc4qECHB&open=AZ9BHI0VrrHxBc4qECHB&pullRequest=34181
});

it("returns the event for a location event", () => {
Expand All @@ -49,14 +52,14 @@
const notLiveBeacon = makeBeaconInfoEvent(userId, roomId, { isLive: false });
makeRoomWithBeacons(roomId, client, [notLiveBeacon]);

expect(getShareableLocationEvent(notLiveBeacon, client)).toBe(null);

Check warning on line 55 in apps/web/src/events/location/getShareableLocationEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getShareableLocationEvent(notLiveBeacon, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI0VrrHxBc4qECHC&open=AZ9BHI0VrrHxBc4qECHC&pullRequest=34181
});

it("returns null for a live beacon that does not have a location", () => {
const liveBeacon = makeBeaconInfoEvent(userId, roomId, { isLive: true });
makeRoomWithBeacons(roomId, client, [liveBeacon]);

expect(getShareableLocationEvent(liveBeacon, client)).toBe(null);

Check warning on line 62 in apps/web/src/events/location/getShareableLocationEvent.test.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer a more specific assertion instead of this generic one, e.g. "expect(getShareableLocationEvent(liveBeacon, client)).toBeNull()".

See more on https://sonarcloud.io/project/issues?id=element-web&issues=AZ9BHI0VrrHxBc4qECHD&open=AZ9BHI0VrrHxBc4qECHD&pullRequest=34181
});

it("returns the latest location event for a live beacon with location", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Loading
Loading