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

Commit a409a13

Browse files
committed
Implement message forward pagination from start when no from is given. Include
unit tests for forward and backward pagination of room messages. Fixes #12383 .
1 parent 130668b commit a409a13

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

changelog.d/14149.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix #12383: paginate room messages from the start if no from is given. Contributed by @gnunicorn .

synapse/handlers/pagination.py

+6
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,12 @@ async def get_messages(
448448

449449
if pagin_config.from_token:
450450
from_token = pagin_config.from_token
451+
elif pagin_config.direction == "f":
452+
from_token = (
453+
await self.hs.get_event_sources().get_start_token_for_pagination(
454+
room_id
455+
)
456+
)
451457
else:
452458
from_token = (
453459
await self.hs.get_event_sources().get_current_token_for_pagination(

synapse/streams/events.py

+13
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ def get_current_token(self) -> StreamToken:
7070
)
7171
return token
7272

73+
@trace
74+
async def get_start_token_for_pagination(self, room_id: str) -> StreamToken:
75+
"""Get the start token for a given room to be used to paginate
76+
events.
77+
78+
The returned token does not have the current values for fields other
79+
than `room`, since they are not used during pagination.
80+
81+
Returns:
82+
The start token for pagination.
83+
"""
84+
return StreamToken.START
85+
7386
@trace
7487
async def get_current_token_for_pagination(self, room_id: str) -> StreamToken:
7588
"""Get the current token for a given room to be used to paginate

tests/rest/admin/test_room.py

+40
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,46 @@ def test_stream_token_is_accepted_for_fwd_pagianation(self) -> None:
18571857
self.assertIn("chunk", channel.json_body)
18581858
self.assertIn("end", channel.json_body)
18591859

1860+
def test_room_messages_backward(self) -> None:
1861+
"""Test room messages can be retrieved by an admin that isn't in the room."""
1862+
latest_event_id = self.helper.send(
1863+
self.room_id, body="message 1", tok=self.user_tok
1864+
)["event_id"]
1865+
1866+
# Check that we get the first and second message when querying /messages.
1867+
channel = self.make_request(
1868+
"GET",
1869+
"/_synapse/admin/v1/rooms/%s/messages?dir=b" % (self.room_id,),
1870+
access_token=self.admin_user_tok,
1871+
)
1872+
self.assertEqual(channel.code, 200, channel.json_body)
1873+
1874+
chunk = channel.json_body["chunk"]
1875+
self.assertEqual(len(chunk), 6, [event["content"] for event in chunk])
1876+
1877+
# in backwards, this is the first event
1878+
self.assertEqual(chunk[0]["event_id"], latest_event_id)
1879+
1880+
def test_room_messages_forward(self) -> None:
1881+
"""Test room messages can be retrieved by an admin that isn't in the room."""
1882+
latest_event_id = self.helper.send(
1883+
self.room_id, body="message 1", tok=self.user_tok
1884+
)["event_id"]
1885+
1886+
# Check that we get the first and second message when querying /messages.
1887+
channel = self.make_request(
1888+
"GET",
1889+
"/_synapse/admin/v1/rooms/%s/messages?dir=f" % (self.room_id,),
1890+
access_token=self.admin_user_tok,
1891+
)
1892+
self.assertEqual(channel.code, 200, channel.json_body)
1893+
1894+
chunk = channel.json_body["chunk"]
1895+
self.assertEqual(len(chunk), 6, [event["content"] for event in chunk])
1896+
1897+
# in forward, this is the last event
1898+
self.assertEqual(chunk[5]["event_id"], latest_event_id)
1899+
18601900
def test_room_messages_purge(self) -> None:
18611901
"""Test room messages can be retrieved by an admin that isn't in the room."""
18621902
store = self.hs.get_datastores().main

0 commit comments

Comments
 (0)