You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-08-07 21:23:00 +03:00
Merge pull request #9934 from matrix-org/kegan/lists-as-keys
refactor: sliding sync: convert to lists-as-keys rather than indexes
This commit is contained in:
@@ -78,13 +78,76 @@ describe("SlidingSyncManager", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ensureListRegistered", () => {
|
||||
it("creates a new list based on the key", async () => {
|
||||
const listKey = "key";
|
||||
mocked(slidingSync.getListParams).mockReturnValue(null);
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
await manager.ensureListRegistered(listKey, {
|
||||
sort: ["by_recency"],
|
||||
});
|
||||
expect(slidingSync.setList).toBeCalledWith(
|
||||
listKey,
|
||||
expect.objectContaining({
|
||||
sort: ["by_recency"],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("updates an existing list based on the key", async () => {
|
||||
const listKey = "key";
|
||||
mocked(slidingSync.getListParams).mockReturnValue({
|
||||
ranges: [[0, 42]],
|
||||
});
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
await manager.ensureListRegistered(listKey, {
|
||||
sort: ["by_recency"],
|
||||
});
|
||||
expect(slidingSync.setList).toBeCalledWith(
|
||||
listKey,
|
||||
expect.objectContaining({
|
||||
sort: ["by_recency"],
|
||||
ranges: [[0, 42]],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("updates ranges on an existing list based on the key if there's no other changes", async () => {
|
||||
const listKey = "key";
|
||||
mocked(slidingSync.getListParams).mockReturnValue({
|
||||
ranges: [[0, 42]],
|
||||
});
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
await manager.ensureListRegistered(listKey, {
|
||||
ranges: [[0, 52]],
|
||||
});
|
||||
expect(slidingSync.setList).not.toBeCalled();
|
||||
expect(slidingSync.setListRanges).toBeCalledWith(listKey, [[0, 52]]);
|
||||
});
|
||||
|
||||
it("no-ops for idential changes", async () => {
|
||||
const listKey = "key";
|
||||
mocked(slidingSync.getListParams).mockReturnValue({
|
||||
ranges: [[0, 42]],
|
||||
sort: ["by_recency"],
|
||||
});
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
await manager.ensureListRegistered(listKey, {
|
||||
ranges: [[0, 42]],
|
||||
sort: ["by_recency"],
|
||||
});
|
||||
expect(slidingSync.setList).not.toBeCalled();
|
||||
expect(slidingSync.setListRanges).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("startSpidering", () => {
|
||||
it("requests in batchSizes", async () => {
|
||||
const gapMs = 1;
|
||||
const batchSize = 10;
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
mocked(slidingSync.setListRanges).mockResolvedValue("yep");
|
||||
mocked(slidingSync.getListData).mockImplementation((i) => {
|
||||
mocked(slidingSync.getListData).mockImplementation((key) => {
|
||||
return {
|
||||
joinedCount: 64,
|
||||
roomIndexToRoomId: {},
|
||||
@@ -106,24 +169,24 @@ describe("SlidingSyncManager", () => {
|
||||
wantWindows.forEach((range, i) => {
|
||||
if (i === 0) {
|
||||
expect(slidingSync.setList).toBeCalledWith(
|
||||
manager.getOrAllocateListIndex(SlidingSyncManager.ListSearch),
|
||||
SlidingSyncManager.ListSearch,
|
||||
expect.objectContaining({
|
||||
ranges: [[0, batchSize - 1], range],
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
expect(slidingSync.setListRanges).toBeCalledWith(
|
||||
manager.getOrAllocateListIndex(SlidingSyncManager.ListSearch),
|
||||
[[0, batchSize - 1], range],
|
||||
);
|
||||
expect(slidingSync.setListRanges).toBeCalledWith(SlidingSyncManager.ListSearch, [
|
||||
[0, batchSize - 1],
|
||||
range,
|
||||
]);
|
||||
});
|
||||
});
|
||||
it("handles accounts with zero rooms", async () => {
|
||||
const gapMs = 1;
|
||||
const batchSize = 10;
|
||||
mocked(slidingSync.setList).mockResolvedValue("yep");
|
||||
mocked(slidingSync.getListData).mockImplementation((i) => {
|
||||
mocked(slidingSync.getListData).mockImplementation((key) => {
|
||||
return {
|
||||
joinedCount: 0,
|
||||
roomIndexToRoomId: {},
|
||||
@@ -133,7 +196,7 @@ describe("SlidingSyncManager", () => {
|
||||
expect(slidingSync.getListData).toBeCalledTimes(1);
|
||||
expect(slidingSync.setList).toBeCalledTimes(1);
|
||||
expect(slidingSync.setList).toBeCalledWith(
|
||||
manager.getOrAllocateListIndex(SlidingSyncManager.ListSearch),
|
||||
SlidingSyncManager.ListSearch,
|
||||
expect.objectContaining({
|
||||
ranges: [
|
||||
[0, batchSize - 1],
|
||||
@@ -146,7 +209,7 @@ describe("SlidingSyncManager", () => {
|
||||
const gapMs = 1;
|
||||
const batchSize = 10;
|
||||
mocked(slidingSync.setList).mockRejectedValue("narp");
|
||||
mocked(slidingSync.getListData).mockImplementation((i) => {
|
||||
mocked(slidingSync.getListData).mockImplementation((key) => {
|
||||
return {
|
||||
joinedCount: 0,
|
||||
roomIndexToRoomId: {},
|
||||
@@ -156,7 +219,7 @@ describe("SlidingSyncManager", () => {
|
||||
expect(slidingSync.getListData).toBeCalledTimes(1);
|
||||
expect(slidingSync.setList).toBeCalledTimes(1);
|
||||
expect(slidingSync.setList).toBeCalledWith(
|
||||
manager.getOrAllocateListIndex(SlidingSyncManager.ListSearch),
|
||||
SlidingSyncManager.ListSearch,
|
||||
expect.objectContaining({
|
||||
ranges: [
|
||||
[0, batchSize - 1],
|
||||
|
111
test/hooks/useSlidingSyncRoomSearch-test.tsx
Normal file
111
test/hooks/useSlidingSyncRoomSearch-test.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { mocked } from "jest-mock";
|
||||
import { SlidingSync } from "matrix-js-sdk/src/sliding-sync";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { SlidingSyncRoomSearchOpts, useSlidingSyncRoomSearch } from "../../src/hooks/useSlidingSyncRoomSearch";
|
||||
import { MockEventEmitter, stubClient } from "../test-utils";
|
||||
import { SlidingSyncManager } from "../../src/SlidingSyncManager";
|
||||
|
||||
type RoomSearchHook = {
|
||||
loading: boolean;
|
||||
rooms: Room[];
|
||||
search(opts: SlidingSyncRoomSearchOpts): Promise<boolean>;
|
||||
};
|
||||
|
||||
// hooks must be inside a React component else you get:
|
||||
// "Invalid hook call. Hooks can only be called inside of the body of a function component."
|
||||
function RoomSearchComponent(props: { onClick: (h: RoomSearchHook) => void }) {
|
||||
const roomSearch = useSlidingSyncRoomSearch();
|
||||
return <div onClick={() => props.onClick(roomSearch)} />;
|
||||
}
|
||||
|
||||
describe("useSlidingSyncRoomSearch", () => {
|
||||
it("should display rooms when searching", async () => {
|
||||
const client = stubClient();
|
||||
const roomA = new Room("!a:localhost", client, client.getUserId()!);
|
||||
const roomB = new Room("!b:localhost", client, client.getUserId()!);
|
||||
const slidingSync = mocked(
|
||||
new MockEventEmitter({
|
||||
getListData: jest.fn(),
|
||||
}) as unknown as SlidingSync,
|
||||
);
|
||||
jest.spyOn(SlidingSyncManager.instance, "ensureListRegistered").mockResolvedValue({
|
||||
ranges: [[0, 9]],
|
||||
});
|
||||
SlidingSyncManager.instance.slidingSync = slidingSync;
|
||||
mocked(slidingSync.getListData).mockReturnValue({
|
||||
joinedCount: 2,
|
||||
roomIndexToRoomId: {
|
||||
0: roomA.roomId,
|
||||
1: roomB.roomId,
|
||||
},
|
||||
});
|
||||
mocked(client.getRoom).mockImplementation((roomId) => {
|
||||
switch (roomId) {
|
||||
case roomA.roomId:
|
||||
return roomA;
|
||||
case roomB.roomId:
|
||||
return roomB;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// first check that everything is empty and then do the search
|
||||
let executeHook = (roomSearch: RoomSearchHook) => {
|
||||
expect(roomSearch.loading).toBe(false);
|
||||
expect(roomSearch.rooms).toEqual([]);
|
||||
roomSearch.search({
|
||||
limit: 10,
|
||||
query: "foo",
|
||||
});
|
||||
};
|
||||
const wrapper = mount(
|
||||
<RoomSearchComponent
|
||||
onClick={(roomSearch: RoomSearchHook) => {
|
||||
executeHook(roomSearch);
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
// run the query
|
||||
await act(async () => {
|
||||
await sleep(1);
|
||||
wrapper.simulate("click");
|
||||
return act(() => sleep(1));
|
||||
});
|
||||
// now we expect there to be rooms
|
||||
executeHook = (roomSearch) => {
|
||||
expect(roomSearch.loading).toBe(false);
|
||||
expect(roomSearch.rooms).toEqual([roomA, roomB]);
|
||||
};
|
||||
|
||||
// run the query
|
||||
await act(async () => {
|
||||
await sleep(1);
|
||||
wrapper.simulate("click");
|
||||
return act(() => sleep(1));
|
||||
});
|
||||
});
|
||||
});
|
@@ -30,7 +30,7 @@ import { RoomViewStore } from "../../../src/stores/RoomViewStore";
|
||||
import { MatrixDispatcher } from "../../../src/dispatcher/dispatcher";
|
||||
import { SortAlgorithm } from "../../../src/stores/room-list/algorithms/models";
|
||||
import { DefaultTagID, TagID } from "../../../src/stores/room-list/models";
|
||||
import { UPDATE_SELECTED_SPACE } from "../../../src/stores/spaces";
|
||||
import { MetaSpace, UPDATE_SELECTED_SPACE } from "../../../src/stores/spaces";
|
||||
import { LISTS_LOADING_EVENT } from "../../../src/stores/room-list/RoomListStore";
|
||||
import { UPDATE_EVENT } from "../../../src/stores/AsyncStore";
|
||||
|
||||
@@ -42,7 +42,6 @@ describe("SlidingRoomListStore", () => {
|
||||
let context: TestSdkContext;
|
||||
let dis: MatrixDispatcher;
|
||||
let activeSpace: string;
|
||||
let tagIdToIndex = {};
|
||||
|
||||
beforeEach(async () => {
|
||||
context = new TestSdkContext();
|
||||
@@ -64,27 +63,6 @@ describe("SlidingRoomListStore", () => {
|
||||
getRoomId: jest.fn(),
|
||||
}) as unknown as RoomViewStore,
|
||||
);
|
||||
|
||||
// mock implementations to allow the store to map tag IDs to sliding sync list indexes and vice versa
|
||||
let index = 0;
|
||||
tagIdToIndex = {};
|
||||
mocked(context._SlidingSyncManager.getOrAllocateListIndex).mockImplementation((listId: string): number => {
|
||||
if (tagIdToIndex[listId] != null) {
|
||||
return tagIdToIndex[listId];
|
||||
}
|
||||
tagIdToIndex[listId] = index;
|
||||
index++;
|
||||
return index;
|
||||
});
|
||||
mocked(context.slidingSyncManager.listIdForIndex).mockImplementation((i) => {
|
||||
for (const tagId in tagIdToIndex) {
|
||||
const j = tagIdToIndex[tagId];
|
||||
if (i === j) {
|
||||
return tagId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
mocked(context._SlidingSyncManager.ensureListRegistered).mockResolvedValue({
|
||||
ranges: [[0, 10]],
|
||||
});
|
||||
@@ -104,17 +82,31 @@ describe("SlidingRoomListStore", () => {
|
||||
|
||||
// change the active space
|
||||
activeSpace = spaceRoomId;
|
||||
context._SpaceStore.emit(UPDATE_SELECTED_SPACE, spaceRoomId, false);
|
||||
context._SpaceStore!.emit(UPDATE_SELECTED_SPACE, spaceRoomId, false);
|
||||
await p;
|
||||
|
||||
expect(context._SlidingSyncManager.ensureListRegistered).toHaveBeenCalledWith(
|
||||
tagIdToIndex[DefaultTagID.Untagged],
|
||||
{
|
||||
filters: expect.objectContaining({
|
||||
spaces: [spaceRoomId],
|
||||
}),
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(DefaultTagID.Untagged, {
|
||||
filters: expect.objectContaining({
|
||||
spaces: [spaceRoomId],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("gracefully handles subspaces in the home metaspace", async () => {
|
||||
const subspace = "!sub:space";
|
||||
mocked(context._SpaceStore!.traverseSpace).mockImplementation(
|
||||
(spaceId: string, fn: (roomId: string) => void) => {
|
||||
fn(subspace);
|
||||
},
|
||||
);
|
||||
activeSpace = MetaSpace.Home;
|
||||
await store.start(); // call onReady
|
||||
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(DefaultTagID.Untagged, {
|
||||
filters: expect.objectContaining({
|
||||
spaces: [subspace],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("alters 'filters.spaces' on the DefaultTagID.Untagged list if it loads with an active space", async () => {
|
||||
@@ -126,8 +118,8 @@ describe("SlidingRoomListStore", () => {
|
||||
});
|
||||
await store.start(); // call onReady
|
||||
await p;
|
||||
expect(context._SlidingSyncManager.ensureListRegistered).toHaveBeenCalledWith(
|
||||
tagIdToIndex[DefaultTagID.Untagged],
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(
|
||||
DefaultTagID.Untagged,
|
||||
expect.objectContaining({
|
||||
filters: expect.objectContaining({
|
||||
spaces: [spaceRoomId],
|
||||
@@ -146,7 +138,7 @@ describe("SlidingRoomListStore", () => {
|
||||
return listName === DefaultTagID.Untagged && !isLoading;
|
||||
});
|
||||
|
||||
mocked(context._SpaceStore.traverseSpace).mockImplementation(
|
||||
mocked(context._SpaceStore!.traverseSpace).mockImplementation(
|
||||
(spaceId: string, fn: (roomId: string) => void) => {
|
||||
if (spaceId === spaceRoomId) {
|
||||
fn(subSpace1);
|
||||
@@ -157,31 +149,27 @@ describe("SlidingRoomListStore", () => {
|
||||
|
||||
// change the active space
|
||||
activeSpace = spaceRoomId;
|
||||
context._SpaceStore.emit(UPDATE_SELECTED_SPACE, spaceRoomId, false);
|
||||
context._SpaceStore!.emit(UPDATE_SELECTED_SPACE, spaceRoomId, false);
|
||||
await p;
|
||||
|
||||
expect(context._SlidingSyncManager.ensureListRegistered).toHaveBeenCalledWith(
|
||||
tagIdToIndex[DefaultTagID.Untagged],
|
||||
{
|
||||
filters: expect.objectContaining({
|
||||
spaces: [spaceRoomId, subSpace1, subSpace2],
|
||||
}),
|
||||
},
|
||||
);
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(DefaultTagID.Untagged, {
|
||||
filters: expect.objectContaining({
|
||||
spaces: [spaceRoomId, subSpace1, subSpace2],
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("setTagSorting alters the 'sort' option in the list", async () => {
|
||||
mocked(context._SlidingSyncManager.getOrAllocateListIndex).mockReturnValue(0);
|
||||
const tagId: TagID = "foo";
|
||||
await store.setTagSorting(tagId, SortAlgorithm.Alphabetic);
|
||||
expect(context._SlidingSyncManager.ensureListRegistered).toBeCalledWith(0, {
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toBeCalledWith(tagId, {
|
||||
sort: SlidingSyncSortToFilter[SortAlgorithm.Alphabetic],
|
||||
});
|
||||
expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Alphabetic);
|
||||
|
||||
await store.setTagSorting(tagId, SortAlgorithm.Recent);
|
||||
expect(context._SlidingSyncManager.ensureListRegistered).toBeCalledWith(0, {
|
||||
expect(context._SlidingSyncManager!.ensureListRegistered).toBeCalledWith(tagId, {
|
||||
sort: SlidingSyncSortToFilter[SortAlgorithm.Recent],
|
||||
});
|
||||
expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Recent);
|
||||
@@ -189,33 +177,31 @@ describe("SlidingRoomListStore", () => {
|
||||
|
||||
it("getTagsForRoom gets the tags for the room", async () => {
|
||||
await store.start();
|
||||
const untaggedIndex = context._SlidingSyncManager.getOrAllocateListIndex(DefaultTagID.Untagged);
|
||||
const favIndex = context._SlidingSyncManager.getOrAllocateListIndex(DefaultTagID.Favourite);
|
||||
const roomA = "!a:localhost";
|
||||
const roomB = "!b:localhost";
|
||||
const indexToListData = {
|
||||
[untaggedIndex]: {
|
||||
const keyToListData: Record<string, { joinedCount: number; roomIndexToRoomId: Record<number, string> }> = {
|
||||
[DefaultTagID.Untagged]: {
|
||||
joinedCount: 10,
|
||||
roomIndexToRoomId: {
|
||||
0: roomA,
|
||||
1: roomB,
|
||||
},
|
||||
},
|
||||
[favIndex]: {
|
||||
[DefaultTagID.Favourite]: {
|
||||
joinedCount: 2,
|
||||
roomIndexToRoomId: {
|
||||
0: roomB,
|
||||
},
|
||||
},
|
||||
};
|
||||
mocked(context._SlidingSyncManager.slidingSync.getListData).mockImplementation((i: number) => {
|
||||
return indexToListData[i] || null;
|
||||
mocked(context._SlidingSyncManager!.slidingSync.getListData).mockImplementation((key: string) => {
|
||||
return keyToListData[key] || null;
|
||||
});
|
||||
|
||||
expect(store.getTagsForRoom(new Room(roomA, context.client, context.client.getUserId()))).toEqual([
|
||||
expect(store.getTagsForRoom(new Room(roomA, context.client!, context.client!.getUserId()))).toEqual([
|
||||
DefaultTagID.Untagged,
|
||||
]);
|
||||
expect(store.getTagsForRoom(new Room(roomB, context.client, context.client.getUserId()))).toEqual([
|
||||
expect(store.getTagsForRoom(new Room(roomB, context.client!, context.client!.getUserId()))).toEqual([
|
||||
DefaultTagID.Favourite,
|
||||
DefaultTagID.Untagged,
|
||||
]);
|
||||
@@ -227,7 +213,6 @@ describe("SlidingRoomListStore", () => {
|
||||
const roomB = "!b:localhost";
|
||||
const roomC = "!c:localhost";
|
||||
const tagId = DefaultTagID.Favourite;
|
||||
const listIndex = context.slidingSyncManager.getOrAllocateListIndex(tagId);
|
||||
const joinCount = 10;
|
||||
const roomIndexToRoomId = {
|
||||
// mixed to ensure we sort
|
||||
@@ -236,11 +221,11 @@ describe("SlidingRoomListStore", () => {
|
||||
0: roomA,
|
||||
};
|
||||
const rooms = [
|
||||
new Room(roomA, context.client, context.client.getUserId()),
|
||||
new Room(roomB, context.client, context.client.getUserId()),
|
||||
new Room(roomC, context.client, context.client.getUserId()),
|
||||
new Room(roomA, context.client!, context.client!.getUserId()),
|
||||
new Room(roomB, context.client!, context.client!.getUserId()),
|
||||
new Room(roomC, context.client!, context.client!.getUserId()),
|
||||
];
|
||||
mocked(context.client.getRoom).mockImplementation((roomId: string) => {
|
||||
mocked(context.client!.getRoom).mockImplementation((roomId: string) => {
|
||||
switch (roomId) {
|
||||
case roomA:
|
||||
return rooms[0];
|
||||
@@ -252,7 +237,7 @@ describe("SlidingRoomListStore", () => {
|
||||
return null;
|
||||
});
|
||||
const p = untilEmission(store, LISTS_UPDATE_EVENT);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, listIndex, joinCount, roomIndexToRoomId);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, tagId, joinCount, roomIndexToRoomId);
|
||||
await p;
|
||||
expect(store.getCount(tagId)).toEqual(joinCount);
|
||||
expect(store.orderedLists[tagId]).toEqual(rooms);
|
||||
@@ -265,7 +250,6 @@ describe("SlidingRoomListStore", () => {
|
||||
const roomIdB = "!b:localhost";
|
||||
const roomIdC = "!c:localhost";
|
||||
const tagId = DefaultTagID.Favourite;
|
||||
const listIndex = context.slidingSyncManager.getOrAllocateListIndex(tagId);
|
||||
const joinCount = 10;
|
||||
const roomIndexToRoomId = {
|
||||
// mixed to ensure we sort
|
||||
@@ -273,10 +257,10 @@ describe("SlidingRoomListStore", () => {
|
||||
2: roomIdC,
|
||||
0: roomIdA,
|
||||
};
|
||||
const roomA = new Room(roomIdA, context.client, context.client.getUserId());
|
||||
const roomB = new Room(roomIdB, context.client, context.client.getUserId());
|
||||
const roomC = new Room(roomIdC, context.client, context.client.getUserId());
|
||||
mocked(context.client.getRoom).mockImplementation((roomId: string) => {
|
||||
const roomA = new Room(roomIdA, context.client!, context.client!.getUserId());
|
||||
const roomB = new Room(roomIdB, context.client!, context.client!.getUserId());
|
||||
const roomC = new Room(roomIdC, context.client!, context.client!.getUserId());
|
||||
mocked(context.client!.getRoom).mockImplementation((roomId: string) => {
|
||||
switch (roomId) {
|
||||
case roomIdA:
|
||||
return roomA;
|
||||
@@ -287,8 +271,8 @@ describe("SlidingRoomListStore", () => {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
mocked(context._SlidingSyncManager.slidingSync.getListData).mockImplementation((i: number) => {
|
||||
if (i !== listIndex) {
|
||||
mocked(context._SlidingSyncManager!.slidingSync.getListData).mockImplementation((key: string) => {
|
||||
if (key !== tagId) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
@@ -297,7 +281,7 @@ describe("SlidingRoomListStore", () => {
|
||||
};
|
||||
});
|
||||
let p = untilEmission(store, LISTS_UPDATE_EVENT);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, listIndex, joinCount, roomIndexToRoomId);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, tagId, joinCount, roomIndexToRoomId);
|
||||
await p;
|
||||
expect(store.orderedLists[tagId]).toEqual([roomA, roomB, roomC]);
|
||||
|
||||
@@ -310,7 +294,7 @@ describe("SlidingRoomListStore", () => {
|
||||
roomIndexToRoomId[1] = roomIdA;
|
||||
roomIndexToRoomId[2] = roomIdB;
|
||||
p = untilEmission(store, LISTS_UPDATE_EVENT);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, listIndex, joinCount, roomIndexToRoomId);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, tagId, joinCount, roomIndexToRoomId);
|
||||
await p;
|
||||
|
||||
// check that B didn't move and that A was put below B
|
||||
@@ -323,4 +307,43 @@ describe("SlidingRoomListStore", () => {
|
||||
await p;
|
||||
expect(store.orderedLists[tagId].map((r) => r.roomId)).toEqual([roomC, roomA, roomB].map((r) => r.roomId));
|
||||
});
|
||||
|
||||
it("gracefully handles unknown room IDs", async () => {
|
||||
await store.start();
|
||||
const roomIdA = "!a:localhost";
|
||||
const roomIdB = "!b:localhost"; // does not exist
|
||||
const roomIdC = "!c:localhost";
|
||||
const roomIndexToRoomId = {
|
||||
0: roomIdA,
|
||||
1: roomIdB, // does not exist
|
||||
2: roomIdC,
|
||||
};
|
||||
const tagId = DefaultTagID.Favourite;
|
||||
const joinCount = 10;
|
||||
// seed the store with 2 rooms
|
||||
const roomA = new Room(roomIdA, context.client!, context.client!.getUserId());
|
||||
const roomC = new Room(roomIdC, context.client!, context.client!.getUserId());
|
||||
mocked(context.client!.getRoom).mockImplementation((roomId: string) => {
|
||||
switch (roomId) {
|
||||
case roomIdA:
|
||||
return roomA;
|
||||
case roomIdC:
|
||||
return roomC;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
mocked(context._SlidingSyncManager!.slidingSync.getListData).mockImplementation((key: string) => {
|
||||
if (key !== tagId) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
roomIndexToRoomId: roomIndexToRoomId,
|
||||
joinedCount: joinCount,
|
||||
};
|
||||
});
|
||||
const p = untilEmission(store, LISTS_UPDATE_EVENT);
|
||||
context.slidingSyncManager.slidingSync.emit(SlidingSyncEvent.List, tagId, joinCount, roomIndexToRoomId);
|
||||
await p;
|
||||
expect(store.orderedLists[tagId]).toEqual([roomA, roomC]);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user