New room list: add notification options menu (#29639)
* feat: add `utils.hasAccessToNotificationMenu` * feat(room list item view model): use `hasAccessToNotificationMenu` to compute `showHoverMenu` * feat(room list item menu view model): add notification options menu attributes * feat(room list item menu view): add notification options * test: add tests for `utils.hasAccessToNotificationMenu` * test(room list item view model): add test for `showHoverMenu` * test(room list item menu view model): add tests for new attributes * test(room list item menu view): add tests for notification options menu * chore: update i18n * test(e2e): update screenshots * test(e2e): add tests for notification options menu
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
import type { MatrixClient, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { mkRoom, stubClient } from "../../../../../test-utils";
|
||||
import { RoomListItemMenuView } from "../../../../../../src/components/views/rooms/RoomListPanel/RoomListItemMenuView";
|
||||
import { RoomNotifState } from "../../../../../../src/RoomNotifs";
|
||||
|
||||
jest.mock("../../../../../../src/components/viewmodels/roomlist/RoomListItemMenuViewModel", () => ({
|
||||
useRoomListItemMenuViewModel: jest.fn(),
|
||||
@@ -25,11 +26,16 @@ jest.mock("../../../../../../src/components/viewmodels/roomlist/RoomListItemMenu
|
||||
describe("<RoomListItemMenuView />", () => {
|
||||
const defaultValue: RoomListItemMenuViewState = {
|
||||
showMoreOptionsMenu: true,
|
||||
showNotificationMenu: true,
|
||||
isFavourite: true,
|
||||
canInvite: true,
|
||||
canMarkAsUnread: true,
|
||||
canMarkAsRead: true,
|
||||
canCopyRoomLink: true,
|
||||
isNotificationAllMessage: true,
|
||||
isNotificationMentionOnly: true,
|
||||
isNotificationAllMessageLoud: true,
|
||||
isNotificationMute: true,
|
||||
copyRoomLink: jest.fn(),
|
||||
markAsUnread: jest.fn(),
|
||||
markAsRead: jest.fn(),
|
||||
@@ -37,6 +43,7 @@ describe("<RoomListItemMenuView />", () => {
|
||||
toggleLowPriority: jest.fn(),
|
||||
toggleFavorite: jest.fn(),
|
||||
invite: jest.fn(),
|
||||
setRoomNotifState: jest.fn(),
|
||||
};
|
||||
|
||||
let matrixClient: MatrixClient;
|
||||
@@ -58,22 +65,37 @@ describe("<RoomListItemMenuView />", () => {
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render the notification options menu", () => {
|
||||
const { asFragment } = renderMenu();
|
||||
expect(screen.getByRole("button", { name: "Notification options" })).toBeInTheDocument();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should not render the more options menu when showMoreOptionsMenu is false", () => {
|
||||
mocked(useRoomListItemMenuViewModel).mockReturnValue({ ...defaultValue, showMoreOptionsMenu: false });
|
||||
renderMenu();
|
||||
expect(screen.queryByRole("button", { name: "More Options" })).toBeNull();
|
||||
});
|
||||
|
||||
it("should call setMenuOpen when the menu is opened", async () => {
|
||||
const user = userEvent.setup();
|
||||
const setMenuOpen = jest.fn();
|
||||
renderMenu(setMenuOpen);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "More Options" }));
|
||||
expect(setMenuOpen).toHaveBeenCalledWith(true);
|
||||
it("should not render the notification options menu when showNotificationMenu is false", () => {
|
||||
mocked(useRoomListItemMenuViewModel).mockReturnValue({ ...defaultValue, showNotificationMenu: false });
|
||||
renderMenu();
|
||||
expect(screen.queryByRole("button", { name: "Notification options" })).toBeNull();
|
||||
});
|
||||
|
||||
it("should display all the buttons and have the actions linked", async () => {
|
||||
it.each([["More Options"], ["Notification options"]])(
|
||||
"should call setMenuOpen when the menu is opened for %s menu",
|
||||
async (label) => {
|
||||
const user = userEvent.setup();
|
||||
const setMenuOpen = jest.fn();
|
||||
renderMenu(setMenuOpen);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: label }));
|
||||
expect(setMenuOpen).toHaveBeenCalledWith(true);
|
||||
},
|
||||
);
|
||||
|
||||
it("should display all the buttons and have the actions linked for the more options menu", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderMenu();
|
||||
|
||||
@@ -107,4 +129,27 @@ describe("<RoomListItemMenuView />", () => {
|
||||
await user.click(screen.getByRole("menuitem", { name: "Leave room" }));
|
||||
expect(defaultValue.leaveRoom).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should display all the buttons and have the actions linked for the notification options menu", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderMenu();
|
||||
|
||||
const openMenu = screen.getByRole("button", { name: "Notification options" });
|
||||
await user.click(openMenu);
|
||||
|
||||
await user.click(screen.getByRole("menuitem", { name: "Match default settings" }));
|
||||
expect(defaultValue.setRoomNotifState).toHaveBeenCalledWith(RoomNotifState.AllMessages);
|
||||
|
||||
await user.click(openMenu);
|
||||
await user.click(screen.getByRole("menuitem", { name: "All messages" }));
|
||||
expect(defaultValue.setRoomNotifState).toHaveBeenCalledWith(RoomNotifState.AllMessagesLoud);
|
||||
|
||||
await user.click(openMenu);
|
||||
await user.click(screen.getByRole("menuitem", { name: "Mentions and keywords" }));
|
||||
expect(defaultValue.setRoomNotifState).toHaveBeenCalledWith(RoomNotifState.MentionsOnly);
|
||||
|
||||
await user.click(openMenu);
|
||||
await user.click(screen.getByRole("menuitem", { name: "Mute room" }));
|
||||
expect(defaultValue.setRoomNotifState).toHaveBeenCalledWith(RoomNotifState.Mute);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,6 +37,115 @@ exports[`<RoomListItemMenuView /> should render the more options menu 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
aria-label="Notification options"
|
||||
aria-labelledby=":r9:"
|
||||
class="_icon-button_m2erp_8"
|
||||
data-state="closed"
|
||||
id="radix-:r7:"
|
||||
role="button"
|
||||
style="--cpd-icon-button-size: 24px;"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_zr2a0_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="m4.917 2.083 17 17a1 1 0 0 1-1.414 1.414L19.006 19H4.414c-.89 0-1.337-1.077-.707-1.707L5 16v-6s0-2.034 1.096-3.91L3.504 3.498a1 1 0 0 1 1.414-1.414M19 13.35 9.136 3.484C9.93 3.181 10.874 3 12 3c7 0 7 7 7 7z"
|
||||
/>
|
||||
<path
|
||||
d="M10 20h4a2 2 0 0 1-4 0"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<RoomListItemMenuView /> should render the notification options menu 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_Flex mx_RoomListItemMenuView"
|
||||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-0-5x); --mx-flex-wrap: nowrap;"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
aria-label="More Options"
|
||||
aria-labelledby=":ri:"
|
||||
class="_icon-button_m2erp_8"
|
||||
data-state="closed"
|
||||
id="radix-:rg:"
|
||||
role="button"
|
||||
style="--cpd-icon-button-size: 24px;"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_zr2a0_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
aria-label="Notification options"
|
||||
aria-labelledby=":rp:"
|
||||
class="_icon-button_m2erp_8"
|
||||
data-state="closed"
|
||||
id="radix-:rn:"
|
||||
role="button"
|
||||
style="--cpd-icon-button-size: 24px;"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_zr2a0_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="m4.917 2.083 17 17a1 1 0 0 1-1.414 1.414L19.006 19H4.414c-.89 0-1.337-1.077-.707-1.707L5 16v-6s0-2.034 1.096-3.91L3.504 3.498a1 1 0 0 1 1.414-1.414M19 13.35 9.136 3.484C9.93 3.181 10.874 3 12 3c7 0 7 7 7 7z"
|
||||
/>
|
||||
<path
|
||||
d="M10 20h4a2 2 0 0 1-4 0"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user