Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit f90d381

Browse files
authored
Edits/annotations should not have any bundled aggregations calculated. (#12633)
Fixes a regression from 8b309ad (#11660) and b65acea (#11752) where events which themselves were an edit or an annotation could have bundled aggregations calculated, which is not allowed.
1 parent ddc8bba commit f90d381

File tree

3 files changed

+50
-20
lines changed

3 files changed

+50
-20
lines changed

changelog.d/12633.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug introduced in Synapse v1.53.0 where bundled aggregations for annotations/edits were incorrectly calculated.

synapse/handlers/relations.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -364,21 +364,29 @@ async def get_bundled_aggregations(
364364
The results may include additional events which are related to the
365365
requested events.
366366
"""
367-
# De-duplicate events by ID to handle the same event requested multiple times.
368-
#
369-
# State events do not get bundled aggregations.
370-
events_by_id = {
371-
event.event_id: event for event in events if not event.is_state()
372-
}
373-
367+
# De-duplicated events by ID to handle the same event requested multiple times.
368+
events_by_id = {}
374369
# A map of event ID to the relation in that event, if there is one.
375370
relations_by_id: Dict[str, str] = {}
376-
for event_id, event in events_by_id.items():
371+
for event in events:
372+
# State events do not get bundled aggregations.
373+
if event.is_state():
374+
continue
375+
377376
relates_to = event.content.get("m.relates_to")
377+
relation_type = None
378378
if isinstance(relates_to, collections.abc.Mapping):
379379
relation_type = relates_to.get("rel_type")
380-
if isinstance(relation_type, str):
381-
relations_by_id[event_id] = relation_type
380+
# An event which is a replacement (ie edit) or annotation (ie,
381+
# reaction) may not have any other event related to it.
382+
if relation_type in (RelationTypes.ANNOTATION, RelationTypes.REPLACE):
383+
continue
384+
385+
# The event should get bundled aggregations.
386+
events_by_id[event.event_id] = event
387+
# Track the event's relation information for later.
388+
if isinstance(relation_type, str):
389+
relations_by_id[event.event_id] = relation_type
382390

383391
# event ID -> bundled aggregation in non-serialized form.
384392
results: Dict[str, BundledAggregations] = {}
@@ -413,16 +421,6 @@ async def get_bundled_aggregations(
413421

414422
# Fetch other relations per event.
415423
for event in events_by_id.values():
416-
# An event which is a replacement (ie edit) or annotation (ie, reaction)
417-
# may not have any other event related to it.
418-
#
419-
# XXX This is buggy, see https://github.com/matrix-org/synapse/issues/12566
420-
if relations_by_id.get(event.event_id) in (
421-
RelationTypes.ANNOTATION,
422-
RelationTypes.REPLACE,
423-
):
424-
continue
425-
426424
# Fetch any annotations (ie, reactions) to bundle with this event.
427425
annotations = await self.get_annotations_for_event(
428426
event.event_id, event.room_id, ignored_users=ignored_users

tests/rest/client/test_relations.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,19 @@ def test_edit_edit(self) -> None:
620620
{"event_id": edit_event_id, "sender": self.user_id}, m_replace_dict
621621
)
622622

623+
# Directly requesting the edit should not have the edit to the edit applied.
624+
channel = self.make_request(
625+
"GET",
626+
f"/rooms/{self.room}/event/{edit_event_id}",
627+
access_token=self.user_token,
628+
)
629+
self.assertEqual(200, channel.code, channel.json_body)
630+
self.assertEqual("Wibble", channel.json_body["content"]["body"])
631+
self.assertIn("m.new_content", channel.json_body["content"])
632+
633+
# The relations information should not include the edit to the edit.
634+
self.assertNotIn("m.relations", channel.json_body["unsigned"])
635+
623636
def test_unknown_relations(self) -> None:
624637
"""Unknown relations should be accepted."""
625638
channel = self._send_relation("m.relation.test", "m.room.test")
@@ -984,6 +997,24 @@ def assert_annotations(bundled_aggregations: JsonDict) -> None:
984997

985998
self._test_bundled_aggregations(RelationTypes.ANNOTATION, assert_annotations, 7)
986999

1000+
def test_annotation_to_annotation(self) -> None:
1001+
"""Any relation to an annotation should be ignored."""
1002+
channel = self._send_relation(RelationTypes.ANNOTATION, "m.reaction", "a")
1003+
event_id = channel.json_body["event_id"]
1004+
self._send_relation(
1005+
RelationTypes.ANNOTATION, "m.reaction", "b", parent_id=event_id
1006+
)
1007+
1008+
# Fetch the initial annotation event to see if it has bundled aggregations.
1009+
channel = self.make_request(
1010+
"GET",
1011+
f"/_matrix/client/v3/rooms/{self.room}/event/{event_id}",
1012+
access_token=self.user_token,
1013+
)
1014+
self.assertEquals(200, channel.code, channel.json_body)
1015+
# The first annotationt should not have any bundled aggregations.
1016+
self.assertNotIn("m.relations", channel.json_body["unsigned"])
1017+
9871018
def test_reference(self) -> None:
9881019
"""
9891020
Test that references get correctly bundled.

0 commit comments

Comments
 (0)