/* Copyright 2024 New Vector Ltd. Copyright 2022 The Matrix.org Foundation C.I.C. Copyright 2021 Šimon Brandner SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ import React from "react"; import { act, fireEvent, screen, waitFor } from "jest-matrix-react"; import { RoomMember, User, RoomEvent } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { mocked } from "jest-mock"; import { shouldShowComponent } from "../../../../../../src/customisations/helpers/UIComponents"; import defaultDispatcher from "../../../../../../src/dispatcher/dispatcher"; import { Rendered, renderMemberList } from "./common"; jest.mock("../../../../../../src/customisations/helpers/UIComponents", () => ({ shouldShowComponent: jest.fn(), })); type Children = (args: { height: number; width: number }) => React.JSX.Element; jest.mock("react-virtualized", () => { const ReactVirtualized = jest.requireActual("react-virtualized"); return { ...ReactVirtualized, AutoSizer: ({ children }: { children: Children }) => children({ height: 1000, width: 1000 }), }; }); jest.spyOn(HTMLElement.prototype, "offsetHeight", "get").mockReturnValue(1500); jest.spyOn(HTMLElement.prototype, "offsetWidth", "get").mockReturnValue(1500); describe("Does not render invite button in memberlist header", () => { it("when user is not a member", async () => { await renderMemberList(true, (room) => room.updateMyMembership(KnownMembership.Leave)); expect(screen.queryByRole("button", { name: "Invite" })).toBeNull(); }); it("when UI customisation hides invites", async () => { mocked(shouldShowComponent).mockReturnValue(false); const { client, memberListRoom } = await renderMemberList(true); // Needs this specific event... act(() => { client.emit(RoomEvent.MyMembership, memberListRoom, KnownMembership.Join, KnownMembership.Invite); }); await waitFor(() => expect(screen.queryByRole("button", { name: "Invite" })).toBeNull()); }); }); describe("MemberListHeaderView", () => { let rendered: Rendered; beforeEach(async function () { mocked(shouldShowComponent).mockReturnValue(true); rendered = await renderMemberList(true); }); it("Shows the correct member count", async () => { expect(await screen.findByText("6 Members")).toBeVisible(); }); it("Does not show search box when there's less than 20 members", async () => { expect(screen.queryByPlaceholderText("Filter room members")).toBeNull(); }); it("Shows search box when there's more than 20 members", async () => { const { memberListRoom, client, reRender } = rendered; // Memberlist already has 6 members, add 14 more to make the total 20 for (let i = 0; i < 14; ++i) { const newMember = new RoomMember(memberListRoom.roomId, `@new${i}:localhost`); newMember.membership = KnownMembership.Join; newMember.powerLevel = 0; newMember.user = User.createUser(newMember.userId, client); newMember.user.currentlyActive = true; newMember.user.presence = "online"; newMember.user.lastPresenceTs = 1000; newMember.user.lastActiveAgo = 10; memberListRoom.currentState.members[newMember.userId] = newMember; } await reRender(); expect(screen.queryByPlaceholderText("Filter room members")).toBeVisible(); }); describe("Invite button functionality", () => { afterEach(() => { jest.restoreAllMocks(); }); it("Renders disabled invite button when current user is a member but does not have rights to invite", async () => { const { memberListRoom, reRender } = rendered; jest.spyOn(memberListRoom, "getMyMembership").mockReturnValue(KnownMembership.Join); jest.spyOn(memberListRoom, "canInvite").mockReturnValue(false); await reRender(); expect(screen.getByRole("button", { name: "Invite" })).toHaveAttribute("aria-disabled", "true"); }); it("Renders enabled invite button when current user is a member and has rights to invite", async () => { const { memberListRoom, reRender } = rendered; jest.spyOn(memberListRoom, "getMyMembership").mockReturnValue(KnownMembership.Join); jest.spyOn(memberListRoom, "canInvite").mockReturnValue(true); await reRender(); expect(screen.getByRole("button", { name: "Invite" })).not.toHaveAttribute("aria-disabled", "true"); }); it("Opens room inviter on button click", async () => { const { memberListRoom, reRender } = rendered; jest.spyOn(defaultDispatcher, "dispatch"); jest.spyOn(memberListRoom, "canInvite").mockReturnValue(true); await reRender(); fireEvent.click(screen.getByRole("button", { name: "Invite" })); expect(defaultDispatcher.dispatch).toHaveBeenCalledWith({ action: "view_invite", roomId: memberListRoom.roomId, }); }); }); });