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:
Will Hunt
2025-07-02 09:03:31 +01:00
committed by GitHub
parent 99f7656d09
commit e1fea71c97
7 changed files with 107 additions and 34 deletions
+29 -30
View File
@@ -22,6 +22,7 @@ import { collectBugReport } from "../../src/rageshake/submit-rageshake";
import SettingsStore from "../../src/settings/SettingsStore";
import { type ConsoleLogger } from "../../src/rageshake/rageshake";
import { type FeatureSettingKey, type SettingKey } from "../../src/settings/Settings.tsx";
import { SettingLevel } from "../../src/settings/SettingLevel.ts";
describe("Rageshakes", () => {
const RUST_CRYPTO_VERSION = "Rust SDK 0.7.0 (691ec63), Vodozemac 0.5.0";
@@ -35,6 +36,8 @@ describe("Rageshakes", () => {
onlyData: true,
},
);
let windowSpy: jest.SpyInstance;
let mockWindow: Mocked<Window>;
beforeEach(() => {
mockClient = getMockClientWithEventEmitter({
@@ -50,30 +53,24 @@ describe("Rageshakes", () => {
ed25519: "",
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.catch(404);
});
afterEach(() => {
windowSpy.mockRestore();
});
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 () => {
mockPlatformPeg({ getAppVersion: jest.fn().mockReturnValue("1.11.58") });
@@ -376,6 +373,10 @@ describe("Rageshakes", () => {
describe("Settings Store", () => {
const mockSettingsStore = mocked(SettingsStore);
afterEach(() => {
jest.restoreAllMocks();
});
it("should collect labs from settings store", async () => {
const someFeatures = [
"feature_video_rooms",
@@ -430,6 +431,7 @@ describe("Rageshakes", () => {
afterEach(() => {
navigatorSpy.mockRestore();
SettingsStore.reset();
});
it("should collect navigator storage persisted", async () => {
@@ -488,6 +490,7 @@ describe("Rageshakes", () => {
};
const disabledFeatures = ["cssanimations", "d0", "d1"];
const mockWindow = {
matchMedia: jest.fn().mockReturnValue({ matches: false }),
Modernizr: {
...allFeatures,
},
@@ -503,20 +506,16 @@ describe("Rageshakes", () => {
});
it("should collect localstorage settings", async () => {
const localSettings = {
language: "fr",
showHiddenEventsInTimeline: true,
activeCallRoomIds: [],
};
const spy = jest.spyOn(window.localStorage.__proto__, "getItem").mockImplementation((key) => {
return JSON.stringify(localSettings);
});
await SettingsStore.setValue("language", null, SettingLevel.DEVICE, "fr");
await SettingsStore.setValue("showHiddenEventsInTimeline", null, SettingLevel.DEVICE, true);
await SettingsStore.setValue("userTimezone", null, SettingLevel.DEVICE, "Europe/London");
await SettingsStore.setValue("activeCallRoomIds", null, SettingLevel.DEVICE, []);
const formData = await collectBugReport();
expect(formData.get("mx_local_settings")).toBe(JSON.stringify(localSettings));
spy.mockRestore();
const settingDataJSON = formData.get("mx_local_settings");
expect(settingDataJSON).not.toBeNull();
const settingsData = JSON.parse(settingDataJSON as string);
expect(settingsData.showHiddenEventsInTimeline).toEqual(true);
});
it("should collect logs", async () => {