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>
This commit is contained in:
parent
36a7a96e0e
commit
ce96853ad7
5 changed files with 64 additions and 2 deletions
|
@ -2205,6 +2205,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
knocked={myMembership === "knock" || this.state.knocked}
|
knocked={myMembership === "knock" || this.state.knocked}
|
||||||
onSubmitAskToJoin={this.onSubmitAskToJoin}
|
onSubmitAskToJoin={this.onSubmitAskToJoin}
|
||||||
onCancelAskToJoin={this.onCancelAskToJoin}
|
onCancelAskToJoin={this.onCancelAskToJoin}
|
||||||
|
onForgetClick={this.onForgetClick}
|
||||||
/>
|
/>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -62,6 +62,7 @@ enum MessageCase {
|
||||||
OtherError = "OtherError",
|
OtherError = "OtherError",
|
||||||
PromptAskToJoin = "PromptAskToJoin",
|
PromptAskToJoin = "PromptAskToJoin",
|
||||||
Knocked = "Knocked",
|
Knocked = "Knocked",
|
||||||
|
RequestDenied = "requestDenied",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
@ -188,7 +189,11 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
||||||
const myMember = this.getMyMember();
|
const myMember = this.getMyMember();
|
||||||
|
|
||||||
if (myMember) {
|
if (myMember) {
|
||||||
|
const previousMembership = myMember.events.member?.getPrevContent().membership;
|
||||||
if (myMember.isKicked()) {
|
if (myMember.isKicked()) {
|
||||||
|
if (previousMembership === "knock") {
|
||||||
|
return MessageCase.RequestDenied;
|
||||||
|
}
|
||||||
return MessageCase.Kicked;
|
return MessageCase.Kicked;
|
||||||
} else if (myMember.membership === "ban") {
|
} else if (myMember.membership === "ban") {
|
||||||
return MessageCase.Banned;
|
return MessageCase.Banned;
|
||||||
|
@ -397,6 +402,21 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageCase.RequestDenied: {
|
||||||
|
title = _t("You have been denied access");
|
||||||
|
|
||||||
|
subTitle = _t(
|
||||||
|
"As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isSpace) {
|
||||||
|
primaryActionLabel = _t("Forget this space");
|
||||||
|
} else {
|
||||||
|
primaryActionLabel = _t("Forget this room");
|
||||||
|
}
|
||||||
|
primaryActionHandler = this.props.onForgetClick;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MessageCase.Banned: {
|
case MessageCase.Banned: {
|
||||||
const { memberName, reason } = this.getKickOrBanInfo();
|
const { memberName, reason } = this.getKickOrBanInfo();
|
||||||
if (roomName) {
|
if (roomName) {
|
||||||
|
|
|
@ -2150,6 +2150,8 @@
|
||||||
"Forget this space": "Forget this space",
|
"Forget this space": "Forget this space",
|
||||||
"Forget this room": "Forget this room",
|
"Forget this room": "Forget this room",
|
||||||
"Re-join": "Re-join",
|
"Re-join": "Re-join",
|
||||||
|
"You have been denied access": "You have been denied access",
|
||||||
|
"As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.": "As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.",
|
||||||
"You were banned from %(roomName)s by %(memberName)s": "You were banned from %(roomName)s by %(memberName)s",
|
"You were banned from %(roomName)s by %(memberName)s": "You were banned from %(roomName)s by %(memberName)s",
|
||||||
"You were banned by %(memberName)s": "You were banned by %(memberName)s",
|
"You were banned by %(memberName)s": "You were banned by %(memberName)s",
|
||||||
"Something went wrong with your invite to %(roomName)s": "Something went wrong with your invite to %(roomName)s",
|
"Something went wrong with your invite to %(roomName)s": "Something went wrong with your invite to %(roomName)s",
|
||||||
|
|
|
@ -45,23 +45,27 @@ const makeMockRoomMember = ({
|
||||||
membership,
|
membership,
|
||||||
content,
|
content,
|
||||||
memberContent,
|
memberContent,
|
||||||
|
oldMembership,
|
||||||
}: {
|
}: {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
isKicked?: boolean;
|
isKicked?: boolean;
|
||||||
membership?: "invite" | "ban";
|
membership?: "invite" | "ban" | "leave";
|
||||||
content?: Partial<IContent>;
|
content?: Partial<IContent>;
|
||||||
memberContent?: Partial<IContent>;
|
memberContent?: Partial<IContent>;
|
||||||
|
oldMembership?: "join" | "knock";
|
||||||
}) =>
|
}) =>
|
||||||
({
|
({
|
||||||
userId,
|
userId,
|
||||||
rawDisplayName: `${userId} name`,
|
rawDisplayName: `${userId} name`,
|
||||||
isKicked: jest.fn().mockReturnValue(!!isKicked),
|
isKicked: jest.fn().mockReturnValue(!!isKicked),
|
||||||
getContent: jest.fn().mockReturnValue(content || {}),
|
getContent: jest.fn().mockReturnValue(content || {}),
|
||||||
|
getPrevContent: jest.fn().mockReturnValue(content || {}),
|
||||||
membership,
|
membership,
|
||||||
events: {
|
events: {
|
||||||
member: {
|
member: {
|
||||||
getSender: jest.fn().mockReturnValue("@kicker:test.com"),
|
getSender: jest.fn().mockReturnValue("@kicker:test.com"),
|
||||||
getContent: jest.fn().mockReturnValue({ reason: "test reason", ...memberContent }),
|
getContent: jest.fn().mockReturnValue({ reason: "test reason", ...memberContent }),
|
||||||
|
getPrevContent: jest.fn().mockReturnValue({ membership: oldMembership, ...memberContent }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as unknown as RoomMember);
|
} as unknown as RoomMember);
|
||||||
|
@ -168,11 +172,33 @@ describe("<RoomPreviewBar />", () => {
|
||||||
it("renders kicked message", () => {
|
it("renders kicked message", () => {
|
||||||
const room = createRoom(roomId, otherUserId);
|
const room = createRoom(roomId, otherUserId);
|
||||||
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true }));
|
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true }));
|
||||||
const component = getComponent({ loading: true, room });
|
const component = getComponent({ room, promptAskToJoin: true });
|
||||||
|
|
||||||
expect(getMessage(component)).toMatchSnapshot();
|
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", () => {
|
it("renders banned message", () => {
|
||||||
const room = createRoom(roomId, otherUserId);
|
const room = createRoom(roomId, otherUserId);
|
||||||
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ membership: "ban" }));
|
jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ membership: "ban" }));
|
||||||
|
|
|
@ -107,6 +107,19 @@ exports[`<RoomPreviewBar /> renders banned message 1`] = `
|
||||||
</div>
|
</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`] = `
|
exports[`<RoomPreviewBar /> renders kicked message 1`] = `
|
||||||
<div
|
<div
|
||||||
class="mx_RoomPreviewBar_message"
|
class="mx_RoomPreviewBar_message"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue