diff --git a/changelog.d/18675.feature b/changelog.d/18675.feature new file mode 100644 index 000000000..7ff244580 --- /dev/null +++ b/changelog.d/18675.feature @@ -0,0 +1 @@ +Include `event_id` when getting state with `?format=event`. Contributed by @tulir @ Beeper. diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py index 4600a8777..6b0deda0d 100644 --- a/synapse/rest/client/room.py +++ b/synapse/rest/client/room.py @@ -44,7 +44,11 @@ from synapse.api.errors import ( UnredactedContentDeletedError, ) from synapse.api.filtering import Filter -from synapse.events.utils import SerializeEventConfig, format_event_for_client_v2 +from synapse.events.utils import ( + SerializeEventConfig, + format_event_for_client_v2, + serialize_event, +) from synapse.http.server import HttpServer from synapse.http.servlet import ( ResolveRoomIdMixin, @@ -198,6 +202,7 @@ class RoomStateEventRestServlet(RestServlet): self.message_handler = hs.get_message_handler() self.delayed_events_handler = hs.get_delayed_events_handler() self.auth = hs.get_auth() + self.clock = hs.get_clock() self._max_event_delay_ms = hs.config.server.max_event_delay_ms self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker @@ -268,7 +273,14 @@ class RoomStateEventRestServlet(RestServlet): raise SynapseError(404, "Event not found.", errcode=Codes.NOT_FOUND) if format == "event": - event = format_event_for_client_v2(data.get_dict()) + event = serialize_event( + data, + self.clock.time_msec(), + config=SerializeEventConfig( + event_format=format_event_for_client_v2, + requester=requester, + ), + ) return 200, event elif format == "content": return 200, data.get_dict()["content"] diff --git a/tests/rest/client/test_rooms.py b/tests/rest/client/test_rooms.py index 8a6e6f118..48d33b8e1 100644 --- a/tests/rest/client/test_rooms.py +++ b/tests/rest/client/test_rooms.py @@ -552,6 +552,51 @@ class RoomStateTestCase(RoomBase): self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.result["body"]) self.assertEqual(channel.json_body, {"membership": "join"}) + def test_get_state_format_content(self) -> None: + """Test response of a `/rooms/$room_id/state/$event_type?format=content` request.""" + room_id = self.helper.create_room_as(self.user_id) + channel1 = self.make_request( + "GET", + "/rooms/%s/state/m.room.member/%s?format=content" + % ( + room_id, + self.user_id, + ), + ) + self.assertEqual(channel1.code, HTTPStatus.OK, channel1.json_body) + self.assertEqual(channel1.json_body, {"membership": "join"}) + channel2 = self.make_request( + "GET", + "/rooms/%s/state/m.room.member/%s" + % ( + room_id, + self.user_id, + ), + ) + self.assertEqual(channel2.code, HTTPStatus.OK, channel2.json_body) + # "content" is the default format. + self.assertEqual(channel1.json_body, channel2.json_body) + + def test_get_state_format_event(self) -> None: + """Test response of a `/rooms/$room_id/state/$event_type?format=event` request.""" + room_id = self.helper.create_room_as(self.user_id) + channel = self.make_request( + "GET", + "/rooms/%s/state/m.room.member/%s?format=event" + % ( + room_id, + self.user_id, + ), + ) + self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body) + self.assertEqual(channel.json_body["content"], {"membership": "join"}) + self.assertEqual(channel.json_body["room_id"], room_id) + self.assertRegex(channel.json_body["event_id"], r"\$.+") + self.assertEqual(channel.json_body["type"], "m.room.member") + self.assertEqual(channel.json_body["sender"], self.user_id) + self.assertEqual(channel.json_body["state_key"], self.user_id) + self.assertTrue(type(channel.json_body["origin_server_ts"]) is int) + class RoomsMemberListTestCase(RoomBase): """Tests /rooms/$room_id/members/list REST events."""