New room list: fix missing/incorrect notification decoration (#29796)

* fix: recompute notification when room change in room list item vm

* test: add use case when room list change

* test(e2e): add screenshot to unread filter test
This commit is contained in:
Florian Duros
2025-04-22 15:21:50 +02:00
committed by GitHub
parent f6a3a429f7
commit 5933f50930
4 changed files with 47 additions and 18 deletions

View File

@@ -140,29 +140,35 @@ test.describe("Room list filters and sort", () => {
expect(await roomList.locator("role=gridcell").count()).toBe(3);
});
test("unread filter should only match unread rooms that have a count", async ({ page, app, bot }) => {
const roomListView = getRoomList(page);
test(
"unread filter should only match unread rooms that have a count",
{ tag: "@screenshot" },
async ({ page, app, bot }) => {
const roomListView = getRoomList(page);
// Let's configure unread dm room so that we only get notification for mentions and keywords
await app.viewRoomById(unReadDmId);
await app.settings.openRoomSettings("Notifications");
await page.getByText("@mentions & keywords").click();
await app.settings.closeDialog();
// Let's configure unread dm room so that we only get notification for mentions and keywords
await app.viewRoomById(unReadDmId);
await app.settings.openRoomSettings("Notifications");
await page.getByText("@mentions & keywords").click();
await app.settings.closeDialog();
// Let's open a room other than unread room or unread dm
await roomListView.getByRole("gridcell", { name: "Open room favourite room" }).click();
// Let's open a room other than unread room or unread dm
await roomListView.getByRole("gridcell", { name: "Open room favourite room" }).click();
// Let's make the bot send a new message in both rooms
await bot.sendMessage(unReadDmId, "Hello!");
await bot.sendMessage(unReadRoomId, "Hello!");
// Let's make the bot send a new message in both rooms
await bot.sendMessage(unReadDmId, "Hello!");
await bot.sendMessage(unReadRoomId, "Hello!");
// Let's activate the unread filter now
await page.getByRole("option", { name: "Unread" }).click();
// Let's activate the unread filter now
await page.getByRole("option", { name: "Unread" }).click();
// Unread filter should only show unread room and not unread dm!
await expect(roomListView.getByRole("gridcell", { name: "Open room unread room" })).toBeVisible();
await expect(roomListView.getByRole("gridcell", { name: "Open room unread dm" })).not.toBeVisible();
});
// Unread filter should only show unread room and not unread dm!
const unreadDm = roomListView.getByRole("gridcell", { name: "Open room unread room" });
await expect(unreadDm).toBeVisible();
await expect(unreadDm).toMatchScreenshot("unread-dm.png");
await expect(roomListView.getByRole("gridcell", { name: "Open room unread dm" })).not.toBeVisible();
},
);
});
test.describe("Empty room list", () => {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -92,6 +92,11 @@ export function useRoomListItemViewModel(room: Room): RoomListItemViewState {
setNotificationValues(getNotificationValues(notificationState));
});
// If the notification reference change due to room change, update the values
useEffect(() => {
setNotificationValues(getNotificationValues(notificationState));
}, [notificationState]);
// We don't want to show the hover menu if
// - there is an invitation for this room
// - the user doesn't have access to both notification and more options menus

View File

@@ -128,6 +128,24 @@ describe("RoomListItemViewModel", () => {
);
expect(vm.current.isBold).toBe(true);
});
it("should recompute notification state when room changes", () => {
const newRoom = mkStubRoom("room2", "Room 2", room.client);
const newNotificationState = new RoomNotificationState(newRoom, false);
const { result, rerender } = renderHook((room) => useRoomListItemViewModel(room), {
...withClientContextRenderOptions(room.client),
initialProps: room,
});
expect(result.current.showNotificationDecoration).toBe(false);
jest.spyOn(newNotificationState, "hasAnyNotificationOrActivity", "get").mockReturnValue(true);
jest.spyOn(RoomNotificationStateStore.instance, "getRoomState").mockReturnValue(newNotificationState);
rerender(newRoom);
expect(result.current.showNotificationDecoration).toBe(true);
});
});
describe("a11yLabel", () => {