Merge branch 'develop' into andybalaam/stas-demydiuk-membership-type3
This commit is contained in:
commit
d7bdbee8d2
124 changed files with 2399 additions and 1052 deletions
|
@ -141,10 +141,28 @@ describe("RoomGeneralContextMenu", () => {
|
|||
const markAsReadBtn = getByLabelText(container, "Mark as read");
|
||||
fireEvent.click(markAsReadBtn);
|
||||
|
||||
await new Promise(setImmediate);
|
||||
|
||||
expect(mockClient.sendReadReceipt).toHaveBeenCalledWith(event, ReceiptType.Read, true);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("marks the room as unread", async () => {
|
||||
room.updateMyMembership("join");
|
||||
|
||||
const { container } = getComponent({});
|
||||
|
||||
const markAsUnreadBtn = getByLabelText(container, "Mark as unread");
|
||||
fireEvent.click(markAsUnreadBtn);
|
||||
|
||||
await new Promise(setImmediate);
|
||||
|
||||
expect(mockClient.setRoomAccountData).toHaveBeenCalledWith(ROOM_ID, "com.famedly.marked_unread", {
|
||||
unread: true,
|
||||
});
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("when developer mode is disabled, it should not render the developer tools option", () => {
|
||||
getComponent();
|
||||
expect(screen.queryByText("Developer tools")).not.toBeInTheDocument();
|
||||
|
|
|
@ -15,22 +15,24 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { render } from "@testing-library/react";
|
||||
import { render, waitFor } from "@testing-library/react";
|
||||
import hljs, { type HighlightOptions } from "highlight.js";
|
||||
import React from "react";
|
||||
|
||||
import SyntaxHighlight from "../../../../src/components/views/elements/SyntaxHighlight";
|
||||
|
||||
describe("<SyntaxHighlight />", () => {
|
||||
it("renders", () => {
|
||||
it("renders", async () => {
|
||||
const { container } = render(<SyntaxHighlight>console.log("Hello, World!");</SyntaxHighlight>);
|
||||
await waitFor(() => expect(container.querySelector(".language-arcade")).toBeTruthy());
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it.each(["json", "javascript", "css"])("uses the provided language", (lang) => {
|
||||
it.each(["json", "javascript", "css"])("uses the provided language", async (lang) => {
|
||||
const mock = jest.spyOn(hljs, "highlight");
|
||||
|
||||
render(<SyntaxHighlight language={lang}>// Hello, World</SyntaxHighlight>);
|
||||
const { container } = render(<SyntaxHighlight language={lang}>// Hello, World</SyntaxHighlight>);
|
||||
await waitFor(() => expect(container.querySelector(`.language-${lang}`)).toBeTruthy());
|
||||
|
||||
const [_lang, opts] = mock.mock.lastCall!;
|
||||
expect((opts as HighlightOptions)["language"]).toBe(lang);
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
RoomStateEvent,
|
||||
PendingEventOrdering,
|
||||
ISearchResults,
|
||||
IContent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { CallType } from "matrix-js-sdk/src/webrtc/call";
|
||||
|
@ -112,7 +113,7 @@ describe("LegacyRoomHeader", () => {
|
|||
room: roomId,
|
||||
user: alice.userId,
|
||||
skey: stateKey,
|
||||
content,
|
||||
content: content as IContent,
|
||||
});
|
||||
room.addLiveEvents([event]);
|
||||
return { event_id: event.getId()! };
|
||||
|
|
|
@ -20,8 +20,41 @@ import React from "react";
|
|||
import { StatelessNotificationBadge } from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
|
||||
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||
import NotificationBadge from "../../../../../src/components/views/rooms/NotificationBadge";
|
||||
import { NotificationState } from "../../../../../src/stores/notifications/NotificationState";
|
||||
|
||||
class DummyNotificationState extends NotificationState {
|
||||
constructor(level: NotificationLevel) {
|
||||
super();
|
||||
this._level = level;
|
||||
}
|
||||
}
|
||||
|
||||
describe("NotificationBadge", () => {
|
||||
it("shows a dot if the level is activity", () => {
|
||||
const notif = new DummyNotificationState(NotificationLevel.Activity);
|
||||
|
||||
const { container } = render(<NotificationBadge roomId="!foo:bar" notification={notif} />);
|
||||
expect(container.querySelector(".mx_NotificationBadge_dot")).toBeInTheDocument();
|
||||
expect(container.querySelector(".mx_NotificationBadge")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not show a dot if the level is activity and hideIfDot is true", () => {
|
||||
const notif = new DummyNotificationState(NotificationLevel.Activity);
|
||||
|
||||
const { container } = render(<NotificationBadge roomId="!foo:bar" notification={notif} hideIfDot={true} />);
|
||||
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
|
||||
expect(container.querySelector(".mx_NotificationBadge")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("still shows an empty badge if hideIfDot us true", () => {
|
||||
const notif = new DummyNotificationState(NotificationLevel.Notification);
|
||||
|
||||
const { container } = render(<NotificationBadge roomId="!foo:bar" notification={notif} hideIfDot={true} />);
|
||||
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
|
||||
expect(container.querySelector(".mx_NotificationBadge")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe("StatelessNotificationBadge", () => {
|
||||
it("lets you click it", () => {
|
||||
const cb = jest.fn();
|
||||
|
|
|
@ -36,6 +36,13 @@ describe("StatelessNotificationBadge", () => {
|
|||
expect(container.querySelector(".mx_NotificationBadge_knocked")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("has dot style for activity", () => {
|
||||
const { container } = render(
|
||||
<StatelessNotificationBadge symbol={null} count={3} level={NotificationLevel.Activity} />,
|
||||
);
|
||||
expect(container.querySelector(".mx_NotificationBadge_dot")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("has badge style for notification", () => {
|
||||
const { container } = render(
|
||||
<StatelessNotificationBadge symbol={null} count={3} level={NotificationLevel.Notification} />,
|
||||
|
|
120
test/components/views/settings/PowerLevelSelector-test.tsx
Normal file
120
test/components/views/settings/PowerLevelSelector-test.tsx
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
*
|
||||
* 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 { render, screen } from "@testing-library/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import { PowerLevelSelector } from "../../../../src/components/views/settings/PowerLevelSelector";
|
||||
import { stubClient } from "../../../test-utils";
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
|
||||
describe("PowerLevelSelector", () => {
|
||||
const matrixClient = stubClient();
|
||||
|
||||
const currentUser = matrixClient.getUserId()!;
|
||||
const userLevels = {
|
||||
[currentUser]: 100,
|
||||
"@alice:server.org": 50,
|
||||
"@bob:server.org": 0,
|
||||
};
|
||||
|
||||
const renderPLS = (props: Partial<ComponentProps<typeof PowerLevelSelector>>) =>
|
||||
render(
|
||||
<MatrixClientContext.Provider value={matrixClient}>
|
||||
<PowerLevelSelector
|
||||
userLevels={userLevels}
|
||||
canChangeLevels={true}
|
||||
currentUserLevel={userLevels[currentUser]}
|
||||
title="title"
|
||||
// filter nothing by default
|
||||
filter={() => true}
|
||||
onClick={jest.fn()}
|
||||
{...props}
|
||||
>
|
||||
empty label
|
||||
</PowerLevelSelector>
|
||||
</MatrixClientContext.Provider>,
|
||||
);
|
||||
|
||||
it("should render", () => {
|
||||
renderPLS({});
|
||||
expect(screen.getByRole("group")).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should display only the current user", async () => {
|
||||
// Display only the current user
|
||||
renderPLS({ filter: (user) => user === currentUser });
|
||||
|
||||
// Only alice should be displayed
|
||||
const userSelects = screen.getAllByRole("combobox");
|
||||
expect(userSelects).toHaveLength(1);
|
||||
expect(userSelects[0]).toHaveAccessibleName(currentUser);
|
||||
|
||||
expect(screen.getByRole("group")).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should be able to change the power level of the current user", async () => {
|
||||
const onClick = jest.fn();
|
||||
renderPLS({ onClick });
|
||||
|
||||
// Until the power level is changed, the apply button should be disabled
|
||||
// compound button is using aria-disabled instead of the disabled attribute, we can't toBeDisabled on it
|
||||
expect(screen.getByRole("button", { name: "Apply" })).toHaveAttribute("aria-disabled", "true");
|
||||
|
||||
const select = screen.getByRole("combobox", { name: currentUser });
|
||||
// Sanity check
|
||||
expect(select).toHaveValue("100");
|
||||
|
||||
// Change current user power level to 50
|
||||
await userEvent.selectOptions(select, "50");
|
||||
expect(select).toHaveValue("50");
|
||||
// After the user level changes, the apply button should be enabled
|
||||
expect(screen.getByRole("button", { name: "Apply" })).toHaveAttribute("aria-disabled", "false");
|
||||
|
||||
// Click on Apply should call onClick with the new power level
|
||||
await userEvent.click(screen.getByRole("button", { name: "Apply" }));
|
||||
expect(onClick).toHaveBeenCalledWith(50, currentUser);
|
||||
});
|
||||
|
||||
it("should not be able to change the power level if `canChangeLevels` is false", async () => {
|
||||
renderPLS({ canChangeLevels: false });
|
||||
|
||||
// The selects should be disabled
|
||||
const userSelects = screen.getAllByRole("combobox");
|
||||
userSelects.forEach((select) => expect(select).toBeDisabled());
|
||||
});
|
||||
|
||||
it("should be able to change only the level of someone with a lower level", async () => {
|
||||
const userLevels = {
|
||||
[currentUser]: 50,
|
||||
"@alice:server.org": 100,
|
||||
};
|
||||
renderPLS({ userLevels });
|
||||
|
||||
expect(screen.getByRole("combobox", { name: currentUser })).toBeEnabled();
|
||||
expect(screen.getByRole("combobox", { name: "@alice:server.org" })).toBeDisabled();
|
||||
});
|
||||
|
||||
it("should display the children if there is no user to display", async () => {
|
||||
// No user to display
|
||||
renderPLS({ filter: () => false });
|
||||
|
||||
expect(screen.getByText("empty label")).toBeInTheDocument();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,235 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PowerLevelSelector should display only the current user 1`] = `
|
||||
<fieldset
|
||||
class="mx_SettingsFieldset"
|
||||
>
|
||||
<legend
|
||||
class="mx_SettingsFieldset_legend"
|
||||
>
|
||||
title
|
||||
</legend>
|
||||
<div
|
||||
class="mx_SettingsFieldset_content"
|
||||
>
|
||||
<div
|
||||
class="mx_PowerSelector"
|
||||
>
|
||||
<div
|
||||
class="mx_Field mx_Field_select"
|
||||
>
|
||||
<select
|
||||
data-testid="power-level-select-element"
|
||||
id="mx_Field_4"
|
||||
label="@userId:matrix.org"
|
||||
placeholder="@userId:matrix.org"
|
||||
type="text"
|
||||
>
|
||||
<option
|
||||
data-testid="power-level-option-0"
|
||||
value="0"
|
||||
>
|
||||
Default
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-50"
|
||||
value="50"
|
||||
>
|
||||
Moderator
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-100"
|
||||
value="100"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-SELECT_VALUE_CUSTOM"
|
||||
value="SELECT_VALUE_CUSTOM"
|
||||
>
|
||||
Custom level
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
for="mx_Field_4"
|
||||
>
|
||||
@userId:matrix.org
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
aria-disabled="true"
|
||||
aria-label="Apply"
|
||||
class="_button_dyfp8_17 mx_Dialog_nonDialogButton mx_PowerLevelSelector_Button"
|
||||
data-kind="primary"
|
||||
data-size="sm"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
`;
|
||||
|
||||
exports[`PowerLevelSelector should render 1`] = `
|
||||
<fieldset
|
||||
class="mx_SettingsFieldset"
|
||||
>
|
||||
<legend
|
||||
class="mx_SettingsFieldset_legend"
|
||||
>
|
||||
title
|
||||
</legend>
|
||||
<div
|
||||
class="mx_SettingsFieldset_content"
|
||||
>
|
||||
<div
|
||||
class="mx_PowerSelector"
|
||||
>
|
||||
<div
|
||||
class="mx_Field mx_Field_select"
|
||||
>
|
||||
<select
|
||||
data-testid="power-level-select-element"
|
||||
id="mx_Field_1"
|
||||
label="@bob:server.org"
|
||||
placeholder="@bob:server.org"
|
||||
type="text"
|
||||
>
|
||||
<option
|
||||
data-testid="power-level-option-0"
|
||||
value="0"
|
||||
>
|
||||
Default
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-50"
|
||||
value="50"
|
||||
>
|
||||
Moderator
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-100"
|
||||
value="100"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-SELECT_VALUE_CUSTOM"
|
||||
value="SELECT_VALUE_CUSTOM"
|
||||
>
|
||||
Custom level
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
for="mx_Field_1"
|
||||
>
|
||||
@bob:server.org
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_PowerSelector"
|
||||
>
|
||||
<div
|
||||
class="mx_Field mx_Field_select"
|
||||
>
|
||||
<select
|
||||
data-testid="power-level-select-element"
|
||||
id="mx_Field_2"
|
||||
label="@alice:server.org"
|
||||
placeholder="@alice:server.org"
|
||||
type="text"
|
||||
>
|
||||
<option
|
||||
data-testid="power-level-option-0"
|
||||
value="0"
|
||||
>
|
||||
Default
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-50"
|
||||
value="50"
|
||||
>
|
||||
Moderator
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-100"
|
||||
value="100"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-SELECT_VALUE_CUSTOM"
|
||||
value="SELECT_VALUE_CUSTOM"
|
||||
>
|
||||
Custom level
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
for="mx_Field_2"
|
||||
>
|
||||
@alice:server.org
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_PowerSelector"
|
||||
>
|
||||
<div
|
||||
class="mx_Field mx_Field_select"
|
||||
>
|
||||
<select
|
||||
data-testid="power-level-select-element"
|
||||
id="mx_Field_3"
|
||||
label="@userId:matrix.org"
|
||||
placeholder="@userId:matrix.org"
|
||||
type="text"
|
||||
>
|
||||
<option
|
||||
data-testid="power-level-option-0"
|
||||
value="0"
|
||||
>
|
||||
Default
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-50"
|
||||
value="50"
|
||||
>
|
||||
Moderator
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-100"
|
||||
value="100"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
<option
|
||||
data-testid="power-level-option-SELECT_VALUE_CUSTOM"
|
||||
value="SELECT_VALUE_CUSTOM"
|
||||
>
|
||||
Custom level
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
for="mx_Field_3"
|
||||
>
|
||||
@userId:matrix.org
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
aria-disabled="true"
|
||||
aria-label="Apply"
|
||||
class="_button_dyfp8_17 mx_Dialog_nonDialogButton mx_PowerLevelSelector_Button"
|
||||
data-kind="primary"
|
||||
data-size="sm"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
`;
|
|
@ -15,11 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { fireEvent, render, RenderResult, screen, waitFor } from "@testing-library/react";
|
||||
import { fireEvent, getByRole, render, RenderResult, screen, waitFor } from "@testing-library/react";
|
||||
import { MatrixClient, EventType, MatrixEvent, Room, RoomMember, ISendEventResponse } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { mocked } from "jest-mock";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import RolesRoomSettingsTab from "../../../../../../src/components/views/settings/tabs/room/RolesRoomSettingsTab";
|
||||
import { mkStubRoom, withClientContextRenderOptions, stubClient } from "../../../../../test-utils";
|
||||
|
@ -263,6 +264,11 @@ describe("RolesRoomSettingsTab", () => {
|
|||
fireEvent.change(selector, { target: { value: "50" } });
|
||||
expect(selector).toHaveValue("50");
|
||||
|
||||
// Get the apply button of the privileged user section and click on it
|
||||
const privilegedUsersSection = screen.getByRole("group", { name: "Privileged Users" });
|
||||
const applyButton = getByRole(privilegedUsersSection, "button", { name: "Apply" });
|
||||
await userEvent.click(applyButton);
|
||||
|
||||
deferred.reject("Error");
|
||||
await waitFor(() => expect(selector).toHaveValue("100"));
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue