mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-12-10 15:26:08 -05:00
Add an API for listing threads in a room. (#13394)
Implement the /threads endpoint from MSC3856. This is currently unstable and behind an experimental configuration flag. It includes a background update to backfill data, results from the /threads endpoint will be partial until that finishes.
This commit is contained in:
parent
b6baa46db0
commit
3bbe532abb
10 changed files with 522 additions and 6 deletions
|
|
@ -1707,3 +1707,154 @@ class RelationRedactionTestCase(BaseRelationsTestCase):
|
|||
relations[RelationTypes.THREAD]["latest_event"]["event_id"],
|
||||
related_event_id,
|
||||
)
|
||||
|
||||
|
||||
class ThreadsTestCase(BaseRelationsTestCase):
|
||||
@unittest.override_config({"experimental_features": {"msc3856_enabled": True}})
|
||||
def test_threads(self) -> None:
|
||||
"""Create threads and ensure the ordering is due to their latest event."""
|
||||
# Create 2 threads.
|
||||
thread_1 = self.parent_id
|
||||
res = self.helper.send(self.room, body="Thread Root!", tok=self.user_token)
|
||||
thread_2 = res["event_id"]
|
||||
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test")
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test", parent_id=thread_2)
|
||||
|
||||
# Request the threads in the room.
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_2, thread_1])
|
||||
|
||||
# Update the first thread, the ordering should swap.
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test")
|
||||
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_1, thread_2])
|
||||
|
||||
@unittest.override_config({"experimental_features": {"msc3856_enabled": True}})
|
||||
def test_pagination(self) -> None:
|
||||
"""Create threads and paginate through them."""
|
||||
# Create 2 threads.
|
||||
thread_1 = self.parent_id
|
||||
res = self.helper.send(self.room, body="Thread Root!", tok=self.user_token)
|
||||
thread_2 = res["event_id"]
|
||||
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test")
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test", parent_id=thread_2)
|
||||
|
||||
# Request the threads in the room.
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads?limit=1",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_2])
|
||||
|
||||
# Make sure next_batch has something in it that looks like it could be a
|
||||
# valid token.
|
||||
next_batch = channel.json_body.get("next_batch")
|
||||
self.assertIsInstance(next_batch, str, channel.json_body)
|
||||
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads?limit=1&from={next_batch}",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_1], channel.json_body)
|
||||
|
||||
self.assertNotIn("next_batch", channel.json_body, channel.json_body)
|
||||
|
||||
@unittest.override_config({"experimental_features": {"msc3856_enabled": True}})
|
||||
def test_include(self) -> None:
|
||||
"""Filtering threads to all or participated in should work."""
|
||||
# Thread 1 has the user as the root event.
|
||||
thread_1 = self.parent_id
|
||||
self._send_relation(
|
||||
RelationTypes.THREAD, "m.room.test", access_token=self.user2_token
|
||||
)
|
||||
|
||||
# Thread 2 has the user replying.
|
||||
res = self.helper.send(self.room, body="Thread Root!", tok=self.user2_token)
|
||||
thread_2 = res["event_id"]
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test", parent_id=thread_2)
|
||||
|
||||
# Thread 3 has the user not participating in.
|
||||
res = self.helper.send(self.room, body="Another thread!", tok=self.user2_token)
|
||||
thread_3 = res["event_id"]
|
||||
self._send_relation(
|
||||
RelationTypes.THREAD,
|
||||
"m.room.test",
|
||||
access_token=self.user2_token,
|
||||
parent_id=thread_3,
|
||||
)
|
||||
|
||||
# All threads in the room.
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(
|
||||
thread_roots, [thread_3, thread_2, thread_1], channel.json_body
|
||||
)
|
||||
|
||||
# Only participated threads.
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads?include=participated",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_2, thread_1], channel.json_body)
|
||||
|
||||
@unittest.override_config({"experimental_features": {"msc3856_enabled": True}})
|
||||
def test_ignored_user(self) -> None:
|
||||
"""Events from ignored users should be ignored."""
|
||||
# Thread 1 has a reply from an ignored user.
|
||||
thread_1 = self.parent_id
|
||||
self._send_relation(
|
||||
RelationTypes.THREAD, "m.room.test", access_token=self.user2_token
|
||||
)
|
||||
|
||||
# Thread 2 is created by an ignored user.
|
||||
res = self.helper.send(self.room, body="Thread Root!", tok=self.user2_token)
|
||||
thread_2 = res["event_id"]
|
||||
self._send_relation(RelationTypes.THREAD, "m.room.test", parent_id=thread_2)
|
||||
|
||||
# Ignore user2.
|
||||
self.get_success(
|
||||
self.store.add_account_data_for_user(
|
||||
self.user_id,
|
||||
AccountDataTypes.IGNORED_USER_LIST,
|
||||
{"ignored_users": {self.user2_id: {}}},
|
||||
)
|
||||
)
|
||||
|
||||
# Only thread 1 is returned.
|
||||
channel = self.make_request(
|
||||
"GET",
|
||||
f"/_matrix/client/unstable/org.matrix.msc3856/rooms/{self.room}/threads",
|
||||
access_token=self.user_token,
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
thread_roots = [ev["event_id"] for ev in channel.json_body["chunk"]]
|
||||
self.assertEqual(thread_roots, [thread_1], channel.json_body)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue