diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index 71a66492e..990b084ba 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. ### Features +- Add a `Client::joined_space_rooms` method that allows retrieving the list of joined spaces. - `Room::enable_encryption` and `Room::enable_encryption_with_state_event_encryption` will poll the encryption state for up to 3 seconds, rather than checking once after a single sync has completed. diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 0337ea01b..635f75f9e 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -1234,6 +1234,15 @@ impl Client { self.rooms_filtered(RoomStateFilter::LEFT) } + /// Returns the joined space rooms this client knows about. + pub fn joined_space_rooms(&self) -> Vec { + self.base_client() + .rooms_filtered(RoomStateFilter::JOINED) + .into_iter() + .flat_map(|room| room.is_space().then_some(Room::new(self.clone(), room))) + .collect() + } + /// Get a room with the given room id. /// /// # Arguments diff --git a/crates/matrix-sdk/tests/integration/client.rs b/crates/matrix-sdk/tests/integration/client.rs index 9af4e41a0..1eb427333 100644 --- a/crates/matrix-sdk/tests/integration/client.rs +++ b/crates/matrix-sdk/tests/integration/client.rs @@ -284,6 +284,7 @@ async fn test_invited_rooms() { assert!(client.joined_rooms().is_empty()); assert!(client.left_rooms().is_empty()); assert!(!client.invited_rooms().is_empty()); + assert!(client.joined_space_rooms().is_empty()); let room = client.get_room(room_id!("!696r7674:example.com")).unwrap(); assert_eq!(room.state(), RoomState::Invited); @@ -300,11 +301,31 @@ async fn test_left_rooms() { assert!(client.joined_rooms().is_empty()); assert!(!client.left_rooms().is_empty()); assert!(client.invited_rooms().is_empty()); + assert!(client.joined_space_rooms().is_empty()); let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap(); assert_eq!(room.state(), RoomState::Left); } +#[async_test] +async fn test_joined_space_rooms() { + let (client, server) = logged_in_client_with_server().await; + + mock_sync(&server, &*test_json::JOIN_SPACE_SYNC, None).await; + + let _response = client.sync_once(SyncSettings::default()).await.unwrap(); + + assert!(!client.joined_rooms().is_empty()); + assert!(!client.joined_space_rooms().is_empty()); + + assert!(client.left_rooms().is_empty()); + assert!(client.invited_rooms().is_empty()); + + let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap(); + assert_eq!(room.state(), RoomState::Joined); + assert!(room.is_space()); +} + #[async_test] async fn test_whoami() { let (client, server) = logged_in_client_with_server().await; diff --git a/testing/matrix-sdk-test/src/test_json/mod.rs b/testing/matrix-sdk-test/src/test_json/mod.rs index 8843cd4b4..dfe30ad7a 100644 --- a/testing/matrix-sdk-test/src/test_json/mod.rs +++ b/testing/matrix-sdk-test/src/test_json/mod.rs @@ -25,8 +25,8 @@ pub use api_responses::{ }; pub use members::MEMBERS; pub use sync::{ - DEFAULT_SYNC_SUMMARY, INVITE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC, MORE_SYNC_2, SYNC, - VOIP_SYNC, + DEFAULT_SYNC_SUMMARY, INVITE_SYNC, JOIN_SPACE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC, + MORE_SYNC_2, SYNC, VOIP_SYNC, }; pub use sync_events::{ ALIAS, ALIASES, ENCRYPTION, MEMBER, MEMBER_ADDITIONAL, MEMBER_BAN, MEMBER_INVITE, MEMBER_LEAVE, diff --git a/testing/matrix-sdk-test/src/test_json/sync.rs b/testing/matrix-sdk-test/src/test_json/sync.rs index e9d9648fa..312b2962b 100644 --- a/testing/matrix-sdk-test/src/test_json/sync.rs +++ b/testing/matrix-sdk-test/src/test_json/sync.rs @@ -1231,6 +1231,268 @@ pub static LEAVE_SYNC_EVENT: Lazy = Lazy::new(|| { }) }); +pub static JOIN_SPACE_SYNC: Lazy = Lazy::new(|| { + json!({ + "device_one_time_keys_count": {}, + "next_batch": "s526_47314_0_7_1_1_1_11444_1", + "device_lists": { + "changed": [ + "@example:example.org" + ], + "left": [] + }, + "account_data": { + "events": [ + { + "content": { + "ignored_users": { + "@someone:example.org": {} + } + }, + "type": "m.ignored_user_list" + } + ] + }, + "rooms": { + "invite": {}, + "join": { + *DEFAULT_TEST_ROOM_ID: { + "summary": {}, + "account_data": { + "events": [ + { + "content": { + "event_id": "$someplace:example.org" + }, + "room_id": "!roomid:room.com", + "type": "m.fully_read" + } + ] + }, + "ephemeral": { + "events": [ + { + "content": { + "$151680659217152dPKjd:localhost": { + "m.read": { + "@example:localhost": { + "ts": 151680989 + } + } + } + }, + "room_id": *DEFAULT_TEST_ROOM_ID, + "type": "m.receipt" + }, + ] + }, + "state": { + "events": [ + { + "content": { + "join_rule": "public" + }, + "event_id": "$15139375514WsgmR:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.join_rules", + "unsigned": { + "age": 7034220 + } + }, + { + "content": { + "avatar_url": null, + "displayname": "example", + "membership": "join" + }, + "event_id": "$151800140517rfvjc:localhost", + "membership": "join", + "origin_server_ts": 151800140000000_u64, + "sender": "@example:localhost", + "state_key": "@example:localhost", + "type": "m.room.member", + "unsigned": { + "age": 2970366, + "replaces_state": "$151800111315tsynI:localhost" + } + }, + { + "content": { + "history_visibility": "shared" + }, + "event_id": "$15139375515VaJEY:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.history_visibility", + "unsigned": { + "age": 7034220 + } + }, + { + "content": { + "creator": "@example:localhost", + "type": "m.space" + }, + "event_id": "$15139375510KUZHi:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.create", + "unsigned": { + "age": 703422 + } + }, + { + "content": { + "aliases": [ + "#tutorial:localhost" + ] + }, + "event_id": "$15139375516NUgtD:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "localhost", + "type": "m.room.aliases", + "unsigned": { + "age": 703422 + } + }, + { + "content": { + "topic": "room topic" + }, + "event_id": "$151957878228ssqrJ:localhost", + "origin_server_ts": 151957878000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.topic", + "unsigned": { + "age": 1392989709, + "prev_content": { + "topic": "test" + }, + "prev_sender": "@example:localhost", + "replaces_state": "$151957069225EVYKm:localhost" + } + }, + { + "content": { + "ban": 50, + "events": { + "m.room.avatar": 50, + "m.room.canonical_alias": 50, + "m.room.history_visibility": 100, + "m.room.name": 50, + "m.room.power_levels": 100 + }, + "events_default": 0, + "invite": 0, + "kick": 50, + "redact": 50, + "state_default": 50, + "users": { + "@example:localhost": 100 + }, + "users_default": 0 + }, + "event_id": "$15139375512JaHAW:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.power_levels", + "unsigned": { + "age": 703422 + } + }, + { + "content": { + "alias": "#tutorial:localhost" + }, + "event_id": "$15139375513VdeRF:localhost", + "origin_server_ts": 151393755000000_u64, + "sender": "@example:localhost", + "state_key": "", + "type": "m.room.canonical_alias", + "unsigned": { + "age": 703422 + } + }, + { + "content": { + "avatar_url": null, + "displayname": "example2", + "membership": "join" + }, + "event_id": "$152034824468gOeNB:localhost", + "membership": "join", + "origin_server_ts": 152034824000000_u64, + "sender": "@example2:localhost", + "state_key": "@example2:localhost", + "type": "m.room.member", + "unsigned": { + "age": 623527289, + "prev_content": { + "membership": "leave" + }, + "prev_sender": "@example:localhost", + "replaces_state": "$152034819067QWJxM:localhost" + } + }, + ] + }, + "timeline": { + "events": [ + { + "content": { + "body": "baba", + "format": "org.matrix.custom.html", + "formatted_body": "baba", + "msgtype": "m.text" + }, + "event_id": "$152037280074GZeOm:localhost", + "origin_server_ts": 152037280000000_u64, + "sender": "@example:localhost", + "type": "m.room.message", + "unsigned": { + "age": 598971425 + } + } + ], + "limited": true, + "prev_batch": "t392-516_47314_0_7_1_1_1_11444_1" + }, + "unread_notifications": { + "highlight_count": 0, + "notification_count": 11 + } + } + }, + "leave": {} + }, + "to_device": { + "events": [] + }, + "presence": { + "events": [ + { + "content": { + "avatar_url": "mxc://localhost/wefuiwegh8742w", + "currently_active": false, + "last_active_ago": 1, + "presence": "online", + "status_msg": "Making cupcakes" + }, + "sender": "@example:localhost", + "type": "m.presence" + } + ] + } + }) +}); + /// In the [`MIXED_SYNC`], the room id of the joined room. pub static MIXED_JOINED_ROOM_ID: Lazy<&RoomId> = Lazy::new(|| room_id!("!SVkFJHzfwvuaIEawgC:localhost"));