Fix email lookup in invite dialog (#10150)

pull/28788/head^2
Michael Weimann 2023-02-14 13:21:29 +01:00 committed by GitHub
parent 18c9b2bed2
commit 6ab44fd2cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 33 deletions

View File

@ -684,7 +684,8 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
display_name: profile.displayname, display_name: profile.displayname,
avatar_url: profile.avatar_url, avatar_url: profile.avatar_url,
}), }),
userId: lookup.mxid, // Use the search term as identifier, so that it shows up in suggestions.
userId: term,
}, },
], ],
}); });
@ -934,7 +935,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
<DMRoomTile <DMRoomTile
member={r.user} member={r.user}
lastActiveTs={lastActive(r)} lastActiveTs={lastActive(r)}
key={r.userId} key={r.user.userId}
onToggle={this.toggleMember} onToggle={this.toggleMember}
highlightWord={this.state.filterText} highlightWord={this.state.filterText}
isSelected={this.state.targets.some((t) => t.userId === r.userId)} isSelected={this.state.targets.some((t) => t.userId === r.userId)}

View File

@ -17,11 +17,11 @@ limitations under the License.
import React from "react"; import React from "react";
import { render, screen } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import { RoomType } from "matrix-js-sdk/src/@types/event"; import { RoomType } from "matrix-js-sdk/src/@types/event";
import { Room } from "matrix-js-sdk/src/matrix";
import InviteDialog from "../../../../src/components/views/dialogs/InviteDialog"; import InviteDialog from "../../../../src/components/views/dialogs/InviteDialog";
import { KIND_INVITE } from "../../../../src/components/views/dialogs/InviteDialogTypes"; import { KIND_DM, KIND_INVITE } from "../../../../src/components/views/dialogs/InviteDialogTypes";
import { getMockClientWithEventEmitter, mkStubRoom } from "../../../test-utils"; import { getMockClientWithEventEmitter, mkMembership, mkMessage, mkRoomCreateEvent } from "../../../test-utils";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../src/utils/DMRoomMap"; import DMRoomMap from "../../../../src/utils/DMRoomMap";
import SdkConfig from "../../../../src/SdkConfig"; import SdkConfig from "../../../../src/SdkConfig";
import { ValidatedServerConfig } from "../../../../src/utils/ValidatedServerConfig"; import { ValidatedServerConfig } from "../../../../src/utils/ValidatedServerConfig";
@ -37,8 +37,11 @@ jest.mock("../../../../src/IdentityAuthClient", () =>
describe("InviteDialog", () => { describe("InviteDialog", () => {
const roomId = "!111111111111111111:example.org"; const roomId = "!111111111111111111:example.org";
const aliceId = "@alice:example.org"; const aliceId = "@alice:example.org";
const aliceEmail = "foobar@email.com";
const bobId = "@bob:example.org";
const mockClient = getMockClientWithEventEmitter({ const mockClient = getMockClientWithEventEmitter({
getUserId: jest.fn().mockReturnValue(aliceId), getUserId: jest.fn().mockReturnValue(bobId),
getSafeUserId: jest.fn().mockReturnValue(bobId),
isGuest: jest.fn().mockReturnValue(false), isGuest: jest.fn().mockReturnValue(false),
getVisibleRooms: jest.fn().mockReturnValue([]), getVisibleRooms: jest.fn().mockReturnValue([]),
getRoom: jest.fn(), getRoom: jest.fn(),
@ -58,27 +61,53 @@ describe("InviteDialog", () => {
getOpenIdToken: jest.fn().mockResolvedValue({}), getOpenIdToken: jest.fn().mockResolvedValue({}),
getIdentityAccount: jest.fn().mockResolvedValue({}), getIdentityAccount: jest.fn().mockResolvedValue({}),
getTerms: jest.fn().mockResolvedValue({ policies: [] }), getTerms: jest.fn().mockResolvedValue({ policies: [] }),
supportsThreads: jest.fn().mockReturnValue(false),
isInitialSyncComplete: jest.fn().mockReturnValue(true),
}); });
let room: Room;
beforeEach(() => { beforeEach(() => {
SdkConfig.put({ validated_server_config: {} as ValidatedServerConfig } as IConfigOptions); SdkConfig.put({ validated_server_config: {} as ValidatedServerConfig } as IConfigOptions);
DMRoomMap.makeShared(); DMRoomMap.makeShared();
jest.clearAllMocks(); jest.clearAllMocks();
mockClient.getUserId.mockReturnValue("@bob:example.org"); mockClient.getUserId.mockReturnValue(bobId);
const room = mkStubRoom(roomId, "Room", mockClient); room = new Room(roomId, mockClient, mockClient.getSafeUserId());
room.addLiveEvents([
mkMessage({
msg: "Hello",
relatesTo: undefined,
event: true,
room: roomId,
user: mockClient.getSafeUserId(),
ts: Date.now(),
}),
]);
room.currentState.setStateEvents([
mkRoomCreateEvent(bobId, roomId),
mkMembership({
event: true,
room: roomId,
mship: "join",
user: aliceId,
skey: aliceId,
}),
]);
jest.spyOn(DMRoomMap.shared(), "getUniqueRoomsWithIndividuals").mockReturnValue({
[aliceId]: room,
});
mockClient.getRooms.mockReturnValue([room]); mockClient.getRooms.mockReturnValue([room]);
mockClient.getRoom.mockReturnValue(room); mockClient.getRoom.mockReturnValue(room);
}); });
afterAll(() => { afterAll(() => {
jest.spyOn(MatrixClientPeg, "get").mockRestore(); jest.restoreAllMocks();
}); });
it("should label with space name", () => { it("should label with space name", () => {
mockClient.getRoom(roomId)!.isSpaceRoom = jest.fn().mockReturnValue(true); room.isSpaceRoom = jest.fn().mockReturnValue(true);
mockClient.getRoom(roomId)!.getType = jest.fn().mockReturnValue(RoomType.Space); room.getType = jest.fn().mockReturnValue(RoomType.Space);
mockClient.getRoom(roomId)!.name = "Space"; room.name = "Space";
render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />); render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />);
expect(screen.queryByText("Invite to Space")).toBeTruthy(); expect(screen.queryByText("Invite to Space")).toBeTruthy();
@ -86,8 +115,7 @@ describe("InviteDialog", () => {
it("should label with room name", () => { it("should label with room name", () => {
render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />); render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />);
expect(screen.getByText(`Invite to ${roomId}`)).toBeInTheDocument();
expect(screen.queryByText("Invite to Room")).toBeTruthy();
}); });
it("should suggest valid MXIDs even if unknown", async () => { it("should suggest valid MXIDs even if unknown", async () => {
@ -116,27 +144,37 @@ describe("InviteDialog", () => {
expect(screen.queryByText("@localpart:server:tld")).toBeFalsy(); expect(screen.queryByText("@localpart:server:tld")).toBeFalsy();
}); });
it("should lookup inputs which look like email addresses", async () => { it.each([[KIND_DM], [KIND_INVITE]] as [typeof KIND_DM | typeof KIND_INVITE][])(
mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server"); "should lookup inputs which look like email addresses (%s)",
mockClient.lookupThreePid.mockResolvedValue({ async (kind: typeof KIND_DM | typeof KIND_INVITE) => {
address: "foobar@email.com", mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server");
medium: "email", mockClient.lookupThreePid.mockResolvedValue({
mxid: "@foobar:server", address: aliceEmail,
}); medium: "email",
mockClient.getProfileInfo.mockResolvedValue({ mxid: aliceId,
displayname: "Mr. Foo", });
avatar_url: "mxc://foo/bar", mockClient.getProfileInfo.mockResolvedValue({
}); displayname: "Mrs Alice",
avatar_url: "mxc://foo/bar",
});
render( render(
<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} initialText="foobar@email.com" />, <InviteDialog
); kind={kind}
roomId={kind === KIND_INVITE ? roomId : ""}
onFinished={jest.fn()}
initialText={aliceEmail}
/>,
);
await screen.findByText("Mr. Foo"); await screen.findByText("Mrs Alice");
await screen.findByText("@foobar:server"); // expect the email and MXID to be visible
expect(mockClient.lookupThreePid).toHaveBeenCalledWith("email", "foobar@email.com", expect.anything()); await screen.findByText(aliceId);
expect(mockClient.getProfileInfo).toHaveBeenCalledWith("@foobar:server"); await screen.findByText(aliceEmail);
}); expect(mockClient.lookupThreePid).toHaveBeenCalledWith("email", aliceEmail, expect.anything());
expect(mockClient.getProfileInfo).toHaveBeenCalledWith(aliceId);
},
);
it("should suggest e-mail even if lookup fails", async () => { it("should suggest e-mail even if lookup fails", async () => {
mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server"); mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server");