From 18826b05f48b6a974a17541ccf78d0f519aae289 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 9 Mar 2023 10:36:23 +0000 Subject: [PATCH 1/3] Support dynamic room predecessors in OwnBeaconStore --- src/stores/OwnBeaconStore.ts | 27 ++++++++++++++++++++- test/stores/OwnBeaconStore-test.ts | 39 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/stores/OwnBeaconStore.ts b/src/stores/OwnBeaconStore.ts index dc2524b5b5f..3bcef0ff7bd 100644 --- a/src/stores/OwnBeaconStore.ts +++ b/src/stores/OwnBeaconStore.ts @@ -43,6 +43,7 @@ import { } from "../utils/beacon"; import { getCurrentPosition } from "../utils/beacon"; import { doMaybeLocalRoomAction } from "../utils/local-room"; +import SettingsStore from "../settings/SettingsStore"; const isOwnBeacon = (beacon: Beacon, userId: string): boolean => beacon.beaconInfoOwner === userId; @@ -119,6 +120,10 @@ export class OwnBeaconStore extends AsyncStoreWithClient { * when the target is stationary */ private lastPublishedPositionTimestamp?: number; + /** + * Ref returned from watchSetting for the MSC3946 labs flag + */ + private dynamicWatcherRef: string; public constructor() { super(defaultDispatcher); @@ -142,7 +147,12 @@ export class OwnBeaconStore extends AsyncStoreWithClient { this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon); this.matrixClient.removeListener(BeaconEvent.Destroy, this.onDestroyBeacon); this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers); + SettingsStore.unwatchSetting(this.dynamicWatcherRef); + + this.clearBeacons(); + } + private clearBeacons(): void { this.beacons.forEach((beacon) => beacon.destroy()); this.stopPollingLocation(); @@ -159,6 +169,11 @@ export class OwnBeaconStore extends AsyncStoreWithClient { this.matrixClient.on(BeaconEvent.Update, this.onUpdateBeacon); this.matrixClient.on(BeaconEvent.Destroy, this.onDestroyBeacon); this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers); + this.dynamicWatcherRef = SettingsStore.watchSetting( + "feature_dynamic_room_predecessors", + null, + this.reinitialiseBeaconState, + ); this.initialiseBeaconState(); } @@ -308,9 +323,19 @@ export class OwnBeaconStore extends AsyncStoreWithClient { ); } + /** + * @internal public for test only + */ + public reinitialiseBeaconState = (): void => { + this.clearBeacons(); + this.initialiseBeaconState(); + }; + private initialiseBeaconState = (): void => { const userId = this.matrixClient.getUserId()!; - const visibleRooms = this.matrixClient.getVisibleRooms(); + const visibleRooms = this.matrixClient.getVisibleRooms( + SettingsStore.getValue("feature_dynamic_room_predecessors"), + ); visibleRooms.forEach((room) => { const roomState = room.currentState; diff --git a/test/stores/OwnBeaconStore-test.ts b/test/stores/OwnBeaconStore-test.ts index 79ff78530e1..937b0259748 100644 --- a/test/stores/OwnBeaconStore-test.ts +++ b/test/stores/OwnBeaconStore-test.ts @@ -38,6 +38,7 @@ import { } from "../test-utils"; import { makeBeaconInfoEvent, mockGeolocation, watchPositionMockImplementation } from "../test-utils/beacon"; import { getMockClientWithEventEmitter } from "../test-utils/client"; +import SettingsStore from "../../src/settings/SettingsStore"; // modern fake timers and lodash.debounce are a faff // short circuit it @@ -62,6 +63,7 @@ describe("OwnBeaconStore", () => { unstable_setLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }), sendEvent: jest.fn().mockResolvedValue({ event_id: "1" }), unstable_createLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }), + isGuest: jest.fn().mockReturnValue(false), }); const room1Id = "$room1:server.org"; const room2Id = "$room2:server.org"; @@ -1204,4 +1206,41 @@ describe("OwnBeaconStore", () => { expect(mockClient.unstable_createLiveBeacon).toHaveBeenCalledWith(room1Id, content); }); }); + + describe("If the feature_dynamic_room_predecessors is not enabled", () => { + beforeEach(() => { + jest.spyOn(SettingsStore, "getValue").mockReturnValue(false); + }); + + it("Passes through the dynamic predecessor setting", async () => { + mockClient.getVisibleRooms.mockReset(); + mockClient.getVisibleRooms.mockReturnValue([]); + await makeOwnBeaconStore(); + expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(false); + }); + }); + + describe("If the feature_dynamic_room_predecessors is enabled", () => { + beforeEach(() => { + // Turn on feature_dynamic_room_predecessors setting + jest.spyOn(SettingsStore, "getValue").mockImplementation( + (settingName) => settingName === "feature_dynamic_room_predecessors", + ); + }); + + it("Passes through the dynamic predecessor setting", async () => { + mockClient.getVisibleRooms.mockReset(); + mockClient.getVisibleRooms.mockReturnValue([]); + await makeOwnBeaconStore(); + expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(true); + }); + + it("Passes through the dynamic predecessor when reinitialised", async () => { + const store = await makeOwnBeaconStore(); + mockClient.getVisibleRooms.mockReset(); + mockClient.getVisibleRooms.mockReturnValue([]); + store.reinitialiseBeaconState(); + expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(true); + }); + }); }); From 6b529f11d04dd9d561bf5f9d53e254ed255b38bb Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 9 Mar 2023 10:45:15 +0000 Subject: [PATCH 2/3] Fix type of dynamicWatcherRef --- src/stores/OwnBeaconStore.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stores/OwnBeaconStore.ts b/src/stores/OwnBeaconStore.ts index 3bcef0ff7bd..458cca7454c 100644 --- a/src/stores/OwnBeaconStore.ts +++ b/src/stores/OwnBeaconStore.ts @@ -123,7 +123,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient { /** * Ref returned from watchSetting for the MSC3946 labs flag */ - private dynamicWatcherRef: string; + private dynamicWatcherRef: string | undefined; public constructor() { super(defaultDispatcher); @@ -147,7 +147,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient { this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon); this.matrixClient.removeListener(BeaconEvent.Destroy, this.onDestroyBeacon); this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers); - SettingsStore.unwatchSetting(this.dynamicWatcherRef); + SettingsStore.unwatchSetting(this.dynamicWatcherRef ?? ""); this.clearBeacons(); } From d624906e278e9c635d90bcab12a7043342add38b Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 9 Mar 2023 13:38:13 +0000 Subject: [PATCH 3/3] Mock a function missing from client --- test/components/views/beacon/RoomLiveShareWarning-test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/test/components/views/beacon/RoomLiveShareWarning-test.tsx b/test/components/views/beacon/RoomLiveShareWarning-test.tsx index fef2bcbb327..3db674bc7fe 100644 --- a/test/components/views/beacon/RoomLiveShareWarning-test.tsx +++ b/test/components/views/beacon/RoomLiveShareWarning-test.tsx @@ -44,6 +44,7 @@ describe("", () => { getUserId: jest.fn().mockReturnValue(aliceId), unstable_setLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }), sendEvent: jest.fn(), + isGuest: jest.fn().mockReturnValue(false), }); // 14.03.2022 16:15