Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix wrongly grouping 3pid invites into a single repeated transition #10087

Merged
merged 4 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions src/components/views/elements/EventListSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -507,39 +507,36 @@ export default class EventListSummary extends React.Component<IProps> {
eventsToRender.forEach((e, index) => {
const type = e.getType();

let userId = e.getSender();
if (type === EventType.RoomMember) {
userId = e.getStateKey();
let userKey = e.getSender()!;
if (type === EventType.RoomThirdPartyInvite) {
userKey = e.getContent().display_name;
} else if (type === EventType.RoomMember) {
userKey = e.getStateKey();
} else if (e.isRedacted()) {
userId = e.getUnsigned()?.redacted_because?.sender;
userKey = e.getUnsigned()?.redacted_because?.sender;
}

// Initialise a user's events
if (!userEvents[userId]) {
userEvents[userId] = [];
if (!userEvents[userKey]) {
userEvents[userKey] = [];
}

let displayName = userId;
if (type === EventType.RoomThirdPartyInvite) {
displayName = e.getContent().display_name;
if (e.sender) {
latestUserAvatarMember.set(userId, e.sender);
}
} else if (e.isRedacted()) {
const sender = this.context?.room.getMember(userId);
let displayName = userKey;
if (e.isRedacted()) {
const sender = this.context?.room?.getMember(userKey);
if (sender) {
displayName = sender.name;
latestUserAvatarMember.set(userId, sender);
latestUserAvatarMember.set(userKey, sender);
}
} else if (e.target && TARGET_AS_DISPLAY_NAME_EVENTS.includes(type as EventType)) {
displayName = e.target.name;
latestUserAvatarMember.set(userId, e.target);
} else if (e.sender) {
latestUserAvatarMember.set(userKey, e.target);
} else if (e.sender && type !== EventType.RoomThirdPartyInvite) {
displayName = e.sender.name;
latestUserAvatarMember.set(userId, e.sender);
latestUserAvatarMember.set(userKey, e.sender);
}

userEvents[userId].push({
userEvents[userKey].push({
mxEvent: e,
displayName,
index: index,
Expand Down
55 changes: 54 additions & 1 deletion test/components/views/elements/EventListSummary-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { MatrixEvent, RoomMember } from "matrix-js-sdk/src/matrix";

import {
getMockClientWithEventEmitter,
mkEvent,
mkMembership,
mockClientMethodsUser,
unmockClientPeg,
Expand Down Expand Up @@ -100,7 +101,7 @@ describe("EventListSummary", function () {
// is created by replacing the first "$" in userIdTemplate with `i` for
// `i = 0 .. n`.
const generateEventsForUsers = (userIdTemplate, n, events) => {
let eventsForUsers = [];
let eventsForUsers: MatrixEvent[] = [];
let userId = "";
for (let i = 0; i < n; i++) {
userId = userIdTemplate.replace("$", i);
Expand Down Expand Up @@ -656,4 +657,56 @@ describe("EventListSummary", function () {

expect(summaryText).toBe("user_0, user_1 and 18 others joined");
});

it("should not blindly group 3pid invites and treat them as distinct users instead", () => {
const events = [
mkEvent({
event: true,
skey: "randomstring1",
user: "@user1:server",
type: "m.room.third_party_invite",
content: {
display_name: "n...@d...",
key_validity_url: "https://blah",
public_key: "public_key",
},
}),
mkEvent({
event: true,
skey: "randomstring2",
user: "@user1:server",
type: "m.room.third_party_invite",
content: {
display_name: "n...@d...",
key_validity_url: "https://blah",
public_key: "public_key",
},
}),
mkEvent({
event: true,
skey: "randomstring3",
user: "@user1:server",
type: "m.room.third_party_invite",
content: {
display_name: "d...@w...",
key_validity_url: "https://blah",
public_key: "public_key",
},
}),
];

const props = {
events: events,
children: generateTiles(events),
summaryLength: 2,
avatarsMaxLength: 5,
threshold: 3,
};

const wrapper = renderComponent(props);
const summary = wrapper.find(".mx_GenericEventListSummary_summary");
const summaryText = summary.text();

expect(summaryText).toBe("n...@d... was invited 2 times, d...@w... was invited");
});
});