Fixing tests that break settings getValue expectations

This commit is contained in:
Half-Shot
2025-04-14 09:16:11 +01:00
parent 5c5484c6b5
commit 3d49a61f88
11 changed files with 110 additions and 71 deletions

View File

@@ -430,7 +430,7 @@ export const SETTINGS: Settings = {
},
"mediaPreviewConfig": {
controller: new MediaPreviewConfigController(),
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
supportedLevels: LEVELS_ROOM_SETTINGS,
default: MediaPreviewConfigController.default,
},
"feature_report_to_moderators": {

View File

@@ -62,7 +62,11 @@ export class MockClientWithEventEmitter extends EventEmitter {
export const getMockClientWithEventEmitter = (
mockProperties: Partial<Record<keyof MatrixClient, unknown>>,
): MockedObject<MatrixClient> => {
const mock = mocked(new MockClientWithEventEmitter(mockProperties) as unknown as MatrixClient);
const mock = mocked(
new MockClientWithEventEmitter({
...mockProperties,
}) as unknown as MatrixClient,
);
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mock);
jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(mock);

View File

@@ -14,6 +14,7 @@ import parse from "html-react-parser";
import { bodyToHtml, bodyToNode, formatEmojis, topicToHtml } from "../../src/HtmlUtils";
import SettingsStore from "../../src/settings/SettingsStore";
import { getMockClientWithEventEmitter } from "../test-utils";
import { SettingLevel } from "../../src/settings/SettingLevel";
jest.mock("../../src/settings/SettingsStore");
@@ -108,7 +109,11 @@ describe("bodyToHtml", () => {
describe("feature_latex_maths", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature === "feature_latex_maths");
SettingsStore.setValue("feature_latex_maths", null, SettingLevel.ACCOUNT, true);
});
afterEach(() => {
SettingsStore.reset();
});
it("should render inline katex", () => {

View File

@@ -50,6 +50,7 @@ import SettingsStore from "../../../../src/settings/SettingsStore";
import ScrollPanel from "../../../../src/components/structures/ScrollPanel";
import defaultDispatcher from "../../../../src/dispatcher/dispatcher";
import { Action } from "../../../../src/dispatcher/actions";
import { SettingLevel } from "../../../../src/settings/SettingLevel";
// ScrollPanel calls this, but jsdom doesn't mock it for us
HTMLDivElement.prototype.scrollBy = () => {};
@@ -312,16 +313,11 @@ describe("TimelinePanel", () => {
beforeEach(async () => {
client.isVersionSupported.mockResolvedValue(true);
client.doesServerSupportUnstableFeature.mockResolvedValue(true);
jest.spyOn(SettingsStore, "getValue").mockImplementation((setting: string): any => {
if (setting === "sendReadReceipts") return false;
return undefined;
});
SettingsStore.setValue("sendReadReceipts", null, SettingLevel.ACCOUNT, false);
});
afterEach(() => {
mocked(SettingsStore.getValue).mockReset();
SettingsStore.reset();
});
it("should send a fully read marker and a private receipt", async () => {

View File

@@ -17,12 +17,12 @@ import DMRoomMap from "../../../../../src/utils/DMRoomMap";
import { LocalRoom } from "../../../../../src/models/LocalRoom";
import * as AvatarModule from "../../../../../src/Avatar";
import { DirectoryMember } from "../../../../../src/utils/direct-messages";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { MediaPreviewValue } from "../../../../../src/@types/media_preview";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { SettingLevel } from "../../../../../src/settings/SettingLevel";
describe("RoomAvatar", () => {
let client: MatrixClient;
let showAvatarsSetting: MediaPreviewValue.On | MediaPreviewValue.Off = MediaPreviewValue.On;
filterConsole(
// unrelated for this test
@@ -35,16 +35,15 @@ describe("RoomAvatar", () => {
jest.spyOn(dmRoomMap, "getUserIdForRoomId");
jest.spyOn(DMRoomMap, "shared").mockReturnValue(dmRoomMap);
jest.spyOn(AvatarModule, "defaultAvatarUrlForString");
const origFn = SettingsStore.getValue;
jest.spyOn(SettingsStore, "getValue").mockImplementation((setting, ...args) => {
if (setting === "mediaPreviewConfig") {
return { invite_avatars: showAvatarsSetting, media_previews: MediaPreviewValue.Off };
}
return origFn(setting, ...args);
});
});
afterAll(() => {
SettingsStore.setValue(
"mediaPreviewConfig",
null,
SettingLevel.ACCOUNT,
SettingsStore.getDefaultValue("mediaPreviewConfig"),
);
jest.restoreAllMocks();
});
@@ -82,7 +81,9 @@ describe("RoomAvatar", () => {
expect(render(<RoomAvatar room={room} />).container).toMatchSnapshot();
});
it("should not render an invite avatar if the user has disabled it", () => {
showAvatarsSetting = MediaPreviewValue.Off;
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
invite_avatars: MediaPreviewValue.Off,
});
const room = new Room("!room:example.com", client, client.getSafeUserId());
room.name = "test room";
room.updateMyMembership("invite");

View File

@@ -6,7 +6,7 @@ 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, { act } from "react";
import React from "react";
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from "jest-matrix-react";
import { EventType, getHttpUriForMxc, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import fetchMock from "fetch-mock-jest";
@@ -28,7 +28,6 @@ import {
} from "../../../../test-utils";
import { MediaEventHelper } from "../../../../../src/utils/MediaEventHelper";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { SettingLevel } from "../../../../../src/settings/SettingLevel";
import { MediaPreviewValue } from "../../../../../src/@types/media_preview";
jest.mock("matrix-encrypt-attachment", () => ({
@@ -88,6 +87,7 @@ describe("<MImageBody/>", () => {
});
afterEach(() => {
SettingsStore.reset();
mocked(encrypt.decryptAttachment).mockReset();
});
@@ -148,17 +148,6 @@ describe("<MImageBody/>", () => {
});
});
afterEach(() => {
act(() => {
SettingsStore.setValue(
"showMediaEventIds",
null,
SettingLevel.DEVICE,
SettingsStore.getDefaultValue("showMediaEventIds"),
);
});
});
it("should not download image", async () => {
fetchMock.getOnce(url, { status: 200 });

View File

@@ -6,7 +6,7 @@ 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, { act } from "react";
import React from "react";
import { EventType, getHttpUriForMxc, type IContent, type MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { fireEvent, render, screen, type RenderResult } from "jest-matrix-react";
import fetchMock from "fetch-mock-jest";
@@ -25,7 +25,6 @@ import {
} from "../../../../test-utils";
import MVideoBody from "../../../../../src/components/views/messages/MVideoBody";
import type { IBodyProps } from "../../../../../src/components/views/messages/IBodyProps";
import { SettingLevel } from "../../../../../src/settings/SettingLevel";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { MediaPreviewValue } from "../../../../../src/@types/media_preview";
@@ -70,6 +69,7 @@ describe("MVideoBody", () => {
room_id: "!room:server",
sender: userId,
type: EventType.RoomMessage,
event_id: "$foo:bar",
content: {
body: "alt for a test video",
info: {
@@ -114,14 +114,7 @@ describe("MVideoBody", () => {
});
afterEach(() => {
act(() => {
SettingsStore.setValue(
"showMediaEventIds",
null,
SettingLevel.DEVICE,
SettingsStore.getDefaultValue("showMediaEventIds"),
);
});
SettingsStore.reset();
jest.restoreAllMocks();
});

View File

@@ -57,6 +57,7 @@ import * as UseCall from "../../../../../../src/hooks/useCall";
import { SdkContextClass } from "../../../../../../src/contexts/SDKContext";
import WidgetStore, { type IApp } from "../../../../../../src/stores/WidgetStore";
import { UIFeature } from "../../../../../../src/settings/UIFeature";
import { SettingLevel } from "../../../../../../src/settings/SettingLevel";
jest.mock("../../../../../../src/utils/ShieldUtils");
jest.mock("../../../../../../src/hooks/right-panel/useCurrentPhase", () => ({
@@ -99,6 +100,7 @@ describe("RoomHeader", () => {
afterEach(() => {
jest.restoreAllMocks();
SettingsStore.reset();
});
it("renders the room header", () => {
@@ -187,9 +189,7 @@ describe("RoomHeader", () => {
it("opens the notifications panel", async () => {
const user = userEvent.setup();
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string): any => {
if (name === "feature_notifications") return true;
});
SettingsStore.setValue("feature_notifications", null, SettingLevel.DEVICE, true);
render(<RoomHeader room={room} />, getWrapper());
@@ -228,7 +228,15 @@ describe("RoomHeader", () => {
describe("UIFeature.Widgets enabled (default)", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
SdkConfig.put({
features: {
[UIFeature.Widgets]: true,
},
});
});
afterEach(() => {
SdkConfig.reset();
});
it("should show call buttons in a room with 2 members", () => {
@@ -248,7 +256,15 @@ describe("RoomHeader", () => {
describe("UIFeature.Widgets disabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => false);
SdkConfig.put({
features: {
[UIFeature.Widgets]: true,
},
});
});
afterEach(() => {
SdkConfig.reset();
});
it("should show call buttons in a room with 2 members", () => {
@@ -268,7 +284,15 @@ describe("RoomHeader", () => {
describe("groups call disabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
SdkConfig.put({
features: {
[UIFeature.Widgets]: true,
},
});
});
afterEach(() => {
SdkConfig.reset();
});
it("you can't call if you're alone", () => {
@@ -333,15 +357,26 @@ describe("RoomHeader", () => {
describe("group call enabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(feature) => feature === "feature_group_calls" || feature == UIFeature.Widgets,
);
SdkConfig.put({
features: {
[UIFeature.Widgets]: true,
feature_group_calls: true,
},
});
});
afterEach(() => {
SdkConfig.reset();
});
it("renders only the video call element", async () => {
const user = userEvent.setup();
mockRoomMembers(room, 3);
jest.spyOn(SdkConfig, "get").mockReturnValue({ use_exclusively: true });
SdkConfig.put({
features: {
use_exclusively: true,
},
});
// allow element calls
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
@@ -359,7 +394,11 @@ describe("RoomHeader", () => {
});
it("can't call if there's an ongoing (pinned) call", () => {
jest.spyOn(SdkConfig, "get").mockReturnValue({ use_exclusively: true });
SdkConfig.put({
features: {
use_exclusively: true,
},
});
// allow element calls
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockReturnValue(true);
@@ -377,7 +416,11 @@ describe("RoomHeader", () => {
it("clicking on ongoing (unpinned) call re-pins it", async () => {
const user = userEvent.setup();
mockRoomMembers(room, 3);
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature == UIFeature.Widgets);
SdkConfig.put({
features: {
[UIFeature.Widgets]: true,
},
});
// allow calls
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockReturnValue(false);
@@ -442,8 +485,10 @@ describe("RoomHeader", () => {
jest.spyOn(room.currentState, "maySendStateEvent").mockReturnValue(false);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
jest.spyOn(room, "canInvite").mockReturnValue(false);
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
return { guest_spa_url: "https://guest_spa_url.com", url: "https://spa_url.com" };
SdkConfig.put({
element_call: {
guest_spa_url: "https://guest_spa_url.com",
},
});
const { container: containerNoInviteNotPublic } = render(<RoomHeader room={room} />, getWrapper());
expect(queryAllByLabelText(containerNoInviteNotPublic, "There's no one here to call")).toHaveLength(2);
@@ -751,7 +796,7 @@ describe("RoomHeader", () => {
describe("ask to join enabled", () => {
it("does render the RoomKnocksBar", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((feature) => feature === "feature_ask_to_join");
SettingsStore.setValue("feature_ask_to_join", null, SettingLevel.DEVICE, true);
jest.spyOn(room, "canInvite").mockReturnValue(true);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Knock);
jest.spyOn(room, "getMembersWithMembership").mockReturnValue([new RoomMember(room.roomId, "@foo")]);

View File

@@ -37,6 +37,10 @@ describe("NotificatinSettingsTab", () => {
NotificationSettingsTab.contextType = React.createContext<MatrixClient>(cli);
});
afterEach(() => {
SettingsStore.reset();
});
it("should prevent »Settings« link click from bubbling up to radio buttons", async () => {
const tab = renderTab();

View File

@@ -9,10 +9,10 @@ import { act, renderHook, waitFor } from "jest-matrix-react";
import { JoinRule, type MatrixClient, type Room } from "matrix-js-sdk/src/matrix";
import { useMediaVisible } from "../../../src/hooks/useMediaVisible";
import SettingsStore from "../../../src/settings/SettingsStore";
import { createTestClient, mkStubRoom, withClientContextRenderOptions } from "../../test-utils";
import { type MediaPreviewConfig, MediaPreviewValue } from "../../../src/@types/media_preview";
import MediaPreviewConfigController from "../../../src/settings/controllers/MediaPreviewConfigController";
import SettingsStore from "../../../src/settings/SettingsStore";
const EVENT_ID = "$fibble:example.org";
const ROOM_ID = "!foobar:example.org";

View File

@@ -33,6 +33,7 @@ import { getMockClientWithEventEmitter } from "../../test-utils/client";
import { mkMessage, stubClient } from "../../test-utils/test-utils";
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
import { NotificationLevel } from "../../../src/stores/notifications/NotificationLevel";
import { SettingLevel } from "../../../src/settings/SettingLevel";
jest.mock("../../../src/settings/SettingsStore");
@@ -116,7 +117,11 @@ describe("notifications", () => {
const ROOM_ID = "123";
const USER_ID = "@bob:example.org";
let message: MatrixEvent;
let sendReceiptsSetting = true;
const sendReceiptsSetting = true;
afterEach(() => {
SettingsStore.reset();
});
beforeEach(() => {
stubClient();
@@ -131,9 +136,7 @@ describe("notifications", () => {
room.addLiveEvents([message], { addToState: true });
sendReadReceiptSpy = jest.spyOn(client, "sendReadReceipt").mockResolvedValue({});
jest.spyOn(client, "getRooms").mockReturnValue([room]);
jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => {
return name === "sendReadReceipts" && sendReceiptsSetting;
});
SettingsStore.setValue("sendReadReceipts", null, SettingLevel.ACCOUNT, sendReceiptsSetting);
});
it("sends a request even if everything has been read", async () => {
@@ -152,11 +155,8 @@ describe("notifications", () => {
});
describe("when sendReadReceipts setting is disabled", () => {
beforeEach(() => {
sendReceiptsSetting = false;
});
it("should send a private read receipt", async () => {
SettingsStore.setValue("sendReadReceipts", null, SettingLevel.ACCOUNT, sendReceiptsSetting);
await clearRoomNotification(room, client);
expect(sendReadReceiptSpy).toHaveBeenCalledWith(message, ReceiptType.ReadPrivate, true);
});
@@ -177,9 +177,11 @@ describe("notifications", () => {
room = new Room(ROOM_ID, client, USER_ID);
sendReadReceiptSpy = jest.spyOn(client, "sendReadReceipt").mockResolvedValue({});
jest.spyOn(client, "getRooms").mockReturnValue([room]);
jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => {
return name === "sendReadReceipts";
});
SettingsStore.setValue("sendReadReceipts", null, SettingLevel.ACCOUNT, true);
});
afterEach(() => {
SettingsStore.reset();
});
it("does not send any requests if everything has been read", () => {
@@ -212,7 +214,7 @@ describe("notifications", () => {
room.addLiveEvents([message], { addToState: true });
room.setUnreadNotificationCount(NotificationCountType.Total, 1);
jest.spyOn(SettingsStore, "getValue").mockReset().mockReturnValue(false);
SettingsStore.setValue("sendReadReceipts", null, SettingLevel.ACCOUNT, false);
await clearAllNotifications(client);