From f2917c05571f666886ede4788d0f3963c570b3f3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 21 Jul 2023 15:08:02 +0100 Subject: [PATCH 1/3] Fix invite dialog showing the same user multiple times --- src/components/views/dialogs/InviteDialog.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 7bb714c0254..bd1371be038 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -384,6 +384,7 @@ export default class InviteDialog extends React.PureComponent t); // cheap clone for mutation - const idx = targets.indexOf(member); + const idx = targets.findIndex((m) => m.userId === member.userId); if (idx >= 0) { targets.splice(idx, 1); } else { @@ -945,11 +948,11 @@ export default class InviteDialog extends React.PureComponent { return ( + !this.state.recents.some((m) => m.userId === u.userId) && !sourceMembers.some((m) => m.userId === u.userId) && !priorityAdditionalMembers.some((m) => m.userId === u.userId) && !otherAdditionalMembers.some((m) => m.userId === u.userId) From 9a906e0c00d4e018faf2dc09dc64ca65aa884020 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 21 Jul 2023 17:39:46 +0100 Subject: [PATCH 2/3] Add test --- src/components/views/dialogs/InviteDialog.tsx | 5 +++-- test/components/views/dialogs/InviteDialog-test.tsx | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index bd1371be038..fa81a28bee0 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -21,6 +21,7 @@ import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import { logger } from "matrix-js-sdk/src/logger"; import { MatrixError } from "matrix-js-sdk/src/matrix"; +import { uniqBy } from "lodash"; import { Icon as InfoIcon } from "../../../../res/img/element-icons/info.svg"; import { Icon as EmailPillAvatarIcon } from "../../../../res/img/icon-email-pill-avatar.svg"; @@ -948,11 +949,11 @@ export default class InviteDialog extends React.PureComponent t.userId), }); } else { this.setState({ - targets: [...new Set([...this.state.targets, ...toAdd])], + targets: uniqBy([...this.state.targets, ...toAdd], (t) => t.userId), }); } }; diff --git a/test/components/views/dialogs/InviteDialog-test.tsx b/test/components/views/dialogs/InviteDialog-test.tsx index fdd936a421e..b4f9640fa4f 100644 --- a/test/components/views/dialogs/InviteDialog-test.tsx +++ b/test/components/views/dialogs/InviteDialog-test.tsx @@ -366,6 +366,19 @@ describe("InviteDialog", () => { ]); }); + it("should not allow pasting the same user multiple times", async () => { + render(); + + const input = screen.getByTestId("invite-dialog-input"); + input.focus(); + await userEvent.paste(`${bobId}`); + await userEvent.paste(`${bobId}`); + await userEvent.paste(`${bobId}`); + + expect(input).toHaveValue(""); + await expect(screen.findAllByText(bobId, { selector: "a" })).resolves.toHaveLength(1); + }); + describe("when inviting a user with an unknown profile", () => { beforeEach(async () => { render(); From e843811dfd043e47f9757989b8ff979a9e34e561 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 24 Jul 2023 09:26:56 +0100 Subject: [PATCH 3/3] Improve coverage --- .../views/dialogs/InviteDialog-test.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/components/views/dialogs/InviteDialog-test.tsx b/test/components/views/dialogs/InviteDialog-test.tsx index b4f9640fa4f..645492cd3d4 100644 --- a/test/components/views/dialogs/InviteDialog-test.tsx +++ b/test/components/views/dialogs/InviteDialog-test.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React from "react"; -import { render, screen } from "@testing-library/react"; +import { fireEvent, render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { RoomType } from "matrix-js-sdk/src/@types/event"; import { MatrixClient, MatrixError, Room } from "matrix-js-sdk/src/matrix"; @@ -379,6 +379,22 @@ describe("InviteDialog", () => { await expect(screen.findAllByText(bobId, { selector: "a" })).resolves.toHaveLength(1); }); + it("should add to selection on click of user tile", async () => { + render(); + + const input = screen.getByTestId("invite-dialog-input"); + input.focus(); + await userEvent.keyboard(`${aliceId}`); + + const btn = await screen.findByText(aliceId, { + selector: ".mx_InviteDialog_tile_nameStack_userId .mx_InviteDialog_tile--room_highlight", + }); + fireEvent.click(btn); + + const tile = await screen.findByText(aliceId, { selector: ".mx_InviteDialog_userTile_name" }); + expect(tile).toBeInTheDocument(); + }); + describe("when inviting a user with an unknown profile", () => { beforeEach(async () => { render();