diff --git a/src/utils/dm/findDMForUser.ts b/src/utils/dm/findDMForUser.ts index 3f6fcbfca0..c8b5f615d7 100644 --- a/src/utils/dm/findDMForUser.ts +++ b/src/utils/dm/findDMForUser.ts @@ -38,7 +38,15 @@ function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined { (m) => !functionalUsers.includes(m.userId) && m.membership && isJoinedOrNearlyJoined(m.membership), ); const otherMember = joinedMembers.find((m) => m.userId === userId); - return otherMember && joinedMembers.length === 2; + + if (otherMember && joinedMembers.length === 2) { + return true; + } + + const thirdPartyInvites = r.currentState.getStateEvents("m.room.third_party_invite") || []; + + // match room with pending third-party invite + return joinedMembers.length === 1 && thirdPartyInvites.length === 1; } return false; }) diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts index 2e700c2b18..342949e768 100644 --- a/test/test-utils/test-utils.ts +++ b/test/test-utils/test-utils.ts @@ -691,6 +691,19 @@ export const mkRoomMemberJoinEvent = (user: string, room: string): MatrixEvent = }); }; +export const mkThirdPartyInviteEvent = (user: string, displayName: string, room: string): MatrixEvent => { + return mkEvent({ + event: true, + type: EventType.RoomThirdPartyInvite, + content: { + display_name: displayName, + }, + skey: "test" + Math.random(), + user, + room, + }); +}; + export const mkPusher = (extra: Partial = {}): IPusher => ({ app_display_name: "app", app_id: "123", diff --git a/test/utils/dm/findDMForUser-test.ts b/test/utils/dm/findDMForUser-test.ts index 60c5b342f4..71058ce39f 100644 --- a/test/utils/dm/findDMForUser-test.ts +++ b/test/utils/dm/findDMForUser-test.ts @@ -18,7 +18,7 @@ import { mocked } from "jest-mock"; import { MatrixClient, Room } from "matrix-js-sdk/src/matrix"; import DMRoomMap from "../../../src/utils/DMRoomMap"; -import { createTestClient, makeMembershipEvent } from "../../test-utils"; +import { createTestClient, makeMembershipEvent, mkThirdPartyInviteEvent } from "../../test-utils"; import { LocalRoom } from "../../../src/models/LocalRoom"; import { findDMForUser } from "../../../src/utils/dm/findDMForUser"; import { getFunctionalMembers } from "../../../src/utils/room/getFunctionalMembers"; @@ -32,13 +32,15 @@ describe("findDMForUser", () => { const userId2 = "@user2:example.com"; const userId3 = "@user3:example.com"; const botId = "@bot:example.com"; + const thirdPartyId = "party@example.com"; let room1: Room; let room2: LocalRoom; let room3: Room; let room4: Room; let room5: Room; let room6: Room; - const room7Id = "!room7:example.com"; + let room7: Room; + const unknownRoomId = "!unknown:example.com"; let dmRoomMap: DMRoomMap; let mockClient: MatrixClient; @@ -89,6 +91,14 @@ describe("findDMForUser", () => { makeMembershipEvent(room6.roomId, userId3, "join"), ]); + // room with pending third-party invite + room7 = new Room("!room7:example.com", mockClient, userId1); + room7.getMyMembership = () => "join"; + room7.currentState.setStateEvents([ + makeMembershipEvent(room7.roomId, userId1, "join"), + mkThirdPartyInviteEvent(thirdPartyId, "third-party", room7.roomId), + ]); + mocked(mockClient.getRoom).mockImplementation((roomId: string) => { return ( { @@ -98,6 +108,7 @@ describe("findDMForUser", () => { [room4.roomId]: room4, [room5.roomId]: room5, [room6.roomId]: room6, + [room7.roomId]: room7, }[roomId] || null ); }); @@ -113,14 +124,15 @@ describe("findDMForUser", () => { room4.roomId, room5.roomId, room6.roomId, - room7Id, // this room does not exist in client + room7.roomId, + unknownRoomId, // this room does not exist in client ]), ), } as unknown as DMRoomMap; jest.spyOn(DMRoomMap, "shared").mockReturnValue(dmRoomMap); mocked(dmRoomMap.getDMRoomsForUserId).mockImplementation((userId: string) => { if (userId === userId1) { - return [room1.roomId, room2.roomId, room3.roomId, room4.roomId, room5.roomId, room7Id]; + return [room1.roomId, room2.roomId, room3.roomId, room4.roomId, room5.roomId, unknownRoomId]; } return []; @@ -158,4 +170,8 @@ describe("findDMForUser", () => { expect(findDMForUser(mockClient, userId3)).toBe(room6); }); + + it("should find a room with a pending third-party invite", () => { + expect(findDMForUser(mockClient, thirdPartyId)).toBe(room7); + }); });