From a5d9c33b0c015e4f6d81406bbbe6f9efaccd9c2e Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 1 Feb 2024 18:22:30 +0000 Subject: [PATCH 1/2] Add test for the ThreadsActivityCentre component --- .../spaces/ThreadsActivityCentre-test.tsx | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 test/components/views/spaces/ThreadsActivityCentre-test.tsx diff --git a/test/components/views/spaces/ThreadsActivityCentre-test.tsx b/test/components/views/spaces/ThreadsActivityCentre-test.tsx new file mode 100644 index 00000000000..9f2efabbc49 --- /dev/null +++ b/test/components/views/spaces/ThreadsActivityCentre-test.tsx @@ -0,0 +1,143 @@ +/* + * + * Copyright 2024 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. + * / + */ + +import React from "react"; +import { getByText, render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { NotificationCountType, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix"; + +import { ThreadsActivityCentre } from "../../../../src/components/views/spaces/threads-activity-centre"; +import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; +import MatrixClientContext from "../../../../src/contexts/MatrixClientContext"; +import { stubClient } from "../../../test-utils"; +import { populateThread } from "../../../test-utils/threads"; +import DMRoomMap from "../../../../src/utils/DMRoomMap"; + +describe("ThreadsActivityCentre", () => { + const getTACButton = () => { + return screen.getByRole("button", { name: "Threads" }); + }; + + const getTACMenu = () => { + return screen.getByRole("menu"); + }; + + const renderTAC = () => { + render( + + + ); + , + ); + }; + + const cli = stubClient(); + cli.supportsThreads = () => true; + + beforeAll(() => { + jest.spyOn(MatrixClientPeg, "get").mockReturnValue(cli); + jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(cli); + + const dmRoomMap = new DMRoomMap(cli); + jest.spyOn(dmRoomMap, "getUserIdForRoomId"); + jest.spyOn(DMRoomMap, "shared").mockReturnValue(dmRoomMap); + }); + + it("should render the threads activity centre button", async () => { + renderTAC(); + expect(getTACButton()).toBeInTheDocument(); + }); + + it("should render the threads activity centre menu when the button is clicked", async () => { + renderTAC(); + await userEvent.click(getTACButton()); + expect(getTACMenu()).toBeInTheDocument(); + }); + + it("should render a room with a activity in the TAC", async () => { + const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithHighlight.name = "Just activity"; + await populateThread({ + room: roomWithHighlight, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); + renderTAC(); + await userEvent.click(getTACButton()); + + const tacRows = screen.getAllByRole("menuitem"); + expect(tacRows.length).toEqual(1); + + getByText(tacRows[0], "Just activity"); + expect(tacRows[0].getElementsByClassName("mx_NotificationBadge").length).toEqual(1); + expect(tacRows[0].getElementsByClassName("mx_NotificationBadge_level_notification").length).toEqual(0); + }); + + it("should render a room with a regular notification in the TAC", async () => { + const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithHighlight.name = "A notification"; + const threadInfo = await populateThread({ + room: roomWithHighlight, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + roomWithHighlight.setThreadUnreadNotificationCount(threadInfo.thread.id, NotificationCountType.Total, 1); + + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); + renderTAC(); + await userEvent.click(getTACButton()); + + const tacRows = screen.getAllByRole("menuitem"); + expect(tacRows.length).toEqual(1); + + getByText(tacRows[0], "A notification"); + expect(tacRows[0].getElementsByClassName("mx_NotificationBadge_level_notification").length).toEqual(1); + }); + + it("should render a room with a highlight notification in the TAC", async () => { + const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithHighlight.name = "This is a real highlight"; + const threadInfo = await populateThread({ + room: roomWithHighlight, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + roomWithHighlight.setThreadUnreadNotificationCount(threadInfo.thread.id, NotificationCountType.Highlight, 1); + + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); + renderTAC(); + await userEvent.click(getTACButton()); + + const tacRows = screen.getAllByRole("menuitem"); + expect(tacRows.length).toEqual(1); + + getByText(tacRows[0], "This is a real highlight"); + expect(tacRows[0].getElementsByClassName("mx_NotificationBadge_level_highlight").length).toEqual(1); + }); +}); From 6b0e7597c5171e7723820579bcc3a63ebad3a13a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 2 Feb 2024 11:04:50 +0000 Subject: [PATCH 2/2] Add snapshot test --- .../spaces/ThreadsActivityCentre-test.tsx | 91 +++++---- .../ThreadsActivityCentre-test.tsx.snap | 177 ++++++++++++++++++ 2 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 test/components/views/spaces/__snapshots__/ThreadsActivityCentre-test.tsx.snap diff --git a/test/components/views/spaces/ThreadsActivityCentre-test.tsx b/test/components/views/spaces/ThreadsActivityCentre-test.tsx index 9f2efabbc49..ce730550ea5 100644 --- a/test/components/views/spaces/ThreadsActivityCentre-test.tsx +++ b/test/components/views/spaces/ThreadsActivityCentre-test.tsx @@ -49,13 +49,55 @@ describe("ThreadsActivityCentre", () => { const cli = stubClient(); cli.supportsThreads = () => true; - beforeAll(() => { + const roomWithActivity = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithActivity.name = "Just activity"; + + const roomWithNotif = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithNotif.name = "A notification"; + + const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + roomWithHighlight.name = "This is a real highlight"; + + beforeAll(async () => { jest.spyOn(MatrixClientPeg, "get").mockReturnValue(cli); jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(cli); const dmRoomMap = new DMRoomMap(cli); jest.spyOn(dmRoomMap, "getUserIdForRoomId"); jest.spyOn(DMRoomMap, "shared").mockReturnValue(dmRoomMap); + + await populateThread({ + room: roomWithActivity, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + + const notifThreadInfo = await populateThread({ + room: roomWithNotif, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + roomWithNotif.setThreadUnreadNotificationCount(notifThreadInfo.thread.id, NotificationCountType.Total, 1); + + const highlightThreadInfo = await populateThread({ + room: roomWithHighlight, + client: cli, + authorId: "@foo:bar", + participantUserIds: ["@fee:bar"], + }); + roomWithHighlight.setThreadUnreadNotificationCount( + highlightThreadInfo.thread.id, + NotificationCountType.Highlight, + 1, + ); }); it("should render the threads activity centre button", async () => { @@ -70,18 +112,7 @@ describe("ThreadsActivityCentre", () => { }); it("should render a room with a activity in the TAC", async () => { - const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { - pendingEventOrdering: PendingEventOrdering.Detached, - }); - roomWithHighlight.name = "Just activity"; - await populateThread({ - room: roomWithHighlight, - client: cli, - authorId: "@foo:bar", - participantUserIds: ["@fee:bar"], - }); - - cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithActivity]); renderTAC(); await userEvent.click(getTACButton()); @@ -94,19 +125,7 @@ describe("ThreadsActivityCentre", () => { }); it("should render a room with a regular notification in the TAC", async () => { - const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { - pendingEventOrdering: PendingEventOrdering.Detached, - }); - roomWithHighlight.name = "A notification"; - const threadInfo = await populateThread({ - room: roomWithHighlight, - client: cli, - authorId: "@foo:bar", - participantUserIds: ["@fee:bar"], - }); - roomWithHighlight.setThreadUnreadNotificationCount(threadInfo.thread.id, NotificationCountType.Total, 1); - - cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithNotif]); renderTAC(); await userEvent.click(getTACButton()); @@ -118,18 +137,6 @@ describe("ThreadsActivityCentre", () => { }); it("should render a room with a highlight notification in the TAC", async () => { - const roomWithHighlight = new Room("!room:server", cli, cli.getSafeUserId(), { - pendingEventOrdering: PendingEventOrdering.Detached, - }); - roomWithHighlight.name = "This is a real highlight"; - const threadInfo = await populateThread({ - room: roomWithHighlight, - client: cli, - authorId: "@foo:bar", - participantUserIds: ["@fee:bar"], - }); - roomWithHighlight.setThreadUnreadNotificationCount(threadInfo.thread.id, NotificationCountType.Highlight, 1); - cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight]); renderTAC(); await userEvent.click(getTACButton()); @@ -140,4 +147,12 @@ describe("ThreadsActivityCentre", () => { getByText(tacRows[0], "This is a real highlight"); expect(tacRows[0].getElementsByClassName("mx_NotificationBadge_level_highlight").length).toEqual(1); }); + + it("renders notifications matching the snapshot", async () => { + cli.getVisibleRooms = jest.fn().mockReturnValue([roomWithHighlight, roomWithNotif, roomWithActivity]); + renderTAC(); + await userEvent.click(getTACButton()); + + expect(screen.getByRole("menu")).toMatchSnapshot(); + }); }); diff --git a/test/components/views/spaces/__snapshots__/ThreadsActivityCentre-test.tsx.snap b/test/components/views/spaces/__snapshots__/ThreadsActivityCentre-test.tsx.snap new file mode 100644 index 00000000000..5214cf18a95 --- /dev/null +++ b/test/components/views/spaces/__snapshots__/ThreadsActivityCentre-test.tsx.snap @@ -0,0 +1,177 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] = ` + +`;