element-web/test/unit-tests/components/views/rooms/RoomPreviewBar-test.tsx

519 lines
22 KiB
TypeScript
Raw Normal View History

/*
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import React, { ComponentProps } from "react";
import { render, fireEvent, RenderResult, waitFor, waitForElementToBeRemoved } from "jest-matrix-react";
import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types";
import { withClientContextRenderOptions, stubClient } from "../../../../test-utils";
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
import RoomPreviewBar from "../../../../../src/components/views/rooms/RoomPreviewBar";
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
jest.mock("../../../../../src/IdentityAuthClient", () => {
return jest.fn().mockImplementation(() => {
2022-12-12 11:24:14 +00:00
return { getAccessToken: jest.fn().mockResolvedValue("mock-token") };
});
});
jest.useRealTimers();
const createRoom = (roomId: string, userId: string): Room => {
const cli = MatrixClientPeg.safeGet();
const newRoom = new Room(roomId, cli, userId, {});
DMRoomMap.makeShared(cli).start();
return newRoom;
};
2022-12-12 11:24:14 +00:00
const makeMockRoomMember = ({
userId,
2022-12-12 11:24:14 +00:00
isKicked,
membership,
2022-12-12 11:24:14 +00:00
content,
memberContent,
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
oldMembership,
2022-12-12 11:24:14 +00:00
}: {
userId?: string;
isKicked?: boolean;
membership?: KnownMembership.Invite | KnownMembership.Ban | KnownMembership.Leave;
2022-12-12 11:24:14 +00:00
content?: Partial<IContent>;
memberContent?: Partial<IContent>;
oldMembership?: KnownMembership.Join | KnownMembership.Knock;
2022-12-12 11:24:14 +00:00
}) =>
({
userId,
rawDisplayName: `${userId} name`,
isKicked: jest.fn().mockReturnValue(!!isKicked),
getContent: jest.fn().mockReturnValue(content || {}),
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
getPrevContent: jest.fn().mockReturnValue(content || {}),
2022-12-12 11:24:14 +00:00
membership,
events: {
member: {
getSender: jest.fn().mockReturnValue("@kicker:test.com"),
getContent: jest.fn().mockReturnValue({ reason: "test reason", ...memberContent }),
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
getPrevContent: jest.fn().mockReturnValue({ membership: oldMembership, ...memberContent }),
2022-12-12 11:24:14 +00:00
},
},
}) as unknown as RoomMember;
2022-12-12 11:24:14 +00:00
describe("<RoomPreviewBar />", () => {
const roomId = "RoomPreviewBar-test-room";
const userId = "@tester:test.com";
const inviterUserId = "@inviter:test.com";
const otherUserId = "@othertester:test.com";
const getComponent = (props: ComponentProps<typeof RoomPreviewBar> = {}) => {
const defaultProps = {
roomId,
room: createRoom(roomId, userId),
};
return render(
<RoomPreviewBar {...defaultProps} {...props} />,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
};
2022-12-12 11:24:14 +00:00
const isSpinnerRendered = (wrapper: RenderResult) => !!wrapper.container.querySelector(".mx_Spinner");
const getMessage = (wrapper: RenderResult) =>
2022-12-12 11:24:14 +00:00
wrapper.container.querySelector<HTMLDivElement>(".mx_RoomPreviewBar_message");
const getActions = (wrapper: RenderResult) =>
2022-12-12 11:24:14 +00:00
wrapper.container.querySelector<HTMLDivElement>(".mx_RoomPreviewBar_actions");
const getPrimaryActionButton = (wrapper: RenderResult) =>
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_primary");
const getSecondaryActionButton = (wrapper: RenderResult) =>
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_secondary");
beforeEach(() => {
stubClient();
MatrixClientPeg.get()!.getUserId = jest.fn().mockReturnValue(userId);
MatrixClientPeg.get()!.getSafeUserId = jest.fn().mockReturnValue(userId);
MatrixClientPeg.safeGet().getUserId = jest.fn().mockReturnValue(userId);
MatrixClientPeg.safeGet().getSafeUserId = jest.fn().mockReturnValue(userId);
});
afterEach(() => {
const container = document.body.firstChild;
container && document.body.removeChild(container);
});
2022-12-12 11:24:14 +00:00
it("renders joining message", () => {
const component = getComponent({ joining: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component)?.textContent).toEqual("Joining…");
});
2022-12-12 11:24:14 +00:00
it("renders rejecting message", () => {
const component = getComponent({ rejecting: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component)?.textContent).toEqual("Rejecting invite…");
});
2022-12-12 11:24:14 +00:00
it("renders loading message", () => {
const component = getComponent({ loading: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component)?.textContent).toEqual("Loading…");
});
2022-12-12 11:24:14 +00:00
it("renders not logged in message", () => {
MatrixClientPeg.safeGet().isGuest = jest.fn().mockReturnValue(true);
const component = getComponent({ loading: true });
expect(isSpinnerRendered(component)).toBeFalsy();
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
});
it("should send room oob data to start login", async () => {
MatrixClientPeg.safeGet().isGuest = jest.fn().mockReturnValue(true);
const component = getComponent({
oobData: {
name: "Room Name",
avatarUrl: "mxc://foo/bar",
inviterName: "Charlie",
},
});
const dispatcherSpy = jest.fn();
const dispatcherRef = defaultDispatcher.register(dispatcherSpy);
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
fireEvent.click(getPrimaryActionButton(component)!);
2022-12-12 11:24:14 +00:00
await waitFor(() =>
expect(dispatcherSpy).toHaveBeenCalledWith(
expect.objectContaining({
screenAfterLogin: {
screen: "room",
params: expect.objectContaining({
room_name: "Room Name",
room_avatar_url: "mxc://foo/bar",
inviter_name: "Charlie",
}),
},
}),
2022-12-12 11:24:14 +00:00
),
);
defaultDispatcher.unregister(dispatcherRef);
});
2022-12-12 11:24:14 +00:00
it("renders kicked message", () => {
const room = createRoom(roomId, otherUserId);
2022-12-12 11:24:14 +00:00
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true }));
const component = getComponent({ room, canAskToJoinAndMembershipIsLeave: true, promptAskToJoin: false });
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
expect(getMessage(component)).toMatchSnapshot();
});
it("renders denied request message", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(
makeMockRoomMember({
isKicked: true,
membership: KnownMembership.Leave,
oldMembership: KnownMembership.Knock,
}),
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
);
const component = getComponent({ room, promptAskToJoin: true });
expect(getMessage(component)).toMatchSnapshot();
});
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
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: KnownMembership.Leave,
oldMembership: KnownMembership.Knock,
}),
Notify users about denied access on ask-to-join rooms (#11480) * Implement denied request mask and logic Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * refactor / fix deny requests isues * fix tests create denied message test Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * add another test for the primary action for denied request Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> * fix linter issues Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * regenerate translation Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * fix translation and minor refactoring Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> * segment into 4 * Remove parallel from Cypress command to avoid talking to Cypress Cloud * Re-add --parallel flag for Percy * Prevent event propagation when clicking icon buttons (#11515) * Prevent event propagation when clicking icon buttons * Inhibit view user on click behaviour for room header face pile * Update snapshot * Add a 'm.relates_to' to edits in receipt tests and disable failing tests (#11501) * Add a 'm.relates_to' to edits in receipt tests * Disable a test that fails with real edits * Wait for the room to be read after we mark it as read * Skip tests that are failing because of inconsistencies between local and CI behaviour * Allow creating public knock rooms (#11481) * Allow creating public knock rooms Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Apply PR feedback Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> --------- Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Collect `console.debug` logs during cypress tests (#11478) In order for the logs collected by cypress to actually be useful, we really need `cons:debug`. * Migrate more strings to translation keys (#11522) * Only show Search button in RoomSummaryCard if new room UI enabled (#11524) * Only show Search button in RoomSummaryCard if new room UI enabled * Update snapshot * Update vector-im (#11526) * Update vector-im * Update snapshots of Compound Avatars * Update snapshots of Compound Avatars --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Migrate more strings to translation keys (#11530) * Fix regression around FacePile with overflow (#11527) * Work around compound-web AvatarStack not applying overlap to non-Avatars * Fix FacePile overflow tile not being layed out correctly * Use RoomStateEvent.Update for knocks (#11516) Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> * Cypress tests for event shields (#11525) * Factor downloadKey out to `utils.ts` * Add a new `describe` block for event shields * create a beforeEach block * Cypress tests for event shields * Document how to match the CI config for Cypress (#11531) * Document how to match the CI config for Cypress * Clarify language about needing Chrome * Move Cypress info into the Cypress-specific docs * Migrate more strings to translation keys (#11532) --------- Signed-off-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Signed-off-by: nurjinn jafar <nurjin.jafar@nordeck.net> Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net> Co-authored-by: AHMAD KADRI <52747422+ahmadkadri@users.noreply.github.com> Co-authored-by: Kerry Archibald <kerrya@element.io> Co-authored-by: Andy Balaam <andy.balaam@matrix.org> Co-authored-by: Johannes Marbach <johannesm@element.io> Co-authored-by: Germain <germains@element.io> Co-authored-by: Charly Nguyen <1422657+charlynguyen@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-07 08:07:43 +00:00
);
const component = getComponent({ room, promptAskToJoin: true, onForgetClick });
fireEvent.click(getPrimaryActionButton(component)!);
expect(onForgetClick).toHaveBeenCalled();
});
2022-12-12 11:24:14 +00:00
it("renders banned message", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ membership: KnownMembership.Ban }));
const component = getComponent({ loading: true, room });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
describe("with an error", () => {
it("renders room not found error", () => {
const error = new MatrixError({
2022-12-12 11:24:14 +00:00
errcode: "M_NOT_FOUND",
error: "Room not found",
});
const component = getComponent({ error });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders other errors", () => {
const error = new MatrixError({
2022-12-12 11:24:14 +00:00
errcode: "Something_else",
});
const component = getComponent({ error });
expect(getMessage(component)).toMatchSnapshot();
});
});
2022-12-12 11:24:14 +00:00
it("renders viewing room message when room an be previewed", () => {
const component = getComponent({ canPreview: true });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders viewing room message when room can not be previewed", () => {
const component = getComponent({ canPreview: false });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
describe("with an invite", () => {
const inviterName = inviterUserId;
const userMember = makeMockRoomMember({ userId });
const userMemberWithDmInvite = makeMockRoomMember({
2022-12-12 11:24:14 +00:00
userId,
membership: KnownMembership.Invite,
memberContent: { is_direct: true, membership: KnownMembership.Invite },
});
const inviterMember = makeMockRoomMember({
userId: inviterUserId,
content: {
2022-12-12 11:24:14 +00:00
"reason": "test",
"io.element.html_reason": "<h3>hello</h3>",
},
});
2022-12-12 11:24:14 +00:00
describe("without an invited email", () => {
describe("for a non-dm room", () => {
const mockGetMember = (id: string) => {
if (id === userId) return userMember;
return inviterMember;
};
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
let room: Room;
beforeEach(() => {
room = createRoom(roomId, userId);
2022-12-12 11:24:14 +00:00
jest.spyOn(room, "getMember").mockImplementation(mockGetMember);
jest.spyOn(room.currentState, "getMember").mockImplementation(mockGetMember);
onJoinClick.mockClear();
onRejectClick.mockClear();
});
2022-12-12 11:24:14 +00:00
it("renders invite message", () => {
const component = getComponent({ inviterName, room });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join and reject action buttons correctly", () => {
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
expect(getActions(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders reject and ignore action buttons when handler is provided", () => {
const onRejectAndIgnoreClick = jest.fn();
const component = getComponent({
2022-12-12 11:24:14 +00:00
inviterName,
room,
onJoinClick,
onRejectClick,
onRejectAndIgnoreClick,
});
expect(getActions(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join and reject action buttons in reverse order when room can previewed", () => {
// when room is previewed action buttons are rendered left to right, with primary on the right
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick, canPreview: true });
expect(getActions(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("joins room on primary button click", () => {
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
fireEvent.click(getPrimaryActionButton(component)!);
expect(onJoinClick).toHaveBeenCalled();
});
2022-12-12 11:24:14 +00:00
it("rejects invite on secondary button click", () => {
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
fireEvent.click(getSecondaryActionButton(component)!);
expect(onRejectClick).toHaveBeenCalled();
});
});
2022-12-12 11:24:14 +00:00
describe("for a dm room", () => {
const mockGetMember = (id: string) => {
if (id === userId) return userMemberWithDmInvite;
return inviterMember;
};
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
let room: Room;
beforeEach(() => {
room = createRoom(roomId, userId);
2022-12-12 11:24:14 +00:00
jest.spyOn(room, "getMember").mockImplementation(mockGetMember);
jest.spyOn(room.currentState, "getMember").mockImplementation(mockGetMember);
onJoinClick.mockClear();
onRejectClick.mockClear();
});
it("renders invite message", () => {
const component = getComponent({ inviterName, room });
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join and reject action buttons with correct labels", () => {
const onRejectAndIgnoreClick = jest.fn();
const component = getComponent({
2022-12-12 11:24:14 +00:00
inviterName,
room,
onJoinClick,
onRejectAndIgnoreClick,
onRejectClick,
});
expect(getActions(component)).toMatchSnapshot();
});
});
});
2022-12-12 11:24:14 +00:00
describe("with an invited email", () => {
const invitedEmail = "test@test.com";
const mockThreePids = [
2022-12-12 11:24:14 +00:00
{ medium: "email", address: invitedEmail },
{ medium: "not-email", address: "address 2" },
];
const testJoinButton =
(props: ComponentProps<typeof RoomPreviewBar>, expectSecondaryButton = false) =>
async () => {
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
const component = getComponent({ ...props, onJoinClick, onRejectClick });
await waitFor(() => expect(getPrimaryActionButton(component)).toBeTruthy());
if (expectSecondaryButton) expect(getSecondaryActionButton(component)).toBeFalsy();
fireEvent.click(getPrimaryActionButton(component)!);
expect(onJoinClick).toHaveBeenCalled();
};
2022-12-12 11:24:14 +00:00
describe("when client fails to get 3PIDs", () => {
beforeEach(() => {
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockRejectedValue({ errCode: "TEST_ERROR" });
});
2022-12-12 11:24:14 +00:00
it("renders error message", async () => {
const component = getComponent({ inviterName, invitedEmail });
await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join button", testJoinButton({ inviterName, invitedEmail }));
});
2022-12-12 11:24:14 +00:00
describe("when invitedEmail is not associated with current account", () => {
beforeEach(() => {
MatrixClientPeg.safeGet().getThreePids = jest
2022-12-12 11:24:14 +00:00
.fn()
.mockResolvedValue({ threepids: mockThreePids.slice(1) });
});
2022-12-12 11:24:14 +00:00
it("renders invite message with invited email", async () => {
const component = getComponent({ inviterName, invitedEmail });
await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join button", testJoinButton({ inviterName, invitedEmail }));
});
2022-12-12 11:24:14 +00:00
describe("when client has no identity server connected", () => {
beforeEach(() => {
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.safeGet().getIdentityServerUrl = jest.fn().mockReturnValue(false);
});
2022-12-12 11:24:14 +00:00
it("renders invite message with invited email", async () => {
const component = getComponent({ inviterName, invitedEmail });
await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot();
});
2022-12-12 11:24:14 +00:00
it("renders join button", testJoinButton({ inviterName, invitedEmail }));
});
2022-12-12 11:24:14 +00:00
describe("when client has an identity server connected", () => {
beforeEach(() => {
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.safeGet().getIdentityServerUrl = jest.fn().mockReturnValue("identity.test");
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockResolvedValue("identity.test");
});
2022-12-12 11:24:14 +00:00
it("renders email mismatch message when invite email mxid doesnt match", async () => {
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: "not userid" });
const component = getComponent({ inviterName, invitedEmail });
await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot();
expect(MatrixClientPeg.safeGet().lookupThreePid).toHaveBeenCalledWith(
2022-12-12 11:24:14 +00:00
"email",
invitedEmail,
"mock-token",
);
await testJoinButton({ inviterName, invitedEmail })();
});
2022-12-12 11:24:14 +00:00
it("renders invite message when invite email mxid match", async () => {
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: userId });
const component = getComponent({ inviterName, invitedEmail });
await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot();
await testJoinButton({ inviterName, invitedEmail }, false)();
});
});
});
});
describe("message case AskToJoin", () => {
it("renders the corresponding message", () => {
const component = getComponent({ promptAskToJoin: true });
expect(getMessage(component)).toMatchSnapshot();
});
it("renders the corresponding message when kicked", () => {
const room = createRoom(roomId, otherUserId);
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true }));
const component = getComponent({ room, promptAskToJoin: true });
expect(getMessage(component)).toMatchSnapshot();
});
it("renders the corresponding message with a generic title", () => {
const component = render(<RoomPreviewBar promptAskToJoin />);
expect(getMessage(component)).toMatchSnapshot();
});
it("renders the corresponding actions", () => {
const component = getComponent({ promptAskToJoin: true });
expect(getActions(component)).toMatchSnapshot();
});
it("triggers the primary action callback", () => {
const onSubmitAskToJoin = jest.fn();
const component = getComponent({ promptAskToJoin: true, onSubmitAskToJoin });
fireEvent.click(getPrimaryActionButton(component)!);
expect(onSubmitAskToJoin).toHaveBeenCalled();
});
it("triggers the primary action callback with a reason", () => {
const onSubmitAskToJoin = jest.fn();
const reason = "some reason";
const component = getComponent({ promptAskToJoin: true, onSubmitAskToJoin });
fireEvent.change(component.container.querySelector("textarea")!, { target: { value: reason } });
fireEvent.click(getPrimaryActionButton(component)!);
expect(onSubmitAskToJoin).toHaveBeenCalledWith(reason);
});
});
describe("message case Knocked", () => {
it("renders the corresponding message", () => {
const component = getComponent({ knocked: true });
expect(getMessage(component)).toMatchSnapshot();
});
it("renders the corresponding actions", () => {
const component = getComponent({ knocked: true, onCancelAskToJoin: () => {} });
expect(getActions(component)).toMatchSnapshot();
});
it("triggers the secondary action callback", () => {
const onCancelAskToJoin = jest.fn();
const component = getComponent({ knocked: true, onCancelAskToJoin });
fireEvent.click(getSecondaryActionButton(component)!);
expect(onCancelAskToJoin).toHaveBeenCalled();
});
});
});