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

Commit

Permalink
Support MSC3946 in RoomListStore (#10054)
Browse files Browse the repository at this point in the history
  • Loading branch information
andybalaam authored Feb 3, 2023
1 parent 2bde31d commit b7cd28b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
8 changes: 5 additions & 3 deletions src/stores/room-list/RoomListStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ 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 createEvent = roomState.getStateEvents(EventType.RoomCreate, "");
if (createEvent && createEvent.getContent()["predecessor"]) {
const prevRoom = this.matrixClient.getRoom(createEvent.getContent()["predecessor"]["room_id"]);
const predecessor = roomState.findPredecessor(SettingsStore.getValue("feature_dynamic_room_predecessors"));
if (predecessor) {
const prevRoom = this.matrixClient.getRoom(predecessor.roomId);
if (prevRoom) {
const isSticky = this.algorithm.stickyRoom === prevRoom;
if (isSticky) {
Expand All @@ -298,6 +298,8 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
// Note: we hit the algorithm instead of our handleRoomUpdate() function to
// avoid redundant updates.
this.algorithm.handleRoomUpdate(prevRoom, RoomUpdateCause.RoomRemoved);
} else {
logger.warn(`Unable to find predecessor room with id ${predecessor.roomId}`);
}
}

Expand Down
56 changes: 51 additions & 5 deletions test/stores/room-list/RoomListStore-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ limitations under the License.
import { EventType, MatrixEvent, 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 { stubClient, upsertRoomStateEvents } from "../../test-utils";

describe("RoomListStore", () => {
const client = stubClient();
const roomWithCreatePredecessorId = "!roomid:example.com";
const newRoomId = "!roomid:example.com";
const roomNoPredecessorId = "!roomnopreid:example.com";
const oldRoomId = "!oldroomid:example.com";
const userId = "@user:example.com";
const createWithPredecessor = new MatrixEvent({
type: EventType.RoomCreate,
sender: userId,
room_id: roomWithCreatePredecessorId,
room_id: newRoomId,
content: {
predecessor: { room_id: oldRoomId, event_id: "tombstone_event_id" },
},
Expand All @@ -41,19 +42,32 @@ describe("RoomListStore", () => {
const createNoPredecessor = new MatrixEvent({
type: EventType.RoomCreate,
sender: userId,
room_id: roomWithCreatePredecessorId,
room_id: newRoomId,
content: {},
event_id: "$create",
state_key: "",
});
const roomWithCreatePredecessor = new Room(roomWithCreatePredecessorId, client, userId, {});
const predecessor = new MatrixEvent({
type: EventType.RoomPredecessor,
sender: userId,
room_id: newRoomId,
content: {
predecessor_room_id: oldRoomId,
last_known_event_id: "tombstone_event_id",
},
event_id: "$pred",
state_key: "",
});
const roomWithPredecessorEvent = new Room(newRoomId, client, userId, {});
upsertRoomStateEvents(roomWithPredecessorEvent, [predecessor]);
const roomWithCreatePredecessor = new Room(newRoomId, client, userId, {});
upsertRoomStateEvents(roomWithCreatePredecessor, [createWithPredecessor]);
const roomNoPredecessor = new Room(roomNoPredecessorId, client, userId, {});
upsertRoomStateEvents(roomNoPredecessor, [createNoPredecessor]);
const oldRoom = new Room(oldRoomId, client, userId, {});
client.getRoom = jest.fn().mockImplementation((roomId) => {
switch (roomId) {
case roomWithCreatePredecessorId:
case newRoomId:
return roomWithCreatePredecessor;
case oldRoomId:
return oldRoom;
Expand Down Expand Up @@ -123,4 +137,36 @@ describe("RoomListStore", () => {
// And no other updates happen
expect(handleRoomUpdate).toHaveBeenCalledTimes(1);
});

describe("When feature_dynamic_room_predecessors = true", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === "feature_dynamic_room_predecessors",
);
});

afterEach(() => {
jest.spyOn(SettingsStore, "getValue").mockReset();
});

it("Removes old room if it finds a predecessor in the m.predecessor event", () => {
// Given a store we can spy on
const { store, handleRoomUpdate } = createStore();

// When we tell it we joined a new room that has an old room as
// predecessor in the create event
const payload = {
oldMembership: "invite",
membership: "join",
room: roomWithPredecessorEvent,
};
store.onDispatchMyMembership(payload);

// Then the old room is removed
expect(handleRoomUpdate).toHaveBeenCalledWith(oldRoom, RoomUpdateCause.RoomRemoved);

// And the new room is added
expect(handleRoomUpdate).toHaveBeenCalledWith(roomWithPredecessorEvent, RoomUpdateCause.NewRoom);
});
});
});

0 comments on commit b7cd28b

Please sign in to comment.