Merge branch 'develop' into germain-gg/notifications-labs

This commit is contained in:
RMidhunSuresh 2023-09-14 12:14:08 +05:30
commit 1ba419fe11
No known key found for this signature in database
155 changed files with 17952 additions and 15335 deletions

View file

@ -56,7 +56,7 @@ describe("RoomHeader", () => {
});
afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});
it("renders the room header", () => {

View file

@ -165,13 +165,28 @@ describe("RoomKnocksBar", () => {
expect(screen.getByRole("paragraph")).toHaveTextContent(`${bob.name} (${bob.userId})`);
});
it("renders a link to open the room settings people tab", () => {
getComponent(room);
fireEvent.click(getButton("View message"));
expect(dis.dispatch).toHaveBeenCalledWith({
action: "open_room_settings",
initial_tab_id: RoomSettingsTab.People,
room_id: roomId,
describe("when a knock reason is not provided", () => {
it("does not render a link to open the room settings people tab", () => {
getComponent(room);
expect(screen.queryByRole("button", { name: "View message" })).not.toBeInTheDocument();
});
});
describe("when a knock reason is provided", () => {
it("renders a link to open the room settings people tab", () => {
bob.setMembershipEvent(
new MatrixEvent({
content: { displayname: "Bob", membership: "knock", reason: "some reason" },
type: EventType.RoomMember,
}),
);
getComponent(room);
fireEvent.click(getButton("View message"));
expect(dis.dispatch).toHaveBeenCalledWith({
action: "open_room_settings",
initial_tab_id: RoomSettingsTab.People,
room_id: roomId,
});
});
});

View file

@ -45,23 +45,27 @@ const makeMockRoomMember = ({
membership,
content,
memberContent,
oldMembership,
}: {
userId?: string;
isKicked?: boolean;
membership?: "invite" | "ban";
membership?: "invite" | "ban" | "leave";
content?: Partial<IContent>;
memberContent?: Partial<IContent>;
oldMembership?: "join" | "knock";
}) =>
({
userId,
rawDisplayName: `${userId} name`,
isKicked: jest.fn().mockReturnValue(!!isKicked),
getContent: jest.fn().mockReturnValue(content || {}),
getPrevContent: jest.fn().mockReturnValue(content || {}),
membership,
events: {
member: {
getSender: jest.fn().mockReturnValue("@kicker:test.com"),
getContent: jest.fn().mockReturnValue({ reason: "test reason", ...memberContent }),
getPrevContent: jest.fn().mockReturnValue({ membership: oldMembership, ...memberContent }),
},
},
} as unknown as RoomMember);
@ -168,11 +172,33 @@ describe("<RoomPreviewBar />", () => {
it("renders kicked message", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true }));
const component = getComponent({ loading: true, room });
const component = getComponent({ room, promptAskToJoin: true });
expect(getMessage(component)).toMatchSnapshot();
});
it("renders denied request message", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(
makeMockRoomMember({ isKicked: true, membership: "leave", oldMembership: "knock" }),
);
const component = getComponent({ room, promptAskToJoin: true });
expect(getMessage(component)).toMatchSnapshot();
});
it("triggers the primary action callback for denied request", () => {
const onForgetClick = jest.fn();
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(
makeMockRoomMember({ isKicked: true, membership: "leave", oldMembership: "knock" }),
);
const component = getComponent({ room, promptAskToJoin: true, onForgetClick });
fireEvent.click(getPrimaryActionButton(component)!);
expect(onForgetClick).toHaveBeenCalled();
});
it("renders banned message", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ membership: "ban" }));

View file

@ -85,7 +85,6 @@ describe("<SendMessageComposer/>", () => {
msc3946ProcessDynamicPredecessor: false,
canAskToJoin: false,
promptAskToJoin: false,
knocked: false,
};
describe("createMessageContent", () => {
const permalinkCreator = jest.fn() as any;

View file

@ -22,7 +22,7 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
>
<div
aria-level="1"
class="_font-body-lg-semibold_1g2sj_89 mx_RoomHeader_heading"
class="_font-body-lg-semibold_1jx6b_83 mx_RoomHeader_heading"
dir="auto"
role="heading"
title="!1:example.org"
@ -35,7 +35,7 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-2x);"
>
<button
class="_icon-button_1k9cw_17"
class="_icon-button_1segd_17"
data-state="closed"
disabled=""
style="--cpd-icon-button-size: 32px;"
@ -44,7 +44,7 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
<div />
</button>
<button
class="_icon-button_1k9cw_17"
class="_icon-button_1segd_17"
data-state="closed"
disabled=""
style="--cpd-icon-button-size: 32px;"
@ -53,7 +53,7 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
<div />
</button>
<button
class="_icon-button_1k9cw_17"
class="_icon-button_1segd_17"
data-state="closed"
style="--cpd-icon-button-size: 32px;"
title="Threads"

View file

@ -107,6 +107,19 @@ exports[`<RoomPreviewBar /> renders banned message 1`] = `
</div>
`;
exports[`<RoomPreviewBar /> renders denied request message 1`] = `
<div
class="mx_RoomPreviewBar_message"
>
<h3>
You have been denied access
</h3>
<p>
As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.
</p>
</div>
`;
exports[`<RoomPreviewBar /> renders kicked message 1`] = `
<div
class="mx_RoomPreviewBar_message"

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React from "react";
import { fireEvent, render, screen, within } from "@testing-library/react";
import { act, fireEvent, render, screen, within } from "@testing-library/react";
import {
EventType,
GuestAccess,
@ -25,6 +25,8 @@ import {
Room,
ClientEvent,
RoomMember,
MatrixError,
Visibility,
} from "matrix-js-sdk/src/matrix";
import { defer, IDeferred } from "matrix-js-sdk/src/utils";
@ -51,6 +53,8 @@ describe("<JoinRuleSettings />", () => {
getProfileInfo: jest.fn(),
invite: jest.fn().mockResolvedValue(undefined),
isRoomEncrypted: jest.fn().mockReturnValue(false),
getRoomDirectoryVisibility: jest.fn(),
setRoomDirectoryVisibility: jest.fn(),
});
const roomId = "!room:server.org";
const newRoomId = "!roomUpgraded:server.org";
@ -270,10 +274,77 @@ describe("<JoinRuleSettings />", () => {
});
});
describe("knock rooms directory visibility", () => {
const getCheckbox = () => screen.getByRole("checkbox");
let room: Room;
beforeEach(() => (room = new Room(roomId, client, userId)));
describe("when join rule is knock", () => {
beforeEach(() => setRoomStateEvents(room, PreferredRoomVersions.KnockRooms, JoinRule.Knock));
it("should set the visibility to public", async () => {
jest.spyOn(client, "getRoomDirectoryVisibility").mockResolvedValue({ visibility: Visibility.Private });
jest.spyOn(client, "setRoomDirectoryVisibility").mockResolvedValue({});
getComponent({ room });
fireEvent.click(getCheckbox());
await act(async () => await flushPromises());
expect(client.setRoomDirectoryVisibility).toHaveBeenCalledWith(roomId, Visibility.Public);
expect(getCheckbox()).toBeChecked();
});
it("should set the visibility to private", async () => {
jest.spyOn(client, "getRoomDirectoryVisibility").mockResolvedValue({ visibility: Visibility.Public });
jest.spyOn(client, "setRoomDirectoryVisibility").mockResolvedValue({});
getComponent({ room });
await act(async () => await flushPromises());
fireEvent.click(getCheckbox());
await act(async () => await flushPromises());
expect(client.setRoomDirectoryVisibility).toHaveBeenCalledWith(roomId, Visibility.Private);
expect(getCheckbox()).not.toBeChecked();
});
it("should call onError if setting visibility fails", async () => {
const error = new MatrixError();
jest.spyOn(client, "getRoomDirectoryVisibility").mockResolvedValue({ visibility: Visibility.Private });
jest.spyOn(client, "setRoomDirectoryVisibility").mockRejectedValue(error);
getComponent({ room });
fireEvent.click(getCheckbox());
await act(async () => await flushPromises());
expect(getCheckbox()).not.toBeChecked();
expect(defaultProps.onError).toHaveBeenCalledWith(error);
});
});
describe("when the room version is unsupported and upgrade is enabled", () => {
it("should disable the checkbox", () => {
setRoomStateEvents(room, "6", JoinRule.Invite);
getComponent({ promptUpgrade: true, room });
expect(getCheckbox()).toBeDisabled();
});
});
describe("when join rule is not knock", () => {
beforeEach(() => {
setRoomStateEvents(room, PreferredRoomVersions.KnockRooms, JoinRule.Invite);
getComponent({ room });
});
it("should disable the checkbox", () => {
expect(getCheckbox()).toBeDisabled();
});
it("should set the visibility to private by default", () => {
expect(getCheckbox()).not.toBeChecked();
});
});
});
it("should not show knock room join rule", async () => {
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
const room = new Room(newRoomId, client, userId);
getComponent({ room: room });
setRoomStateEvents(room, PreferredRoomVersions.KnockRooms);
getComponent({ room });
expect(screen.queryByText("Ask to join")).not.toBeInTheDocument();
});
});

View file

@ -507,39 +507,25 @@ describe("RoomViewStore", function () {
});
});
describe("knocked()", () => {
it("returns false", () => {
expect(roomViewStore.knocked()).toBe(false);
});
it("returns true", async () => {
jest.spyOn(mockClient, "knockRoom").mockResolvedValue({ room_id: roomId });
await dispatchSubmitAskToJoin(roomId);
expect(roomViewStore.knocked()).toBe(true);
});
});
describe("Action.SubmitAskToJoin", () => {
const reason = "some reason";
beforeEach(async () => await dispatchPromptAskToJoin());
it("calls knockRoom(), sets askToJoin state to false and knocked state to true", async () => {
it("calls knockRoom() and sets promptAskToJoin state to false", async () => {
jest.spyOn(mockClient, "knockRoom").mockResolvedValue({ room_id: roomId });
await dispatchSubmitAskToJoin(roomId, reason);
expect(mockClient.knockRoom).toHaveBeenCalledWith(roomId, { reason, viaServers: [] });
expect(roomViewStore.promptAskToJoin()).toBe(false);
expect(roomViewStore.knocked()).toBe(true);
});
it("calls knockRoom(), sets askToJoin to false, keeps knocked state false and shows an error dialog", async () => {
it("calls knockRoom(), sets promptAskToJoin state to false and shows an error dialog", async () => {
const error = new MatrixError(undefined, 403);
jest.spyOn(mockClient, "knockRoom").mockRejectedValue(error);
await dispatchSubmitAskToJoin(roomId, reason);
expect(mockClient.knockRoom).toHaveBeenCalledWith(roomId, { reason, viaServers: [] });
expect(roomViewStore.promptAskToJoin()).toBe(false);
expect(roomViewStore.knocked()).toBe(false);
expect(Modal.createDialog).toHaveBeenCalledWith(ErrorDialog, {
description: "You need an invite to access this room.",
title: "Failed to join",
@ -550,6 +536,7 @@ describe("RoomViewStore", function () {
const error = new MatrixError();
jest.spyOn(mockClient, "knockRoom").mockRejectedValue(error);
await dispatchSubmitAskToJoin(roomId);
expect(Modal.createDialog).toHaveBeenCalledWith(ErrorDialog, {
description: error.message,
title: "Failed to join",
@ -563,21 +550,19 @@ describe("RoomViewStore", function () {
await dispatchSubmitAskToJoin(roomId);
});
it("calls leave() and sets knocked state to false", async () => {
it("calls leave()", async () => {
jest.spyOn(mockClient, "leave").mockResolvedValue({});
await dispatchCancelAskToJoin(roomId);
expect(mockClient.leave).toHaveBeenCalledWith(roomId);
expect(roomViewStore.knocked()).toBe(false);
});
it("calls leave(), keeps knocked state true and shows an error dialog", async () => {
it("calls leave() and shows an error dialog", async () => {
const error = new MatrixError();
jest.spyOn(mockClient, "leave").mockRejectedValue(error);
await dispatchCancelAskToJoin(roomId);
expect(mockClient.leave).toHaveBeenCalledWith(roomId);
expect(roomViewStore.knocked()).toBe(true);
expect(Modal.createDialog).toHaveBeenCalledWith(ErrorDialog, {
description: error.message,
title: "Failed to cancel",

View file

@ -90,7 +90,6 @@ export function getRoomContext(room: Room, override: Partial<IRoomState>): IRoom
msc3946ProcessDynamicPredecessor: false,
canAskToJoin: false,
promptAskToJoin: false,
knocked: false,
...override,
};