Rewrite tons of tests

This commit is contained in:
Half-Shot
2025-04-10 16:49:52 +01:00
parent b66e024f1f
commit 806f5bee79
13 changed files with 441 additions and 68 deletions

View File

@@ -0,0 +1,129 @@
/*
Copyright 2024, 2025 New Vector Ltd.
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import * as fs from "node:fs";
import { type EventType, type MsgType } from "matrix-js-sdk/src/types";
import { JoinRule } from "matrix-js-sdk/src/matrix";
import type { Locator, Page } from "@playwright/test";
import { test, expect } from "../../element-web-test";
import { Bot } from "../../pages/bot";
const ROOM_NAME = "Test room";
const OLD_NAME = "Alan";
const MEDIA_FILE = fs.readFileSync("playwright/sample-files/riot.png");
test.describe("Media preview settings", () => {
test.use({
displayName: OLD_NAME,
room: async ({ app, page, homeserver, bot, user }, use) => {
const mxc = (await bot.uploadContent(MEDIA_FILE, { name: "image.png", type: "image/png" })).content_uri;
const roomId = await bot.createRoom({
name: ROOM_NAME,
invite: [user.userId],
initial_state: [{ type: "m.room.avatar", content: { url: mxc }, state_key: "" }],
});
await bot.sendEvent(roomId, null, "m.room.message" as EventType, {
msgtype: "m.image" as MsgType,
body: "image.png",
url: mxc,
});
await use({ roomId });
},
});
test("should be able to hide avatars of inviters", { tag: "@screenshot" }, async ({ page, app, room, user }) => {
let settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Hide avatars of room and inviter").click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
expect(page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" })).toMatchScreenshot(
"invite-no-avatar.png",
);
expect(
page.getByRole("tree", { name: "Rooms" }).getByRole("treeitem", { name: "Test room" }),
).toMatchScreenshot("invite-room-tree-no-avatar.png");
// And then go back to being visible
settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Hide avatars of room and inviter").click();
await app.closeDialog();
await page.goto("#/home");
await app.viewRoomById(room.roomId);
expect(page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" })).toMatchScreenshot(
"invite-with-avatar.png",
);
expect(
page.getByRole("tree", { name: "Rooms" }).getByRole("treeitem", { name: "Test room" }),
).toMatchScreenshot("invite-room-tree-with-avatar.png");
});
test("should be able to hide media in rooms globally", async ({ page, app, room, user }) => {
const settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always hide" }).click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
await page.getByRole("button", { name: "Accept" }).click();
await expect(page.getByText("Show image")).toBeVisible();
});
test("should be able to hide media in non-private rooms globally", async ({ page, app, room, user, bot }) => {
await bot.sendStateEvent(room.roomId, "m.room.join_rules", {
join_rule: "public",
});
const settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Show media in timeline").getByLabel("In private rooms").click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
await page.getByRole("button", { name: "Accept" }).click();
await expect(page.getByText("Show image")).toBeVisible();
for (const joinRule of [JoinRule.Invite, JoinRule.Knock, JoinRule.Restricted]) {
await bot.sendStateEvent(room.roomId, "m.room.join_rules", {
join_rule: joinRule,
});
await expect(page.getByText("Show image")).not.toBeVisible();
}
});
test("should be able to show media in rooms globally", async ({ page, app, room, user }) => {
const settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always show" }).click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
await page.getByRole("button", { name: "Accept" }).click();
await expect(page.getByText("Show image")).not.toBeVisible();
});
test("should be able to hide media in an individual room", async ({ page, app, room, user }) => {
const settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always show" }).click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
await page.getByRole("button", { name: "Accept" }).click();
const roomSettings = await app.settings.openRoomSettings("General");
await roomSettings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always hide" }).click();
await app.closeDialog();
await expect(page.getByText("Show image")).toBeVisible();
});
test("should be able to show media in an individual room", async ({ page, app, room, user }) => {
const settings = await app.settings.openUserSettings("Preferences");
await settings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always hide" }).click();
await app.closeDialog();
await app.viewRoomById(room.roomId);
await page.getByRole("button", { name: "Accept" }).click();
const roomSettings = await app.settings.openRoomSettings("General");
await roomSettings.getByLabel("Show media in timeline").getByRole("radio", { name: "Always show" }).click();
await app.closeDialog();
await expect(page.getByText("Show image")).not.toBeVisible();
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -22,6 +22,7 @@ import { SettingsSubsection } from "../../shared/SettingsSubsection";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import { UrlPreviewSettings } from "../../../room_settings/UrlPreviewSettings";
import { MediaPreviewAccountSettings } from "../user/MediaPreviewSetting";
interface IProps {
room: Room;
@@ -92,6 +93,7 @@ export default class GeneralRoomSettingsTab extends React.Component<IProps, ISta
<SettingsSection heading={_t("room_settings|general|other_section")}>
{urlPreviewSettings}
<MediaPreviewAccountSettings roomId={room.roomId} />
{leaveSection}
</SettingsSection>
</SettingsTab>

View File

@@ -15,19 +15,30 @@ import { useSettingValue } from "../../../../../hooks/useSettings";
import SettingsStore from "../../../../../settings/SettingsStore";
import { SettingLevel } from "../../../../../settings/SettingLevel";
export const MediaPreviewAccountSettings: React.FC = () => {
const currentMediaPreview = useSettingValue("mediaPreviewConfig");
export const MediaPreviewAccountSettings: React.FC<{ roomId?: string }> = ({ roomId }) => {
const currentMediaPreview = useSettingValue("mediaPreviewConfig", roomId);
const changeSetting = useCallback(
(newValue: MediaPreviewConfig) => {
SettingsStore.setValue(
"mediaPreviewConfig",
roomId ?? null,
roomId ? SettingLevel.ROOM_ACCOUNT : SettingLevel.ACCOUNT,
newValue,
);
},
[roomId],
);
const avatarOnChange = useCallback(
(c: boolean) => {
const newValue = {
changeSetting({
...currentMediaPreview,
// Switch is inverted. "Hide avatars..."
invite_avatars: c ? MediaPreviewValue.Off : MediaPreviewValue.On,
} satisfies MediaPreviewConfig;
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, newValue);
});
},
[currentMediaPreview],
[changeSetting, currentMediaPreview],
);
const mediaPreviewOnChangeOff = useCallback<ChangeEventHandler<HTMLInputElement>>(
@@ -35,12 +46,12 @@ export const MediaPreviewAccountSettings: React.FC = () => {
if (!event.target.checked) {
return;
}
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
changeSetting({
...currentMediaPreview,
media_previews: MediaPreviewValue.Off,
} satisfies MediaPreviewConfig);
});
},
[currentMediaPreview],
[changeSetting, currentMediaPreview],
);
const mediaPreviewOnChangePrivate = useCallback<ChangeEventHandler<HTMLInputElement>>(
@@ -48,12 +59,12 @@ export const MediaPreviewAccountSettings: React.FC = () => {
if (!event.target.checked) {
return;
}
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
changeSetting({
...currentMediaPreview,
media_previews: MediaPreviewValue.Private,
} satisfies MediaPreviewConfig);
});
},
[currentMediaPreview],
[changeSetting, currentMediaPreview],
);
const mediaPreviewOnChangeOn = useCallback<ChangeEventHandler<HTMLInputElement>>(
@@ -61,56 +72,71 @@ export const MediaPreviewAccountSettings: React.FC = () => {
if (!event.target.checked) {
return;
}
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
changeSetting({
...currentMediaPreview,
media_previews: MediaPreviewValue.On,
} satisfies MediaPreviewConfig);
});
},
[currentMediaPreview],
[changeSetting, currentMediaPreview],
);
return (
<Root>
<LabelledToggleSwitch
label={_t("settings|media_preview|hide_avatars")}
value={currentMediaPreview.invite_avatars === MediaPreviewValue.Off}
onChange={avatarOnChange}
/>
<Field role="radiogroup" name="media_previews">
{!roomId && (
<LabelledToggleSwitch
label={_t("settings|media_preview|hide_avatars")}
value={currentMediaPreview.invite_avatars === MediaPreviewValue.Off}
onChange={avatarOnChange}
/>
)}
{/* Explict label here because htmlFor is not supported for linking to radiogroups */}
<Field
id="mx_media_previews"
role="radiogroup"
name="media_previews"
aria-label={_t("settings|media_preview|media_preview_label")}
>
<Label>{_t("settings|media_preview|media_preview_label")}</Label>
<HelpMessage>{_t("settings|media_preview|media_preview_description")}</HelpMessage>
<InlineField
name="media_preview_off"
control={
<RadioInput
id="mx_media_previews_off"
checked={currentMediaPreview.media_previews === MediaPreviewValue.Off}
onChange={mediaPreviewOnChangeOff}
/>
}
>
<Label>{_t("settings|media_preview|hide_media")}</Label>
</InlineField>
<InlineField
name="media_preview_private"
control={
<RadioInput
checked={currentMediaPreview.media_previews === MediaPreviewValue.Private}
onChange={mediaPreviewOnChangePrivate}
/>
}
>
<Label>{_t("settings|media_preview|show_in_private")}</Label>
<Label htmlFor="mx_media_previews_off">{_t("settings|media_preview|hide_media")}</Label>
</InlineField>
{!roomId && (
<InlineField
name="mx_media_previews_private"
control={
<RadioInput
id="mx_media_previews_private"
checked={currentMediaPreview.media_previews === MediaPreviewValue.Private}
onChange={mediaPreviewOnChangePrivate}
/>
}
>
<Label htmlFor="mx_media_previews_private">
{_t("settings|media_preview|show_in_private")}
</Label>
</InlineField>
)}
<InlineField
name="media_preview_on"
control={
<RadioInput
id="mx_media_previews_on"
checked={currentMediaPreview.media_previews === MediaPreviewValue.On}
onChange={mediaPreviewOnChangeOn}
/>
}
>
<Label>{_t("settings|media_preview|show_media")}</Label>
<Label htmlFor="mx_media_previews_on">{_t("settings|media_preview|show_media")}</Label>
</InlineField>
</Field>
</Root>

