Fix rejoin of knock rooms (#11980)
Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> Co-authored-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net>
This commit is contained in:
parent
e2bc437774
commit
74ea0d134e
5 changed files with 160 additions and 4 deletions
|
@ -63,7 +63,7 @@ describe("Knock Into Room", () => {
|
||||||
cy.stopHomeserver(homeserver);
|
cy.stopHomeserver(homeserver);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should knock into the room then knock is approved and user joins the room", () => {
|
it("should knock into the room then knock is approved and user joins the room then user is kicked and joins again", () => {
|
||||||
cy.viewRoomById(roomId);
|
cy.viewRoomById(roomId);
|
||||||
|
|
||||||
cy.get(".mx_RoomPreviewBar").within(() => {
|
cy.get(".mx_RoomPreviewBar").within(() => {
|
||||||
|
@ -104,6 +104,124 @@ describe("Knock Into Room", () => {
|
||||||
cy.findByRole("group", { name: "Rooms" }).findByRole("treeitem", { name: "Cybersecurity" });
|
cy.findByRole("group", { name: "Rooms" }).findByRole("treeitem", { name: "Cybersecurity" });
|
||||||
|
|
||||||
cy.findByText("Alice joined the room").should("exist");
|
cy.findByText("Alice joined the room").should("exist");
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot kicks Alice
|
||||||
|
await bot.kick(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get(".mx_RoomPreviewBar").within(() => {
|
||||||
|
cy.findByRole("button", { name: "Re-join" }).click();
|
||||||
|
|
||||||
|
cy.findByRole("heading", { name: "Ask to join Cybersecurity?" });
|
||||||
|
cy.findByRole("button", { name: "Request access" }).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot waits for knock request from Alice
|
||||||
|
await waitForRoom(win, bot, roomId, (room) => {
|
||||||
|
const events = room.getLiveTimeline().getEvents();
|
||||||
|
return events.some(
|
||||||
|
(e) =>
|
||||||
|
e.getType() === "m.room.member" &&
|
||||||
|
e.getContent()?.membership === "knock" &&
|
||||||
|
e.getContent()?.displayname === "Alice",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// bot invites Alice
|
||||||
|
await bot.invite(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alice have to accept invitation in order to join the room.
|
||||||
|
// It will be not needed when homeserver implements auto accept knock requests.
|
||||||
|
cy.get(".mx_RoomView").findByRole("button", { name: "Accept" }).click();
|
||||||
|
|
||||||
|
cy.findByText("Alice was invited, joined, was removed, was invited, and joined").should("exist");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should knock into the room then knock is approved and user joins the room then user is banned/unbanned and joins again", () => {
|
||||||
|
cy.viewRoomById(roomId);
|
||||||
|
|
||||||
|
cy.get(".mx_RoomPreviewBar").within(() => {
|
||||||
|
cy.findByRole("button", { name: "Join the discussion" }).click();
|
||||||
|
|
||||||
|
cy.findByRole("heading", { name: "Ask to join?" });
|
||||||
|
cy.findByRole("textbox");
|
||||||
|
cy.findByRole("button", { name: "Request access" }).click();
|
||||||
|
|
||||||
|
cy.findByRole("heading", { name: "Request to join sent" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Knocked room should appear in Rooms
|
||||||
|
cy.findByRole("group", { name: "Rooms" }).findByRole("treeitem", { name: "Cybersecurity" });
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot waits for knock request from Alice
|
||||||
|
await waitForRoom(win, bot, roomId, (room) => {
|
||||||
|
const events = room.getLiveTimeline().getEvents();
|
||||||
|
return events.some(
|
||||||
|
(e) =>
|
||||||
|
e.getType() === "m.room.member" &&
|
||||||
|
e.getContent()?.membership === "knock" &&
|
||||||
|
e.getContent()?.displayname === "Alice",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// bot invites Alice
|
||||||
|
await bot.invite(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.findByRole("group", { name: "Invites" }).findByRole("treeitem", { name: "Cybersecurity" });
|
||||||
|
|
||||||
|
// Alice have to accept invitation in order to join the room.
|
||||||
|
// It will be not needed when homeserver implements auto accept knock requests.
|
||||||
|
cy.get(".mx_RoomView").findByRole("button", { name: "Accept" }).click();
|
||||||
|
|
||||||
|
cy.findByRole("group", { name: "Rooms" }).findByRole("treeitem", { name: "Cybersecurity" });
|
||||||
|
|
||||||
|
cy.findByText("Alice joined the room").should("exist");
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot bans Alice
|
||||||
|
await bot.ban(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get(".mx_RoomPreviewBar").findByText("You were banned from Cybersecurity by Bob").should("exist");
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot unbans Alice
|
||||||
|
await bot.unban(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get(".mx_RoomPreviewBar").within(() => {
|
||||||
|
cy.findByRole("button", { name: "Re-join" }).click();
|
||||||
|
|
||||||
|
cy.findByRole("heading", { name: "Ask to join Cybersecurity?" });
|
||||||
|
cy.findByRole("button", { name: "Request access" }).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.window().then(async (win) => {
|
||||||
|
// bot waits for knock request from Alice
|
||||||
|
await waitForRoom(win, bot, roomId, (room) => {
|
||||||
|
const events = room.getLiveTimeline().getEvents();
|
||||||
|
return events.some(
|
||||||
|
(e) =>
|
||||||
|
e.getType() === "m.room.member" &&
|
||||||
|
e.getContent()?.membership === "knock" &&
|
||||||
|
e.getContent()?.displayname === "Alice",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// bot invites Alice
|
||||||
|
await bot.invite(roomId, user.userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alice have to accept invitation in order to join the room.
|
||||||
|
// It will be not needed when homeserver implements auto accept knock requests.
|
||||||
|
cy.get(".mx_RoomView").findByRole("button", { name: "Accept" }).click();
|
||||||
|
|
||||||
|
cy.findByText("Alice was invited, joined, was banned, was unbanned, was invited, and joined").should("exist");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should knock into the room and knock is cancelled by user himself", () => {
|
it("should knock into the room and knock is cancelled by user himself", () => {
|
||||||
|
|
|
@ -2229,8 +2229,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
<div className="mx_RoomView" data-room-header={roomHeaderType}>
|
<div className="mx_RoomView" data-room-header={roomHeaderType}>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<RoomPreviewBar
|
<RoomPreviewBar
|
||||||
|
onJoinClick={this.onJoinButtonClicked}
|
||||||
room={this.state.room}
|
room={this.state.room}
|
||||||
promptAskToJoin={myMembership === "leave" || this.state.promptAskToJoin}
|
canAskToJoinAndMembershipIsLeave={myMembership === "leave"}
|
||||||
|
promptAskToJoin={this.state.promptAskToJoin}
|
||||||
knocked={myMembership === "knock"}
|
knocked={myMembership === "knock"}
|
||||||
onSubmitAskToJoin={this.onSubmitAskToJoin}
|
onSubmitAskToJoin={this.onSubmitAskToJoin}
|
||||||
onCancelAskToJoin={this.onCancelAskToJoin}
|
onCancelAskToJoin={this.onCancelAskToJoin}
|
||||||
|
|
|
@ -106,6 +106,7 @@ interface IProps {
|
||||||
onRejectAndIgnoreClick?(): void;
|
onRejectAndIgnoreClick?(): void;
|
||||||
onForgetClick?(): void;
|
onForgetClick?(): void;
|
||||||
|
|
||||||
|
canAskToJoinAndMembershipIsLeave?: boolean;
|
||||||
promptAskToJoin?: boolean;
|
promptAskToJoin?: boolean;
|
||||||
knocked?: boolean;
|
knocked?: boolean;
|
||||||
onSubmitAskToJoin?(reason?: string): void;
|
onSubmitAskToJoin?(reason?: string): void;
|
||||||
|
@ -193,6 +194,8 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
||||||
if (myMember.isKicked()) {
|
if (myMember.isKicked()) {
|
||||||
if (previousMembership === "knock") {
|
if (previousMembership === "knock") {
|
||||||
return MessageCase.RequestDenied;
|
return MessageCase.RequestDenied;
|
||||||
|
} else if (this.props.promptAskToJoin) {
|
||||||
|
return MessageCase.PromptAskToJoin;
|
||||||
}
|
}
|
||||||
return MessageCase.Kicked;
|
return MessageCase.Kicked;
|
||||||
} else if (myMember.membership === "ban") {
|
} else if (myMember.membership === "ban") {
|
||||||
|
@ -208,7 +211,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
||||||
return MessageCase.Loading;
|
return MessageCase.Loading;
|
||||||
} else if (this.props.knocked) {
|
} else if (this.props.knocked) {
|
||||||
return MessageCase.Knocked;
|
return MessageCase.Knocked;
|
||||||
} else if (this.props.promptAskToJoin) {
|
} else if (this.props.canAskToJoinAndMembershipIsLeave || this.props.promptAskToJoin) {
|
||||||
return MessageCase.PromptAskToJoin;
|
return MessageCase.PromptAskToJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ 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({ room, promptAskToJoin: true });
|
const component = getComponent({ room, canAskToJoinAndMembershipIsLeave: true, promptAskToJoin: false });
|
||||||
|
|
||||||
expect(getMessage(component)).toMatchSnapshot();
|
expect(getMessage(component)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
@ -458,6 +458,14 @@ describe("<RoomPreviewBar />", () => {
|
||||||
expect(getMessage(component)).toMatchSnapshot();
|
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", () => {
|
it("renders the corresponding message with a generic title", () => {
|
||||||
const component = render(<RoomPreviewBar promptAskToJoin />);
|
const component = render(<RoomPreviewBar promptAskToJoin />);
|
||||||
expect(getMessage(component)).toMatchSnapshot();
|
expect(getMessage(component)).toMatchSnapshot();
|
||||||
|
|
|
@ -39,6 +39,31 @@ exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding mes
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding message when kicked 1`] = `
|
||||||
|
<div
|
||||||
|
class="mx_RoomPreviewBar_message"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
Ask to join RoomPreviewBar-test-room?
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<span
|
||||||
|
class="_avatar_1o69u_17 mx_BaseAvatar _avatar-imageless_1o69u_60"
|
||||||
|
data-color="4"
|
||||||
|
data-testid="avatar-img"
|
||||||
|
data-type="round"
|
||||||
|
role="presentation"
|
||||||
|
style="--cpd-avatar-size: 36px;"
|
||||||
|
>
|
||||||
|
R
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You need to be granted access to this room in order to view or participate in the conversation. You can send a request to join below.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding message with a generic title 1`] = `
|
exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding message with a generic title 1`] = `
|
||||||
<div
|
<div
|
||||||
class="mx_RoomPreviewBar_message"
|
class="mx_RoomPreviewBar_message"
|
||||||
|
|
Loading…
Reference in a new issue