mirror of
https://github.com/element-hq/synapse
synced 2024-10-03 20:12:40 +00:00
Add is_invite
filtering to Sliding Sync /sync
Based on [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575): Sliding Sync
This commit is contained in:
parent
4243c1f074
commit
1ce567ea0a
3 changed files with 172 additions and 32 deletions
|
@ -591,10 +591,20 @@ class SlidingSyncHandler:
|
|||
if (filters.is_encrypted and not is_encrypted) or (
|
||||
not filters.is_encrypted and is_encrypted
|
||||
):
|
||||
filtered_room_id_set.remove(room_id)
|
||||
filtered_room_id_set.discard(room_id)
|
||||
|
||||
if filters.is_invite:
|
||||
raise NotImplementedError()
|
||||
# Filter for rooms that the user has been invited to
|
||||
if filters.is_invite is not None:
|
||||
for room_id, room_for_user in sync_room_map.items():
|
||||
# If we're looking for invite rooms, filter out rooms that the user is
|
||||
# not invited to and vice versa
|
||||
if (
|
||||
filters.is_invite and room_for_user.membership != Membership.INVITE
|
||||
) or (
|
||||
not filters.is_invite
|
||||
and room_for_user.membership == Membership.INVITE
|
||||
):
|
||||
filtered_room_id_set.discard(room_id)
|
||||
|
||||
if filters.room_types:
|
||||
raise NotImplementedError()
|
||||
|
|
|
@ -1200,11 +1200,7 @@ class FilterRoomsTestCase(HomeserverTestCase):
|
|||
user2_tok = self.login(user2_id, "pass")
|
||||
|
||||
# Create a normal room
|
||||
room_id = self.helper.create_room_as(
|
||||
user1_id,
|
||||
is_public=False,
|
||||
tok=user1_tok,
|
||||
)
|
||||
room_id = self.helper.create_room_as(user1_id, tok=user1_tok)
|
||||
|
||||
# Create a DM room
|
||||
dm_room_id = self._create_dm_room(
|
||||
|
@ -1261,18 +1257,10 @@ class FilterRoomsTestCase(HomeserverTestCase):
|
|||
user1_tok = self.login(user1_id, "pass")
|
||||
|
||||
# Create a normal room
|
||||
room_id = self.helper.create_room_as(
|
||||
user1_id,
|
||||
is_public=False,
|
||||
tok=user1_tok,
|
||||
)
|
||||
room_id = self.helper.create_room_as(user1_id, tok=user1_tok)
|
||||
|
||||
# Create an encrypted room
|
||||
encrypted_room_id = self.helper.create_room_as(
|
||||
user1_id,
|
||||
is_public=False,
|
||||
tok=user1_tok,
|
||||
)
|
||||
encrypted_room_id = self.helper.create_room_as(user1_id, tok=user1_tok)
|
||||
self.helper.send_state(
|
||||
encrypted_room_id,
|
||||
EventTypes.RoomEncryption,
|
||||
|
@ -1319,6 +1307,62 @@ class FilterRoomsTestCase(HomeserverTestCase):
|
|||
|
||||
self.assertEqual(falsy_filtered_room_map.keys(), {room_id})
|
||||
|
||||
def test_filter_invite_rooms(self) -> None:
|
||||
"""
|
||||
Test `filter.is_invite` for rooms that the user has been invited to
|
||||
"""
|
||||
user1_id = self.register_user("user1", "pass")
|
||||
user1_tok = self.login(user1_id, "pass")
|
||||
user2_id = self.register_user("user2", "pass")
|
||||
user2_tok = self.login(user2_id, "pass")
|
||||
|
||||
# Create a normal room
|
||||
room_id = self.helper.create_room_as(user2_id, tok=user2_tok)
|
||||
self.helper.join(room_id, user1_id, tok=user1_tok)
|
||||
|
||||
# Create a room that user1 is invited to
|
||||
invite_room_id = self.helper.create_room_as(user2_id, tok=user2_tok)
|
||||
self.helper.invite(invite_room_id, src=user2_id, targ=user1_id, tok=user2_tok)
|
||||
|
||||
after_rooms_token = self.event_sources.get_current_token()
|
||||
|
||||
# Get the rooms the user should be syncing with
|
||||
sync_room_map = self.get_success(
|
||||
self.sliding_sync_handler.get_sync_room_ids_for_user(
|
||||
UserID.from_string(user1_id),
|
||||
from_token=None,
|
||||
to_token=after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
# Try with `is_invite=True`
|
||||
truthy_filtered_room_map = self.get_success(
|
||||
self.sliding_sync_handler.filter_rooms(
|
||||
UserID.from_string(user1_id),
|
||||
sync_room_map,
|
||||
SlidingSyncConfig.SlidingSyncList.Filters(
|
||||
is_invite=True,
|
||||
),
|
||||
after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(truthy_filtered_room_map.keys(), {invite_room_id})
|
||||
|
||||
# Try with `is_invite=False`
|
||||
falsy_filtered_room_map = self.get_success(
|
||||
self.sliding_sync_handler.filter_rooms(
|
||||
UserID.from_string(user1_id),
|
||||
sync_room_map,
|
||||
SlidingSyncConfig.SlidingSyncList.Filters(
|
||||
is_invite=False,
|
||||
),
|
||||
after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(falsy_filtered_room_map.keys(), {room_id})
|
||||
|
||||
|
||||
class SortRoomsTestCase(HomeserverTestCase):
|
||||
"""
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
# [This file includes modifications made by New Vector Limited]
|
||||
#
|
||||
#
|
||||
import logging
|
||||
import json
|
||||
from typing import List
|
||||
|
||||
|
@ -44,6 +45,8 @@ from tests.federation.transport.test_knocking import (
|
|||
)
|
||||
from tests.server import TimedOutException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FilterTestCase(unittest.HomeserverTestCase):
|
||||
user_id = "@apple:test"
|
||||
|
@ -1240,6 +1243,7 @@ class SlidingSyncTestCase(unittest.HomeserverTestCase):
|
|||
inviter_tok: str,
|
||||
invitee_user_id: str,
|
||||
invitee_tok: str,
|
||||
should_join_room: bool = True,
|
||||
) -> str:
|
||||
"""
|
||||
Helper to create a DM room as the "inviter" and invite the "invitee" user to the
|
||||
|
@ -1260,23 +1264,49 @@ class SlidingSyncTestCase(unittest.HomeserverTestCase):
|
|||
tok=inviter_tok,
|
||||
extra_data={"is_direct": True},
|
||||
)
|
||||
# Person that was invited joins the room
|
||||
self.helper.join(room_id, invitee_user_id, tok=invitee_tok)
|
||||
if should_join_room:
|
||||
# Person that was invited joins the room
|
||||
self.helper.join(room_id, invitee_user_id, tok=invitee_tok)
|
||||
|
||||
# Mimic the client setting the room as a direct message in the global account
|
||||
# data
|
||||
# data.
|
||||
# -------------------------------------
|
||||
|
||||
# For the invitee: Get the current map and add to it
|
||||
existing_invitee_dm_map = self.get_success(
|
||||
self.store.get_global_account_data_by_type_for_user(
|
||||
invitee_user_id, AccountDataTypes.DIRECT
|
||||
)
|
||||
)
|
||||
# Merge any existing entries
|
||||
new_invitee_dm_map = existing_invitee_dm_map or {}
|
||||
new_invitee_dm_map[inviter_user_id] = new_invitee_dm_map.get(
|
||||
inviter_user_id, []
|
||||
) + [room_id]
|
||||
self.get_success(
|
||||
self.store.add_account_data_for_user(
|
||||
invitee_user_id,
|
||||
AccountDataTypes.DIRECT,
|
||||
{inviter_user_id: [room_id]},
|
||||
new_invitee_dm_map,
|
||||
)
|
||||
)
|
||||
|
||||
# For the inviter: Get the current map and add to it
|
||||
existing_inviter_dm_map = self.get_success(
|
||||
self.store.get_global_account_data_by_type_for_user(
|
||||
inviter_user_id, AccountDataTypes.DIRECT
|
||||
)
|
||||
)
|
||||
# Merge any existing entries
|
||||
new_inviter_dm_map = existing_inviter_dm_map or {}
|
||||
new_inviter_dm_map[invitee_user_id] = new_inviter_dm_map.get(
|
||||
invitee_user_id, []
|
||||
) + [room_id]
|
||||
self.get_success(
|
||||
self.store.add_account_data_for_user(
|
||||
inviter_user_id,
|
||||
AccountDataTypes.DIRECT,
|
||||
{invitee_user_id: [room_id]},
|
||||
new_inviter_dm_map,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1397,15 +1427,28 @@ class SlidingSyncTestCase(unittest.HomeserverTestCase):
|
|||
user2_tok = self.login(user2_id, "pass")
|
||||
|
||||
# Create a DM room
|
||||
dm_room_id = self._create_dm_room(
|
||||
joined_dm_room_id = self._create_dm_room(
|
||||
inviter_user_id=user1_id,
|
||||
inviter_tok=user1_tok,
|
||||
invitee_user_id=user2_id,
|
||||
invitee_tok=user2_tok,
|
||||
should_join_room=True,
|
||||
)
|
||||
invited_dm_room_id = self._create_dm_room(
|
||||
inviter_user_id=user1_id,
|
||||
inviter_tok=user1_tok,
|
||||
invitee_user_id=user2_id,
|
||||
invitee_tok=user2_tok,
|
||||
should_join_room=False,
|
||||
)
|
||||
|
||||
# Create a normal room
|
||||
room_id = self.helper.create_room_as(user1_id, tok=user1_tok, is_public=True)
|
||||
room_id = self.helper.create_room_as(user1_id, tok=user2_tok)
|
||||
self.helper.join(room_id, user1_id, tok=user1_tok)
|
||||
|
||||
# Create a room that user1 is invited to
|
||||
invite_room_id = self.helper.create_room_as(user1_id, tok=user2_tok)
|
||||
self.helper.invite(invite_room_id, src=user2_id, targ=user1_id, tok=user2_tok)
|
||||
|
||||
# Make the Sliding Sync request
|
||||
channel = self.make_request(
|
||||
|
@ -1413,18 +1456,34 @@ class SlidingSyncTestCase(unittest.HomeserverTestCase):
|
|||
self.sync_endpoint,
|
||||
{
|
||||
"lists": {
|
||||
# Absense of filters does not imply "False" values
|
||||
"all": {
|
||||
"ranges": [[0, 99]],
|
||||
"required_state": [],
|
||||
"timeline_limit": 1,
|
||||
"filters": {},
|
||||
},
|
||||
# Test single truthy filter
|
||||
"dms": {
|
||||
"ranges": [[0, 99]],
|
||||
"required_state": [],
|
||||
"timeline_limit": 1,
|
||||
"filters": {"is_dm": True},
|
||||
},
|
||||
"foo-list": {
|
||||
# Test single falsy filter
|
||||
"non-dms": {
|
||||
"ranges": [[0, 99]],
|
||||
"required_state": [],
|
||||
"timeline_limit": 1,
|
||||
"filters": {"is_dm": False},
|
||||
},
|
||||
# Test how multiple filters should stack (AND'd together)
|
||||
"room-invites": {
|
||||
"ranges": [[0, 99]],
|
||||
"required_state": [],
|
||||
"timeline_limit": 1,
|
||||
"filters": {"is_dm": False, "is_invite": True},
|
||||
},
|
||||
}
|
||||
},
|
||||
access_token=user1_tok,
|
||||
|
@ -1434,32 +1493,59 @@ class SlidingSyncTestCase(unittest.HomeserverTestCase):
|
|||
# Make sure it has the foo-list we requested
|
||||
self.assertListEqual(
|
||||
list(channel.json_body["lists"].keys()),
|
||||
["dms", "foo-list"],
|
||||
["all", "dms", "non-dms", "room-invites"],
|
||||
channel.json_body["lists"].keys(),
|
||||
)
|
||||
|
||||
# Make sure the list includes the room we are joined to
|
||||
# Make sure the lists have the correct rooms
|
||||
self.assertListEqual(
|
||||
list(channel.json_body["lists"]["all"]["ops"]),
|
||||
[
|
||||
{
|
||||
"op": "SYNC",
|
||||
"range": [0, 99],
|
||||
"room_ids": [
|
||||
invite_room_id,
|
||||
room_id,
|
||||
invited_dm_room_id,
|
||||
joined_dm_room_id,
|
||||
],
|
||||
}
|
||||
],
|
||||
list(channel.json_body["lists"]["all"]),
|
||||
)
|
||||
self.assertListEqual(
|
||||
list(channel.json_body["lists"]["dms"]["ops"]),
|
||||
[
|
||||
{
|
||||
"op": "SYNC",
|
||||
"range": [0, 99],
|
||||
"room_ids": [dm_room_id],
|
||||
"room_ids": [invited_dm_room_id, joined_dm_room_id],
|
||||
}
|
||||
],
|
||||
list(channel.json_body["lists"]["dms"]),
|
||||
)
|
||||
self.assertListEqual(
|
||||
list(channel.json_body["lists"]["foo-list"]["ops"]),
|
||||
list(channel.json_body["lists"]["non-dms"]["ops"]),
|
||||
[
|
||||
{
|
||||
"op": "SYNC",
|
||||
"range": [0, 99],
|
||||
"room_ids": [room_id],
|
||||
"room_ids": [invite_room_id, room_id],
|
||||
}
|
||||
],
|
||||
list(channel.json_body["lists"]["foo-list"]),
|
||||
list(channel.json_body["lists"]["non-dms"]),
|
||||
)
|
||||
self.assertListEqual(
|
||||
list(channel.json_body["lists"]["room-invites"]["ops"]),
|
||||
[
|
||||
{
|
||||
"op": "SYNC",
|
||||
"range": [0, 99],
|
||||
"room_ids": [invite_room_id],
|
||||
}
|
||||
],
|
||||
list(channel.json_body["lists"]["room-invites"]),
|
||||
)
|
||||
|
||||
def test_sort_list(self) -> None:
|
||||
|
|
Loading…
Reference in a new issue