View File

@@ -0,0 +1,30 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { useEffect, useState } from "react";
import { EventType, type MatrixEvent, type Room, RoomStateEvent, type JoinRule } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { useTypedEventEmitter } from "../useEventEmitter";
/**
* Helper to retrieve the join rules for given room
* @param room
* @returns the current join rule
*/
export function useJoinRule(room?: Room): Optional<JoinRule> {
const [topic, setJoinRule] = useState(room?.getJoinRule());
useTypedEventEmitter(room?.currentState, RoomStateEvent.Events, (ev: MatrixEvent) => {
if (ev.getType() !== EventType.RoomJoinRules) return;
setJoinRule(room?.getJoinRule());
});
useEffect(() => {
setJoinRule(room?.getJoinRule());
}, [room]);
return topic;
}

View File

@@ -0,0 +1,30 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { useEffect, useState } from "react";
import { EventType, type MatrixEvent, type Room, RoomStateEvent } from "matrix-js-sdk/src/matrix";
import { type Optional } from "matrix-events-sdk";
import { useTypedEventEmitter } from "../useEventEmitter";
/**
* Helper to retrieve the avatar for given room
* @param room
* @returns the current avatar
*/
export function useRoomAvatar(room?: Room): Optional<string> {
const [topic, setAvatar] = useState(room?.getMxcAvatarUrl());
useTypedEventEmitter(room?.currentState, RoomStateEvent.Events, (ev: MatrixEvent) => {
if (ev.getType() !== EventType.RoomAvatar) return;
setAvatar(room?.getMxcAvatarUrl());
});
useEffect(() => {
setAvatar(room?.getMxcAvatarUrl());
}, [room]);
return topic;
}

