element-web/test/unit-tests/stores/BreadcrumbsStore-test.ts

176 lines
6.5 KiB
TypeScript

/*
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import { mocked } from "jest-mock";
import { MatrixClient, Room } from "matrix-js-sdk/src/matrix";
import { createTestClient, flushPromises, setupAsyncStoreWithClient } from "../../test-utils";
import SettingsStore from "../../../src/settings/SettingsStore";
import { BreadcrumbsStore } from "../../../src/stores/BreadcrumbsStore";
import { Action } from "../../../src/dispatcher/actions";
import { defaultDispatcher } from "../../../src/dispatcher/dispatcher";
describe("BreadcrumbsStore", () => {
let store: BreadcrumbsStore;
const client: MatrixClient = createTestClient();
beforeEach(() => {
jest.resetAllMocks();
store = BreadcrumbsStore.instance;
setupAsyncStoreWithClient(store, client);
jest.spyOn(SettingsStore, "setValue").mockImplementation(() => Promise.resolve());
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
});
it("does not meet room requirements if there are not enough rooms", () => {
// We don't have enough rooms, so we don't meet requirements
mocked(client.getVisibleRooms).mockReturnValue(fakeRooms(2));
expect(store.meetsRoomRequirement).toBe(false);
});
it("meets room requirements if there are enough rooms", () => {
// We do have enough rooms to show breadcrumbs
mocked(client.getVisibleRooms).mockReturnValue(fakeRooms(25));
expect(store.meetsRoomRequirement).toBe(true);
});
describe("And 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 room precessors flag", () => {
mocked(client.getVisibleRooms).mockReturnValue(fakeRooms(25));
expect(store.meetsRoomRequirement).toBeTruthy();
expect(client.getVisibleRooms).toHaveBeenCalledWith(true);
});
});
describe("And the feature_dynamic_room_predecessors is not enabled", () => {
it("passes through the dynamic room precessors flag", () => {
mocked(client.getVisibleRooms).mockReturnValue(fakeRooms(25));
expect(store.meetsRoomRequirement).toBeTruthy();
expect(client.getVisibleRooms).toHaveBeenCalledWith(false);
});
});
describe("If the feature_dynamic_room_predecessors is not enabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
});
it("Appends a room when you join", async () => {
// Sanity: no rooms initially
expect(store.rooms).toEqual([]);
// Given a room
const room = fakeRoom();
mocked(client.getRoom).mockReturnValue(room);
mocked(client.getRoomUpgradeHistory).mockReturnValue([]);
// When we hear that we have joined it
await dispatchJoinRoom(room.roomId);
// It is stored in the store's room list
expect(store.rooms.map((r) => r.roomId)).toEqual([room.roomId]);
});
it("Replaces the old room when a newer one joins", async () => {
// Given an old room and a new room
const oldRoom = fakeRoom();
const newRoom = fakeRoom();
mocked(client.getRoom).mockImplementation((roomId) => {
if (roomId === oldRoom.roomId) return oldRoom;
return newRoom;
});
// Where the new one is a predecessor of the old one
mocked(client.getRoomUpgradeHistory).mockReturnValue([oldRoom, newRoom]);
// When we hear that we joined the old room, then the new one
await dispatchJoinRoom(oldRoom.roomId);
await dispatchJoinRoom(newRoom.roomId);
// The store only has the new one
expect(store.rooms.map((r) => r.roomId)).toEqual([newRoom.roomId]);
});
it("Passes through the dynamic predecessor setting", async () => {
// Given a room
const room = fakeRoom();
mocked(client.getRoom).mockReturnValue(room);
mocked(client.getRoomUpgradeHistory).mockReturnValue([]);
// When we signal that we have joined
await dispatchJoinRoom(room.roomId);
// We pass the value of the dynamic predecessor setting through
expect(client.getRoomUpgradeHistory).toHaveBeenCalledWith(room.roomId, false, 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 () => {
// Given a room
const room = fakeRoom();
mocked(client.getRoom).mockReturnValue(room);
mocked(client.getRoomUpgradeHistory).mockReturnValue([]);
// When we signal that we have joined
await dispatchJoinRoom(room.roomId);
// We pass the value of the dynamic predecessor setting through
expect(client.getRoomUpgradeHistory).toHaveBeenCalledWith(room.roomId, false, true);
});
});
/**
* Send a JoinRoom event via the dispatcher, and wait for it to process.
*/
async function dispatchJoinRoom(roomId: string) {
defaultDispatcher.dispatch(
{
action: Action.JoinRoom,
roomId,
metricsTrigger: null,
},
true, // synchronous dispatch
);
// Wait for event dispatch to happen
await flushPromises();
}
/**
* Create as many fake rooms in an array as you ask for.
*/
function fakeRooms(howMany: number): Room[] {
const ret: Room[] = [];
for (let i = 0; i < howMany; i++) {
ret.push(fakeRoom());
}
return ret;
}
let roomIdx = 0;
function fakeRoom(): Room {
roomIdx++;
return new Room(`room${roomIdx}`, client, "@user:example.com");
}
});