@ -14,8 +14,18 @@
from typing import Any , Iterable , Optional , Tuple
from unittest import mock
from synapse . api . constants import EventContentFields , JoinRules , RoomTypes
from synapse . api . constants import (
EventContentFields ,
EventTypes ,
HistoryVisibility ,
JoinRules ,
Membership ,
RestrictedJoinRuleTypes ,
RoomTypes ,
)
from synapse . api . errors import AuthError
from synapse . api . room_versions import RoomVersions
from synapse . events import make_event_from_dict
from synapse . handlers . space_summary import _child_events_comparison_key
from synapse . rest import admin
from synapse . rest . client . v1 import login , room
@ -117,7 +127,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
""" Add a child room to a space. """
self . helper . send_state (
space_id ,
event_type = " m.space.child " ,
event_type = EventTypes . SpaceChild ,
body = { " via " : [ self . hs . hostname ] } ,
tok = token ,
state_key = room_id ,
@ -155,29 +165,129 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
# The user cannot see the space.
self . get_failure ( self . handler . get_space_summary ( user2 , self . space ) , AuthError )
# Joining the room causes it to be visible.
self . helper . join ( self . space , user2 , tok = token2 )
# If the space is made world-readable it should return a result.
self . helper . send_state (
self . space ,
event_type = EventTypes . RoomHistoryVisibility ,
body = { " history_visibility " : HistoryVisibility . WORLD_READABLE } ,
tok = self . token ,
)
result = self . get_success ( self . handler . get_space_summary ( user2 , self . space ) )
# The result should only have the space, but includes the link to the room.
self . _assert_rooms ( result , [ self . space ] )
self . _assert_rooms ( result , [ self . space , self . room ] )
self . _assert_events ( result , [ ( self . space , self . room ) ] )
def test_world_readable ( self ) :
""" A world-readable room is visible to everyone. """
# Make it not world-readable again and confirm it results in an error.
self . helper . send_state (
self . space ,
event_type = " m.room.history_visibility " ,
body = { " history_visibility " : " world_readable " } ,
event_type = EventTypes . RoomHistoryVisibility ,
body = { " history_visibility " : HistoryVisibility . JOINED } ,
tok = self . token ,
)
self . get_failure ( self . handler . get_space_summary ( user2 , self . space ) , AuthError )
# Join the space and results should be returned.
self . helper . join ( self . space , user2 , tok = token2 )
result = self . get_success ( self . handler . get_space_summary ( user2 , self . space ) )
self . _assert_rooms ( result , [ self . space , self . room ] )
self . _assert_events ( result , [ ( self . space , self . room ) ] )
def _create_room_with_join_rule (
self , join_rule : str , room_version : Optional [ str ] = None , * * extra_content
) - > str :
""" Create a room with the given join rule and add it to the space. """
room_id = self . helper . create_room_as (
self . user ,
room_version = room_version ,
tok = self . token ,
extra_content = {
" initial_state " : [
{
" type " : EventTypes . JoinRules ,
" state_key " : " " ,
" content " : {
" join_rule " : join_rule ,
* * extra_content ,
} ,
}
]
} ,
)
self . _add_child ( self . space , room_id , self . token )
return room_id
def test_filtering ( self ) :
"""
Rooms should be properly filtered to only include rooms the user has access to .
"""
user2 = self . register_user ( " user2 " , " pass " )
token2 = self . login ( " user2 " , " pass " )
# The space should be visible, as well as the link to the room.
# Create a few rooms which will have different properties.
public_room = self . _create_room_with_join_rule ( JoinRules . PUBLIC )
knock_room = self . _create_room_with_join_rule (
JoinRules . KNOCK , room_version = RoomVersions . V7 . identifier
)
not_invited_room = self . _create_room_with_join_rule ( JoinRules . INVITE )
invited_room = self . _create_room_with_join_rule ( JoinRules . INVITE )
self . helper . invite ( invited_room , targ = user2 , tok = self . token )
restricted_room = self . _create_room_with_join_rule (
JoinRules . MSC3083_RESTRICTED ,
room_version = RoomVersions . MSC3083 . identifier ,
allow = [ ] ,
)
restricted_accessible_room = self . _create_room_with_join_rule (
JoinRules . MSC3083_RESTRICTED ,
room_version = RoomVersions . MSC3083 . identifier ,
allow = [
{
" type " : RestrictedJoinRuleTypes . ROOM_MEMBERSHIP ,
" room_id " : self . space ,
" via " : [ self . hs . hostname ] ,
}
] ,
)
world_readable_room = self . _create_room_with_join_rule ( JoinRules . INVITE )
self . helper . send_state (
world_readable_room ,
event_type = EventTypes . RoomHistoryVisibility ,
body = { " history_visibility " : HistoryVisibility . WORLD_READABLE } ,
tok = self . token ,
)
joined_room = self . _create_room_with_join_rule ( JoinRules . INVITE )
self . helper . invite ( joined_room , targ = user2 , tok = self . token )
self . helper . join ( joined_room , user2 , tok = token2 )
# Join the space.
self . helper . join ( self . space , user2 , tok = token2 )
result = self . get_success ( self . handler . get_space_summary ( user2 , self . space ) )
self . _assert_rooms ( result , [ self . space ] )
self . _assert_events ( result , [ ( self . space , self . room ) ] )
self . _assert_rooms (
result ,
[
self . space ,
self . room ,
public_room ,
knock_room ,
invited_room ,
restricted_accessible_room ,
world_readable_room ,
joined_room ,
] ,
)
self . _assert_events (
result ,
[
( self . space , self . room ) ,
( self . space , public_room ) ,
( self . space , knock_room ) ,
( self . space , not_invited_room ) ,
( self . space , invited_room ) ,
( self . space , restricted_room ) ,
( self . space , restricted_accessible_room ) ,
( self . space , world_readable_room ) ,
( self . space , joined_room ) ,
] ,
)
def test_complex_space ( self ) :
"""
@ -186,7 +296,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
# Create an inaccessible room.
user2 = self . register_user ( " user2 " , " pass " )
token2 = self . login ( " user2 " , " pass " )
room2 = self . helper . create_room_as ( user2 , tok = token2 )
room2 = self . helper . create_room_as ( user2 , is_public = False , tok = token2 )
# This is a bit odd as "user" is adding a room they don't know about, but
# it works for the tests.
self . _add_child ( self . space , room2 , self . token )
@ -292,16 +402,60 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
subspace = " #subspace: " + fed_hostname
# Create a few rooms which will have different properties.
public_room = " #public: " + fed_hostname
knock_room = " #knock: " + fed_hostname
not_invited_room = " #not_invited: " + fed_hostname
invited_room = " #invited: " + fed_hostname
restricted_room = " #restricted: " + fed_hostname
restricted_accessible_room = " #restricted_accessible: " + fed_hostname
world_readable_room = " #world_readable: " + fed_hostname
joined_room = self . helper . create_room_as ( self . user , tok = self . token )
# Poke an invite over federation into the database.
fed_handler = self . hs . get_federation_handler ( )
event = make_event_from_dict (
{
" room_id " : invited_room ,
" event_id " : " !abcd: " + fed_hostname ,
" type " : EventTypes . Member ,
" sender " : " @remote: " + fed_hostname ,
" state_key " : self . user ,
" content " : { " membership " : Membership . INVITE } ,
" prev_events " : [ ] ,
" auth_events " : [ ] ,
" depth " : 1 ,
" origin_server_ts " : 1234 ,
}
)
self . get_success (
fed_handler . on_invite_request ( fed_hostname , event , RoomVersions . V6 )
)
async def summarize_remote_room (
_self , room , suggested_only , max_children , exclude_rooms
) :
# Note that these entries are brief, but should contain enough info.
rooms = [
{
" room_id " : public_room ,
" world_readable " : False ,
" join_rules " : JoinRules . PUBLIC ,
} ,
{
" room_id " : knock_room ,
" world_readable " : False ,
" join_rules " : JoinRules . KNOCK ,
} ,
{
" room_id " : not_invited_room ,
" world_readable " : False ,
" join_rules " : JoinRules . INVITE ,
} ,
{
" room_id " : invited_room ,
" world_readable " : False ,
" join_rules " : JoinRules . INVITE ,
} ,
{
" room_id " : restricted_room ,
" world_readable " : False ,
@ -364,6 +518,9 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
self . space ,
self . room ,
subspace ,
public_room ,
knock_room ,
invited_room ,
restricted_accessible_room ,
world_readable_room ,
joined_room ,
@ -374,6 +531,10 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
[
( self . space , self . room ) ,
( self . space , subspace ) ,
( subspace , public_room ) ,
( subspace , knock_room ) ,
( subspace , not_invited_room ) ,
( subspace , invited_room ) ,
( subspace , restricted_room ) ,
( subspace , restricted_accessible_room ) ,
( subspace , world_readable_room ) ,