async def test_timeline_event_callback_group(alice: Client, room: Room): cb_group = CallbackGroupTest() alice.rooms.callback_groups.append(cb_group) text = Text("This is a test") emote = Emote("tests") await room.timeline.send(text, local_echo_to=[]) await room.timeline.send(emote, local_echo_to=[]) # We parse a corresponding timeline event on sync for new states await room.state.send(CanonicalAlias()) await alice.sync.once() expected = [room, text, room, emote, room, CanonicalAlias()] assert cb_group.timeline_result == expected
async def test_settings_properties(room: Room): state = room.state base_levels = PowerLevels(users={room.client.user_id: 100}) assert state.creator == room.client.user_id assert state.federated is True assert state.version == state[Creation].content.version assert state.predecessor is None assert state.encryption is None assert state.name is None assert state.topic is None assert state.avatar is None assert state.alias is None assert state.alt_aliases == [] assert state.join_rule is JoinRules.Rule.public assert state.history_visibility is HistoryVisibility.Visibility.shared assert state.guest_access is GuestAccess.Access.forbidden assert state.pinned_events == [] assert state.tombstone is None assert state.power_levels == base_levels assert state.server_acl == ServerACL(allow=["*"]) alias = RoomAlias(f"#{uuid4()}:localhost") alt_alias = RoomAlias(f"#{uuid4()}:localhost") to_send = [ Encryption(), Name("example"), Topic("blah"), Avatar(URL("mxc://exam.ple/1")), CanonicalAlias(alias, [alt_alias]), JoinRules(JoinRules.Rule.private), HistoryVisibility(HistoryVisibility.Visibility.invited), GuestAccess(GuestAccess.Access.can_join), PinnedEvents(["$a:localhost"]), # type: ignore base_levels.but(messages_default=-1), ServerACL(allow_ip_literals=False, allow=["*"]), ] await asyncio.gather(*[room.create_alias(a) for a in (alias, alt_alias)]) await asyncio.gather(*[state.send(c) for c in to_send]) await state.send(Tombstone("dead", RoomId("!n:localhost"))) await room.client.sync.once() assert state.encryption == Encryption() assert state.name == "example" assert state.topic == "blah" assert state.avatar == URL("mxc://exam.ple/1") assert state.alias == alias assert state.alt_aliases == [alt_alias] assert state.join_rule is JoinRules.Rule.private visib = HistoryVisibility.Visibility.invited # type: ignore assert state.history_visibility is visib assert state.guest_access is GuestAccess.Access.can_join assert state.pinned_events == ["$a:localhost"] assert state.tombstone == Tombstone("dead", "!n:localhost") assert state.power_levels == base_levels.but(messages_default=-1) assert state.server_acl == ServerACL(allow_ip_literals=False, allow=["*"])
async def test_state_event_content_callback(alice: Client, room: Room): got = [] cb = lambda room, event: got.extend([room, type(event.content)]) # noqa alice.rooms.callbacks[StateEvent[Name]].append(cb) await room.state.send(Name("Test room")) await room.state.send(Topic("Not the right content type")) await room.timeline.send(CanonicalAlias()) await alice.sync.once() assert got == [room, Name]
async def test_timeline_event_callback(alice: Client, room: Room): got = [] cb = lambda r, e: got.extend([r, type(e.content)]) # noqa alice.rooms.callbacks[TimelineEvent].append(cb) await room.timeline.send(Text("This is a test"), local_echo_to=[]) await room.timeline.send(Emote("tests"), local_echo_to=[]) # We parse a corresponding timeline event on sync for new states await room.state.send(CanonicalAlias()) await alice.sync.once() assert got == [room, Text, room, Emote, room, CanonicalAlias]
async def test_state_event_content_callback_group(alice: Client, room: Room): cb_group = CallbackGroupTest() alice.rooms.callback_groups.append(cb_group) name = Name("Test Room 1000") await room.state.send(name) await room.state.send(Topic("Certainly not a test")) await room.timeline.send(CanonicalAlias()) await alice.sync.once() assert cb_group.state_content_result == [room, name]
async def test_async_and_state_event_callback_group(alice: Client, room: Room): cb_group = CallbackGroupTest() alice.rooms.callback_groups.append(cb_group) topic = Topic("This is not a test") name = Name("Test Room 1000") await room.state.send(name) await room.state.send(topic) await room.timeline.send(CanonicalAlias()) await alice.sync.once() assert cb_group.async_state_result == [room, name, room, topic]
async def test_join_room_alias(room: Room, bob: Client): assert room.client.user_id != bob.user_id alias = RoomAlias(f"#{uuid4()}:localhost") await room.create_alias(alias) await room.state.send(CanonicalAlias(alias)) await bob.sync.once() assert room.id not in bob.rooms await bob.rooms.join(alias, reason="test") await bob.sync.once() assert room.id in bob.rooms assert bob.rooms[room.id].state.me.membership_reason == "test"
async def _display_name(clients: ClientFactory, filter: Optional[Filter]): # TODO: test with lazy load room fields alice = await clients.alice room_id = await alice.rooms.create(public=True) await alice.sync.once(filter=filter) room = alice.rooms[room_id] async def check_name(wanted: Union[str, Pattern]): # Don't use lazy loading, names order will be inconsistent await alice.sync.once(filter=filter) if isinstance(wanted, str): return wanted == room.state.display_name return wanted.match(room.state.display_name) # 1 member (us) assert len(room.state.users) == 1 assert room.state.display_name == "Empty Room" # 2 members bob = await clients.bob await bob.profile.set_name("Bob") await bob.rooms.join(room.id) await check_name("Bob") # 3 members carol = await clients.carol await carol.profile.set_name("Carol") await carol.rooms.join(room.id) await check_name("Bob and Carol") # 4 members dave = await clients.dave await dave.profile.set_name("Dave") await dave.rooms.join(room.id) await check_name("Bob, Carol and Dave") # 5 joined, 1 invited - more than 6 members total erin = await clients.erin await erin.profile.set_name("Erin") await erin.rooms.join(room.id) frank = await clients.frank await frank.profile.set_name("Frank") await frank.rooms.join(room.id) mallory = await clients.mallory await mallory.profile.set_name("Frank") await room.invite(mallory.user_id) fr1 = frank.user_id fr2 = mallory.user_id await check_name(f"Bob, Carol, Dave, Erin, Frank ({fr1}) and 1 more") # 4 joined, 1 invited, 1 left and display name conflict await bob.sync.once(filter=filter) await bob.rooms[room.id].leave() await check_name(f"Carol, Dave, Erin, Frank ({fr1}) and Frank ({fr2})") # 1 joined (us), 1 invited, 5 left and no more display name conflict for client in (carol, dave, erin, frank): await room.state.users[client.user_id].kick() await check_name("Frank") # 1 joined (us), 5 left, 1 banned await alice.sync.once(filter=filter) await room.state.users[mallory.user_id].ban() await check_name( re.compile(r"^Empty Room \(had @.+, @.+, @.+, @.+ and @.+\)$", )) # 1 joined (us), 6 banned (FIXME: display "and more" for empty rooms) for client in (bob, carol, dave, erin, frank): await room.state.users[client.user_id].ban() await check_name( re.compile(r"^Empty Room \(had @.+, @.+, @.+, @.+ and @.+\)$", )) # Room with an alias alias = RoomAlias(f"#{uuid4()}:localhost") await room.create_alias(alias) await room.state.send(CanonicalAlias(alias)) await check_name(alias) # Room with an explicit name await room.state.send(Name("Forest of Magic")) await check_name("Forest of Magic")
async def test_create_alias(room: Room): alias = RoomAlias(f"#{uuid4()}:localhost") await room.create_alias(alias) await room.state.send(CanonicalAlias(alias)) await room.client.sync.once() assert room.state[CanonicalAlias].content.alias == alias