View File

@@ -5,7 +5,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 { useCallback, useMemo } from "react";
import { useCallback } from "react";
import { JoinRule } from "matrix-js-sdk/src/matrix";
import { SettingLevel } from "../settings/SettingLevel";
@@ -13,6 +13,7 @@ import { useSettingValue } from "./useSettings";
import SettingsStore from "../settings/SettingsStore";
import { useMatrixClientContext } from "../contexts/MatrixClientContext";
import { MediaPreviewValue } from "../@types/media_preview";
import { useJoinRule } from "./room/useJoinRule";
const PRIVATE_JOIN_RULES: JoinRule[] = [JoinRule.Invite, JoinRule.Knock, JoinRule.Restricted];
@@ -25,6 +26,7 @@ export function useMediaVisible(eventId: string, roomId: string): [boolean, (vis
const mediaPreviewSetting = useSettingValue("mediaPreviewConfig", roomId);
const client = useMatrixClientContext();
const eventVisibility = useSettingValue("showMediaEventIds");
const joinRule = useJoinRule(client.getRoom(roomId) ?? undefined);
const setMediaVisible = useCallback(
(visible: boolean) => {
SettingsStore.setValue("showMediaEventIds", null, SettingLevel.DEVICE, {
@@ -35,15 +37,7 @@ export function useMediaVisible(eventId: string, roomId: string): [boolean, (vis
[eventId, eventVisibility],
);
const roomIsPrivate = useMemo(() => {
const joinRule = client?.getRoom(roomId)?.getJoinRule();
if (PRIVATE_JOIN_RULES.includes(joinRule as JoinRule)) {
return true;
} else {
// All other join rules, and unknown will default to hiding.
return false;
}
}, [client, roomId]);
const roomIsPrivate = joinRule ? PRIVATE_JOIN_RULES.includes(joinRule) : false;
const explicitEventVisiblity = eventVisibility[eventId];
// Always prefer the explicit per-event user preference here.

View File

@@ -374,10 +374,6 @@ export default class SettingsStore {
roomId: string | null = null,
excludeDefault = false,
): Settings[S]["default"] | undefined {
if (settingName === "mediaPreviewConfig") {
console.log("GET VALUE", SETTINGS[settingName]);
}
// Verify that the setting is actually a setting
if (!SETTINGS[settingName]) {
throw new Error("Setting '" + settingName + "' does not appear to be a setting.");

View File

@@ -5,7 +5,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 { ClientEvent, type MatrixEvent, type MatrixClient, IContent } from "matrix-js-sdk/src/matrix";
import { type IContent } from "matrix-js-sdk/src/matrix";
import { type AccountDataEvents } from "matrix-js-sdk/src/types";
import {
@@ -31,16 +31,22 @@ export default class MediaPreviewConfigController extends MatrixClientBackedCont
const inviteAvatars: MediaPreviewValue = content.invite_avatars;
const validValues = Object.values(MediaPreviewValue);
return {
invite_avatars: validValues.includes(inviteAvatars) ? inviteAvatars : MediaPreviewConfigController.default.invite_avatars,
media_previews: validValues.includes(mediaPreviews) ? mediaPreviews : MediaPreviewConfigController.default.media_previews,
invite_avatars: validValues.includes(inviteAvatars)
? inviteAvatars
: MediaPreviewConfigController.default.invite_avatars,
media_previews: validValues.includes(mediaPreviews)
? mediaPreviews
: MediaPreviewConfigController.default.media_previews,
};
}
public constructor() {
super();
}
private getValue = (roomId?: string): MediaPreviewConfig | null => {
const source = roomId ? this.client?.getRoom(roomId) : this.client;
const value = source
?.getAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE)
?.getContent<MediaPreviewConfig>();
const value = source?.getAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE)?.getContent<MediaPreviewConfig>();
if (!value) {
return null;
@@ -49,20 +55,17 @@ export default class MediaPreviewConfigController extends MatrixClientBackedCont
}
};
protected async initMatrixClient(newClient: MatrixClient, oldClient?: MatrixClient): Promise<void> {
protected async initMatrixClient(): Promise<void> {
// Unused
}
public getValueOverride(_level: SettingLevel, roomId: string | null): MediaPreviewConfig {
if (roomId) {
// Use globals for any undefined setting
return {
...this.getRoomValue(roomId),
...this.globalSetting,
};
const roomConfig = roomId && this.getValue(roomId);
if (roomConfig) {
return roomConfig;
}
return this.globalSetting;
// If no room config, or global settings request then return global.
return this.getValue() ?? MediaPreviewConfigController.default;
}
public get settingDisabled(): false {
@@ -79,9 +82,7 @@ export default class MediaPreviewConfigController extends MatrixClientBackedCont
return false;
}
if (roomId) {
await this.client.setRoomAccountData(roomId, MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, {
value: newValue,
});
await this.client.setRoomAccountData(roomId, MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, newValue);
return true;
}
await this.client.setAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, newValue);

View File

@@ -0,0 +1,165 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2024 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import MatrixClientBackedController from "../../../../src/settings/controllers/MatrixClientBackedController";
import MediaPreviewConfigController from "../../../../src/settings/controllers/MediaPreviewConfigController";
import { SettingLevel } from "../../../../src/settings/SettingLevel";
import { getMockClientWithEventEmitter, mockClientMethodsServer } from "../../../test-utils";
import { MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, MediaPreviewValue } from "../../../../src/@types/media_preview";
describe("MediaPreviewConfigController", () => {
afterEach(() => {
jest.restoreAllMocks();
});
const ROOM_ID = "!room:example.org";
it("gets the default settings when none are specified.", () => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest.fn().mockReturnValue(null),
});
const value = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(value).toEqual(MediaPreviewConfigController.default);
});
it("gets the default settings when the setting is empty.", () => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest
.fn()
.mockReturnValue(new MatrixEvent({ type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, content: {} })),
});
const value = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(value).toEqual(MediaPreviewConfigController.default);
});
it.each([["media_previews"], ["invite_avatars"]])("gets the correct value for %s at the global level", (key) => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest.fn().mockReturnValue(
new MatrixEvent({
type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
content: {
[key]: MediaPreviewValue.Private,
},
}),
),
getRoom: jest.fn().mockReturnValue({
getAccountData: jest.fn().mockReturnValue(null),
}),
});
const globalValue = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(globalValue[key]).toEqual(MediaPreviewValue.Private);
// Should follow the global value.
const roomValue = controller.getValueOverride(SettingLevel.ROOM_ACCOUNT, ROOM_ID);
expect(roomValue[key]).toEqual(MediaPreviewValue.Private);
});
it.each([["media_previews"], ["invite_avatars"]])("gets the correct value for %s at the room level", (key) => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest.fn().mockReturnValue(null),
getRoom: jest.fn().mockReturnValue({
getAccountData: jest.fn().mockReturnValue(
new MatrixEvent({
type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
content: {
[key]: MediaPreviewValue.Private,
},
}),
),
}),
});
const globalValue = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(globalValue[key]).toEqual(MediaPreviewValue.On);
// Should follow the global value.
const roomValue = controller.getValueOverride(SettingLevel.ROOM_ACCOUNT, ROOM_ID);
expect(roomValue[key]).toEqual(MediaPreviewValue.Private);
});
it.each([["media_previews"], ["invite_avatars"]])(
"uses defaults when an invalid value is set on the global level",
(key) => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest.fn().mockReturnValue(
new MatrixEvent({
type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
content: {
[key]: "bibble",
},
}),
),
getRoom: jest.fn().mockReturnValue({
getAccountData: jest.fn().mockReturnValue(null),
}),
});
const globalValue = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(globalValue[key]).toEqual(MediaPreviewValue.On);
// Should follow the global value.
const roomValue = controller.getValueOverride(SettingLevel.ROOM_ACCOUNT, ROOM_ID);
expect(roomValue[key]).toEqual(MediaPreviewValue.On);
},
);
it.each([["media_previews"], ["invite_avatars"]])(
"uses global value when an invalid value is set on the room level",
(key) => {
const controller = new MediaPreviewConfigController();
MatrixClientBackedController.matrixClient = getMockClientWithEventEmitter({
...mockClientMethodsServer(),
getAccountData: jest.fn().mockReturnValue(
new MatrixEvent({
type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
content: {
[key]: MediaPreviewValue.Private,
},
}),
),
getRoom: jest.fn().mockReturnValue({
getAccountData: jest.fn().mockReturnValue(
new MatrixEvent({
type: MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
content: {
[key]: "bibble",
},
}),
),
}),
});
const globalValue = controller.getValueOverride(SettingLevel.ACCOUNT, null);
expect(globalValue[key]).toEqual(MediaPreviewValue.Private);
// Should follow the global value.
const roomValue = controller.getValueOverride(SettingLevel.ROOM_ACCOUNT, ROOM_ID);
expect(roomValue[key]).toEqual(MediaPreviewValue.On);
},
);
});