Filter settings exported when rageshaking (#30236)
* Submit filtered settings to rageshakes and sentry. * Add flag to omit some settings from being exported. * Hide user timezone * Hide recent searches and media event ids * Lint * use better wording * lint * Prevent language from being sent * Add tests to check keys are prevented from being uploaded. * don't export invite rules * Update tests
This commit is contained in:
@@ -171,7 +171,7 @@ async function collectSynapseSpecific(client: MatrixClient, body: FormData): Pro
|
|||||||
} catch {
|
} catch {
|
||||||
try {
|
try {
|
||||||
// If that fails we'll hit any endpoint and look at the server response header
|
// If that fails we'll hit any endpoint and look at the server response header
|
||||||
const res = await window.fetch(client.http.getUrl("/login"), {
|
const res = await fetch(client.http.getUrl("/login"), {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
mode: "cors",
|
mode: "cors",
|
||||||
});
|
});
|
||||||
@@ -257,7 +257,7 @@ export function collectSettings(body: FormData): void {
|
|||||||
body.append("lowBandwidth", "enabled");
|
body.append("lowBandwidth", "enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
body.append("mx_local_settings", localStorage.getItem("mx_local_settings")!);
|
body.append("mx_local_settings", SettingsStore.exportForRageshake());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ async function getCryptoContext(client: MatrixClient): Promise<CryptoContext> {
|
|||||||
function getDeviceContext(client: MatrixClient): DeviceContext {
|
function getDeviceContext(client: MatrixClient): DeviceContext {
|
||||||
const result: DeviceContext = {
|
const result: DeviceContext = {
|
||||||
device_id: client?.deviceId ?? undefined,
|
device_id: client?.deviceId ?? undefined,
|
||||||
mx_local_settings: localStorage.getItem("mx_local_settings"),
|
mx_local_settings: SettingsStore.exportForRageshake(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (window.Modernizr) {
|
if (window.Modernizr) {
|
||||||
|
|||||||
@@ -173,6 +173,11 @@ export interface IBaseSetting<T extends SettingValueType = SettingValueType> {
|
|||||||
|
|
||||||
// Whether the setting should have a warning sign in the microcopy
|
// Whether the setting should have a warning sign in the microcopy
|
||||||
shouldWarn?: boolean;
|
shouldWarn?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the setting should be exported in a rageshake report.
|
||||||
|
*/
|
||||||
|
shouldExportToRageshake?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IFeature extends Omit<IBaseSetting<boolean>, "isFeature"> {
|
export interface IFeature extends Omit<IBaseSetting<boolean>, "isFeature"> {
|
||||||
@@ -441,6 +446,8 @@ export const SETTINGS: Settings = {
|
|||||||
controller: new InviteRulesConfigController(),
|
controller: new InviteRulesConfigController(),
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: InviteRulesConfigController.default,
|
default: InviteRulesConfigController.default,
|
||||||
|
// Contains server names
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"feature_report_to_moderators": {
|
"feature_report_to_moderators": {
|
||||||
isFeature: true,
|
isFeature: true,
|
||||||
@@ -503,10 +510,14 @@ export const SETTINGS: Settings = {
|
|||||||
"mjolnirRooms": {
|
"mjolnirRooms": {
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [],
|
default: [],
|
||||||
|
// Contains room IDs
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"mjolnirPersonalRoom": {
|
"mjolnirPersonalRoom": {
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: null,
|
default: null,
|
||||||
|
// Contains room ID
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"feature_html_topic": {
|
"feature_html_topic": {
|
||||||
isFeature: true,
|
isFeature: true,
|
||||||
@@ -797,6 +808,8 @@ export const SETTINGS: Settings = {
|
|||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
displayName: _td("settings|preferences|user_timezone"),
|
displayName: _td("settings|preferences|user_timezone"),
|
||||||
default: "",
|
default: "",
|
||||||
|
// Location leak
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"userTimezonePublish": {
|
"userTimezonePublish": {
|
||||||
// This is per-device so you can avoid having devices overwrite each other.
|
// This is per-device so you can avoid having devices overwrite each other.
|
||||||
@@ -913,6 +926,8 @@ export const SETTINGS: Settings = {
|
|||||||
"custom_themes": {
|
"custom_themes": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
default: [],
|
default: [],
|
||||||
|
// Potential privacy leak via theme origin
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"use_system_theme": {
|
"use_system_theme": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
@@ -974,26 +989,36 @@ export const SETTINGS: Settings = {
|
|||||||
"language": {
|
"language": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||||
default: "en",
|
default: "en",
|
||||||
|
// For privacy
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"breadcrumb_rooms": {
|
"breadcrumb_rooms": {
|
||||||
// not really a setting
|
// not really a setting
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [],
|
default: [],
|
||||||
|
// Contains joined rooms
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"recent_emoji": {
|
"recent_emoji": {
|
||||||
// not really a setting
|
// not really a setting
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [],
|
default: [],
|
||||||
|
// For privacy
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"SpotlightSearch.recentSearches": {
|
"SpotlightSearch.recentSearches": {
|
||||||
// not really a setting
|
// not really a setting
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [], // list of room IDs, most recent first
|
default: [], // list of room IDs, most recent first
|
||||||
|
// For privacy
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"showMediaEventIds": {
|
"showMediaEventIds": {
|
||||||
// not really a setting
|
// not really a setting
|
||||||
supportedLevels: [SettingLevel.DEVICE],
|
supportedLevels: [SettingLevel.DEVICE],
|
||||||
default: {}, // List of events => is visible
|
default: {}, // List of events => is visible
|
||||||
|
// Exports event IDs
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"SpotlightSearch.showNsfwPublicRooms": {
|
"SpotlightSearch.showNsfwPublicRooms": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
@@ -1003,6 +1028,8 @@ export const SETTINGS: Settings = {
|
|||||||
"room_directory_servers": {
|
"room_directory_servers": {
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [],
|
default: [],
|
||||||
|
// Contains connected servers for user
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"integrationProvisioning": {
|
"integrationProvisioning": {
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
@@ -1012,6 +1039,7 @@ export const SETTINGS: Settings = {
|
|||||||
supportedLevels: [SettingLevel.ROOM_ACCOUNT, SettingLevel.ROOM_DEVICE],
|
supportedLevels: [SettingLevel.ROOM_ACCOUNT, SettingLevel.ROOM_DEVICE],
|
||||||
supportedLevelsAreOrdered: true,
|
supportedLevelsAreOrdered: true,
|
||||||
default: {}, // none allowed
|
default: {}, // none allowed
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
// Legacy, kept around for transitionary purposes
|
// Legacy, kept around for transitionary purposes
|
||||||
"analyticsOptIn": {
|
"analyticsOptIn": {
|
||||||
@@ -1086,6 +1114,8 @@ export const SETTINGS: Settings = {
|
|||||||
"notificationSound": {
|
"notificationSound": {
|
||||||
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
||||||
default: false,
|
default: false,
|
||||||
|
// Contains personal information in file name
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"notificationBodyEnabled": {
|
"notificationBodyEnabled": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
@@ -1112,6 +1142,8 @@ export const SETTINGS: Settings = {
|
|||||||
allow: [],
|
allow: [],
|
||||||
deny: [],
|
deny: [],
|
||||||
},
|
},
|
||||||
|
// Expses widget information
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"breadcrumbs": {
|
"breadcrumbs": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
@@ -1201,6 +1233,8 @@ export const SETTINGS: Settings = {
|
|||||||
// deprecated
|
// deprecated
|
||||||
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
||||||
default: {},
|
default: {},
|
||||||
|
// Sensitive information in widget ID
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
"Widgets.layout": {
|
"Widgets.layout": {
|
||||||
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
||||||
@@ -1275,6 +1309,8 @@ export const SETTINGS: Settings = {
|
|||||||
"activeCallRoomIds": {
|
"activeCallRoomIds": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
default: [],
|
default: [],
|
||||||
|
// Contains room IDs
|
||||||
|
shouldExportToRageshake: false,
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Enable or disable the release announcement feature
|
* Enable or disable the release announcement feature
|
||||||
|
|||||||
@@ -883,6 +883,21 @@ export default class SettingsStore {
|
|||||||
logger.log(`--- END DEBUG`);
|
logger.log(`--- END DEBUG`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export all settings as a JSON object, except for settings
|
||||||
|
* blocked from being exported by `shouldExportToRageshake`.
|
||||||
|
* @returns Settings as a JSON object string.
|
||||||
|
*/
|
||||||
|
public static exportForRageshake(): string {
|
||||||
|
const settingMap: Record<string, unknown> = {};
|
||||||
|
for (const settingKey of (Object.keys(SETTINGS) as SettingKey[]).filter(
|
||||||
|
(s) => SETTINGS[s].shouldExportToRageshake !== false,
|
||||||
|
)) {
|
||||||
|
settingMap[settingKey] = SettingsStore.getValue(settingKey);
|
||||||
|
}
|
||||||
|
return JSON.stringify(settingMap);
|
||||||
|
}
|
||||||
|
|
||||||
private static getHandler(settingName: SettingKey, level: SettingLevel): SettingsHandler | null {
|
private static getHandler(settingName: SettingKey, level: SettingLevel): SettingsHandler | null {
|
||||||
const handlers = SettingsStore.getHandlers(settingName);
|
const handlers = SettingsStore.getHandlers(settingName);
|
||||||
if (!handlers[level]) return null;
|
if (!handlers[level]) return null;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import BugReportDialog, {
|
|||||||
} from "../../../../../src/components/views/dialogs/BugReportDialog";
|
} from "../../../../../src/components/views/dialogs/BugReportDialog";
|
||||||
import SdkConfig from "../../../../../src/SdkConfig";
|
import SdkConfig from "../../../../../src/SdkConfig";
|
||||||
import { type ConsoleLogger } from "../../../../../src/rageshake/rageshake";
|
import { type ConsoleLogger } from "../../../../../src/rageshake/rageshake";
|
||||||
|
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||||
|
|
||||||
const BUG_REPORT_URL = "https://example.org/submit";
|
const BUG_REPORT_URL = "https://example.org/submit";
|
||||||
|
|
||||||
@@ -32,6 +33,16 @@ describe("BugReportDialog", () => {
|
|||||||
bug_report_endpoint_url: BUG_REPORT_URL,
|
bug_report_endpoint_url: BUG_REPORT_URL,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const originalGetValue = SettingsStore.getValue;
|
||||||
|
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName, ...args) => {
|
||||||
|
// These settings rely on a controller that creates an AudioContext in
|
||||||
|
// order to test whether the setting can be enabled. For the sake of this test, disable that.
|
||||||
|
if (settingName === "notificationsEnabled" || settingName === "notificationBodyEnabled") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return originalGetValue(settingName, ...args);
|
||||||
|
});
|
||||||
|
|
||||||
const mockConsoleLogger = {
|
const mockConsoleLogger = {
|
||||||
flush: jest.fn(),
|
flush: jest.fn(),
|
||||||
consume: jest.fn(),
|
consume: jest.fn(),
|
||||||
@@ -55,6 +66,7 @@ describe("BugReportDialog", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
SdkConfig.reset();
|
SdkConfig.reset();
|
||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import SdkConfig from "../../../src/SdkConfig";
|
|||||||
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
||||||
import SettingsStore from "../../../src/settings/SettingsStore";
|
import SettingsStore from "../../../src/settings/SettingsStore";
|
||||||
import { mkStubRoom, mockPlatformPeg, stubClient } from "../../test-utils";
|
import { mkStubRoom, mockPlatformPeg, stubClient } from "../../test-utils";
|
||||||
import { type SettingKey } from "../../../src/settings/Settings.tsx";
|
import { SETTINGS, type SettingKey } from "../../../src/settings/Settings.tsx";
|
||||||
import MatrixClientBackedController from "../../../src/settings/controllers/MatrixClientBackedController.ts";
|
import MatrixClientBackedController from "../../../src/settings/controllers/MatrixClientBackedController.ts";
|
||||||
|
|
||||||
const TEST_DATA = [
|
const TEST_DATA = [
|
||||||
@@ -55,6 +55,7 @@ describe("SettingsStore", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
SdkConfig.reset();
|
SdkConfig.reset();
|
||||||
|
SettingsStore.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getValueAt", () => {
|
describe("getValueAt", () => {
|
||||||
@@ -82,6 +83,16 @@ describe("SettingsStore", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("exportForRageshake", () => {
|
||||||
|
it("should not export settings marked as non-exportable", async () => {
|
||||||
|
await SettingsStore.setValue("userTimezone", null, SettingLevel.DEVICE, "Europe/London");
|
||||||
|
const values = JSON.parse(SettingsStore.exportForRageshake()) as Record<SettingKey, unknown>;
|
||||||
|
for (const exportedKey of Object.keys(values) as SettingKey[]) {
|
||||||
|
expect(SETTINGS[exportedKey].shouldExportToRageshake).not.toEqual(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("runMigrations", () => {
|
describe("runMigrations", () => {
|
||||||
let client: MatrixClient;
|
let client: MatrixClient;
|
||||||
let room: Room;
|
let room: Room;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { collectBugReport } from "../../src/rageshake/submit-rageshake";
|
|||||||
import SettingsStore from "../../src/settings/SettingsStore";
|
import SettingsStore from "../../src/settings/SettingsStore";
|
||||||
import { type ConsoleLogger } from "../../src/rageshake/rageshake";
|
import { type ConsoleLogger } from "../../src/rageshake/rageshake";
|
||||||
import { type FeatureSettingKey, type SettingKey } from "../../src/settings/Settings.tsx";
|
import { type FeatureSettingKey, type SettingKey } from "../../src/settings/Settings.tsx";
|
||||||
|
import { SettingLevel } from "../../src/settings/SettingLevel.ts";
|
||||||
|
|
||||||
describe("Rageshakes", () => {
|
describe("Rageshakes", () => {
|
||||||
const RUST_CRYPTO_VERSION = "Rust SDK 0.7.0 (691ec63), Vodozemac 0.5.0";
|
const RUST_CRYPTO_VERSION = "Rust SDK 0.7.0 (691ec63), Vodozemac 0.5.0";
|
||||||
@@ -35,6 +36,8 @@ describe("Rageshakes", () => {
|
|||||||
onlyData: true,
|
onlyData: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
let windowSpy: jest.SpyInstance;
|
||||||
|
let mockWindow: Mocked<Window>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockClient = getMockClientWithEventEmitter({
|
mockClient = getMockClientWithEventEmitter({
|
||||||
@@ -50,30 +53,24 @@ describe("Rageshakes", () => {
|
|||||||
ed25519: "",
|
ed25519: "",
|
||||||
curve25519: "",
|
curve25519: "",
|
||||||
});
|
});
|
||||||
|
mockWindow = {
|
||||||
|
matchMedia: jest.fn().mockReturnValue({ matches: false }),
|
||||||
|
navigator: {
|
||||||
|
userAgent: "",
|
||||||
|
},
|
||||||
|
} as unknown as Mocked<Window>;
|
||||||
|
// @ts-ignore - We just need partial mock
|
||||||
|
windowSpy = jest.spyOn(global, "window", "get").mockReturnValue(mockWindow);
|
||||||
|
|
||||||
fetchMock.restore();
|
fetchMock.restore();
|
||||||
fetchMock.catch(404);
|
fetchMock.catch(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
windowSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
describe("Basic Information", () => {
|
describe("Basic Information", () => {
|
||||||
let mockWindow: Mocked<Window>;
|
|
||||||
let windowSpy: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
mockWindow = {
|
|
||||||
matchMedia: jest.fn().mockReturnValue({ matches: false }),
|
|
||||||
navigator: {
|
|
||||||
userAgent: "",
|
|
||||||
},
|
|
||||||
} as unknown as Mocked<Window>;
|
|
||||||
// @ts-ignore - We just need partial mock
|
|
||||||
windowSpy = jest.spyOn(global, "window", "get").mockReturnValue(mockWindow);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
windowSpy.mockRestore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should include app version", async () => {
|
it("should include app version", async () => {
|
||||||
mockPlatformPeg({ getAppVersion: jest.fn().mockReturnValue("1.11.58") });
|
mockPlatformPeg({ getAppVersion: jest.fn().mockReturnValue("1.11.58") });
|
||||||
|
|
||||||
@@ -376,6 +373,10 @@ describe("Rageshakes", () => {
|
|||||||
describe("Settings Store", () => {
|
describe("Settings Store", () => {
|
||||||
const mockSettingsStore = mocked(SettingsStore);
|
const mockSettingsStore = mocked(SettingsStore);
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it("should collect labs from settings store", async () => {
|
it("should collect labs from settings store", async () => {
|
||||||
const someFeatures = [
|
const someFeatures = [
|
||||||
"feature_video_rooms",
|
"feature_video_rooms",
|
||||||
@@ -430,6 +431,7 @@ describe("Rageshakes", () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
navigatorSpy.mockRestore();
|
navigatorSpy.mockRestore();
|
||||||
|
SettingsStore.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should collect navigator storage persisted", async () => {
|
it("should collect navigator storage persisted", async () => {
|
||||||
@@ -488,6 +490,7 @@ describe("Rageshakes", () => {
|
|||||||
};
|
};
|
||||||
const disabledFeatures = ["cssanimations", "d0", "d1"];
|
const disabledFeatures = ["cssanimations", "d0", "d1"];
|
||||||
const mockWindow = {
|
const mockWindow = {
|
||||||
|
matchMedia: jest.fn().mockReturnValue({ matches: false }),
|
||||||
Modernizr: {
|
Modernizr: {
|
||||||
...allFeatures,
|
...allFeatures,
|
||||||
},
|
},
|
||||||
@@ -503,20 +506,16 @@ describe("Rageshakes", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should collect localstorage settings", async () => {
|
it("should collect localstorage settings", async () => {
|
||||||
const localSettings = {
|
await SettingsStore.setValue("language", null, SettingLevel.DEVICE, "fr");
|
||||||
language: "fr",
|
await SettingsStore.setValue("showHiddenEventsInTimeline", null, SettingLevel.DEVICE, true);
|
||||||
showHiddenEventsInTimeline: true,
|
await SettingsStore.setValue("userTimezone", null, SettingLevel.DEVICE, "Europe/London");
|
||||||
activeCallRoomIds: [],
|
await SettingsStore.setValue("activeCallRoomIds", null, SettingLevel.DEVICE, []);
|
||||||
};
|
|
||||||
|
|
||||||
const spy = jest.spyOn(window.localStorage.__proto__, "getItem").mockImplementation((key) => {
|
|
||||||
return JSON.stringify(localSettings);
|
|
||||||
});
|
|
||||||
|
|
||||||
const formData = await collectBugReport();
|
const formData = await collectBugReport();
|
||||||
expect(formData.get("mx_local_settings")).toBe(JSON.stringify(localSettings));
|
const settingDataJSON = formData.get("mx_local_settings");
|
||||||
|
expect(settingDataJSON).not.toBeNull();
|
||||||
spy.mockRestore();
|
const settingsData = JSON.parse(settingDataJSON as string);
|
||||||
|
expect(settingsData.showHiddenEventsInTimeline).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should collect logs", async () => {
|
it("should collect logs", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user