Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Pass the dynamic predecessor feature flag when listing rooms
Browse files Browse the repository at this point in the history
  • Loading branch information
andybalaam committed Feb 3, 2023
1 parent 6dd578e commit 800a041
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
21 changes: 19 additions & 2 deletions src/stores/room-list/RoomListStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
public static TEST_MODE = false;

private initialListsGenerated = false;
private msc3946ProcessDynamicPredecessor: boolean;
private msc3946SettingWatcherRef: string;
private algorithm = new Algorithm();
private prefilterConditions: IFilterCondition[] = [];
private updateFn = new MarkedExecution(() => {
Expand All @@ -69,6 +71,20 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
super(dis);
this.setMaxListeners(20); // RoomList + LeftPanel + 8xRoomSubList + spares
this.algorithm.start();

this.msc3946ProcessDynamicPredecessor = SettingsStore.getValue("feature_dynamic_room_predecessors");
this.msc3946SettingWatcherRef = SettingsStore.watchSetting(
"feature_dynamic_room_predecessors",
null,
(_settingName, _roomId, _level, _newValAtLevel, newVal) => {
this.msc3946ProcessDynamicPredecessor = newVal;
this.regenerateAllLists({ trigger: true });
},
);
}

public componentWillUnmount(): void {
SettingsStore.unwatchSetting(this.msc3946SettingWatcherRef);
}

private setupWatchers(): void {
Expand Down Expand Up @@ -286,7 +302,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
// If we're joining an upgraded room, we'll want to make sure we don't proliferate
// the dead room in the list.
const roomState: RoomState = membershipPayload.room.currentState;
const predecessor = roomState.findPredecessor(SettingsStore.getValue("feature_dynamic_room_predecessors"));
const predecessor = roomState.findPredecessor(this.msc3946ProcessDynamicPredecessor);
if (predecessor) {
const prevRoom = this.matrixClient.getRoom(predecessor.roomId);
if (prevRoom) {
Expand Down Expand Up @@ -496,7 +512,8 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
private getPlausibleRooms(): Room[] {
if (!this.matrixClient) return [];

let rooms = this.matrixClient.getVisibleRooms().filter((r) => VisibilityProvider.instance.isRoomVisible(r));
let rooms = this.matrixClient.getVisibleRooms(this.msc3946ProcessDynamicPredecessor);
rooms = rooms.filter((r) => VisibilityProvider.instance.isRoomVisible(r));

if (this.prefilterConditions.length > 0) {
rooms = rooms.filter((r) => {
Expand Down
67 changes: 65 additions & 2 deletions test/stores/room-list/RoomListStore-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { EventType, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import { EventType, MatrixEvent, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix";

import { MatrixDispatcher } from "../../../src/dispatcher/dispatcher";
import SettingsStore from "../../../src/settings/SettingsStore";
import { ListAlgorithm, SortAlgorithm } from "../../../src/stores/room-list/algorithms/models";
import { OrderedDefaultTagIDs, RoomUpdateCause } from "../../../src/stores/room-list/models";
import RoomListStore, { RoomListStoreClass } from "../../../src/stores/room-list/RoomListStore";
import DMRoomMap from "../../../src/utils/DMRoomMap";
import { stubClient, upsertRoomStateEvents } from "../../test-utils";

describe("RoomListStore", () => {
Expand Down Expand Up @@ -62,7 +63,9 @@ describe("RoomListStore", () => {
upsertRoomStateEvents(roomWithPredecessorEvent, [predecessor]);
const roomWithCreatePredecessor = new Room(newRoomId, client, userId, {});
upsertRoomStateEvents(roomWithCreatePredecessor, [createWithPredecessor]);
const roomNoPredecessor = new Room(roomNoPredecessorId, client, userId, {});
const roomNoPredecessor = new Room(roomNoPredecessorId, client, userId, {
pendingEventOrdering: PendingEventOrdering.Detached,
});
upsertRoomStateEvents(roomNoPredecessor, [createNoPredecessor]);
const oldRoom = new Room(oldRoomId, client, userId, {});
client.getRoom = jest.fn().mockImplementation((roomId) => {
Expand Down Expand Up @@ -138,6 +141,52 @@ describe("RoomListStore", () => {
expect(handleRoomUpdate).toHaveBeenCalledTimes(1);
});

it("Lists all rooms that the client says are visible", () => {
// Given 3 rooms that are visible according to the client
const room1 = new Room("!r1:e.com", client, userId, { pendingEventOrdering: PendingEventOrdering.Detached });
const room2 = new Room("!r2:e.com", client, userId, { pendingEventOrdering: PendingEventOrdering.Detached });
const room3 = new Room("!r3:e.com", client, userId, { pendingEventOrdering: PendingEventOrdering.Detached });
room1.updateMyMembership("join");
room2.updateMyMembership("join");
room3.updateMyMembership("join");
DMRoomMap.makeShared();
const { store } = createStore();
client.getVisibleRooms = jest.fn().mockReturnValue([room1, room2, room3]);

// When we make the list of rooms
store.regenerateAllLists({ trigger: false });

// Then the list contains all 3
expect(store.orderedLists).toMatchObject({
"im.vector.fake.recent": [room1, room2, room3],
});

// We asked not to use MSC3946 when we asked the client for the visible rooms
expect(client.getVisibleRooms).toHaveBeenCalledWith(false);
expect(client.getVisibleRooms).toHaveBeenCalledTimes(1);
});

it("Watches the feature flag setting", () => {
jest.spyOn(SettingsStore, "watchSetting").mockReturnValue("dyn_pred_ref");
jest.spyOn(SettingsStore, "unwatchSetting");

// When we create a store
const { store } = createStore();

// Then we watch the feature flag
expect(SettingsStore.watchSetting).toHaveBeenCalledWith(
"feature_dynamic_room_predecessors",
null,
expect.any(Function),
);

// And when we unmount it
store.componentWillUnmount();

// Then we unwatch it.
expect(SettingsStore.unwatchSetting).toHaveBeenCalledWith("dyn_pred_ref");
});

describe("When feature_dynamic_room_predecessors = true", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
Expand Down Expand Up @@ -168,5 +217,19 @@ describe("RoomListStore", () => {
// And the new room is added
expect(handleRoomUpdate).toHaveBeenCalledWith(roomWithPredecessorEvent, RoomUpdateCause.NewRoom);
});

it("Passes the feature flag on to the client when asking for visible rooms", () => {
// Given a store that we can ask for a room list
DMRoomMap.makeShared();
const { store } = createStore();
client.getVisibleRooms = jest.fn().mockReturnValue([]);

// When we make the list of rooms
store.regenerateAllLists({ trigger: false });

// We asked to use MSC3946 when we asked the client for the visible rooms
expect(client.getVisibleRooms).toHaveBeenCalledWith(true);
expect(client.getVisibleRooms).toHaveBeenCalledTimes(1);
});
});
});

0 comments on commit 800a041

Please sign in to comment.