From 66c5d5311ef3b4720ef604f31cbe55b457144543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 18 Jul 2022 12:30:44 +0200 Subject: [PATCH 1/3] test: Add methods to add events in bulk --- .../src/event_builder/invited_room.rs | 14 ++++- .../src/event_builder/joined_room.rs | 57 ++++++++++++++++++- .../src/event_builder/left_room.rs | 46 ++++++++++++++- .../matrix-sdk-test/src/event_builder/mod.rs | 18 ++++++ 4 files changed, 132 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk-test/src/event_builder/invited_room.rs b/crates/matrix-sdk-test/src/event_builder/invited_room.rs index 6c1c7238a..649dc2385 100644 --- a/crates/matrix-sdk-test/src/event_builder/invited_room.rs +++ b/crates/matrix-sdk-test/src/event_builder/invited_room.rs @@ -1,4 +1,7 @@ -use ruma::{api::client::sync::sync_events::v3::InvitedRoom, OwnedRoomId}; +use ruma::{ + api::client::sync::sync_events::v3::InvitedRoom, events::AnyStrippedStateEvent, serde::Raw, + OwnedRoomId, +}; use super::StrippedStateTestEvent; use crate::test_json; @@ -22,6 +25,15 @@ impl InvitedRoomBuilder { self.inner.invite_state.events.push(event.into_raw_event()); self } + + /// Add events to the state in bulk. + pub fn add_state_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.invite_state.events.extend(events); + self + } } impl Default for InvitedRoomBuilder { diff --git a/crates/matrix-sdk-test/src/event_builder/joined_room.rs b/crates/matrix-sdk-test/src/event_builder/joined_room.rs index 09839024f..5539243c9 100644 --- a/crates/matrix-sdk-test/src/event_builder/joined_room.rs +++ b/crates/matrix-sdk-test/src/event_builder/joined_room.rs @@ -1,4 +1,11 @@ -use ruma::{api::client::sync::sync_events::v3::JoinedRoom, OwnedRoomId}; +use ruma::{ + api::client::sync::sync_events::v3::JoinedRoom, + events::{ + AnyRoomAccountDataEvent, AnySyncEphemeralRoomEvent, AnySyncRoomEvent, AnySyncStateEvent, + }, + serde::Raw, + OwnedRoomId, +}; use serde_json::{from_value as from_json_value, Value as JsonValue}; use super::{EphemeralTestEvent, RoomAccountDataTestEvent, StateTestEvent, TimelineTestEvent}; @@ -24,6 +31,27 @@ impl JoinedRoomBuilder { self } + /// Add events in bulk to the timeline. + pub fn add_timeline_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.timeline.events.extend(events); + self + } + + /// Add state events in bulk to the timeline. + /// + /// This is a convenience method that casts `Raw` to + /// `Raw` and calls `JoinedRoom::add_timeline_bulk()`. + pub fn add_timeline_state_bulk(self, events: I) -> Self + where + I: IntoIterator>, + { + let events = events.into_iter().map(|event| event.cast()); + self.add_timeline_bulk(events) + } + /// Set the timeline as limited. pub fn set_timeline_limited(mut self) -> Self { self.inner.timeline.limited = true; @@ -42,18 +70,45 @@ impl JoinedRoomBuilder { self } + /// Add events in bulk to the state. + pub fn add_state_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.state.events.extend(events); + self + } + /// Add an ephemeral event. pub fn add_ephemeral_event(mut self, event: EphemeralTestEvent) -> Self { self.inner.ephemeral.events.push(event.into_raw_event()); self } + /// Add ephemeral events in bulk. + pub fn add_ephemeral_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.ephemeral.events.extend(events); + self + } + /// Add room account data. pub fn add_account_data(mut self, event: RoomAccountDataTestEvent) -> Self { self.inner.account_data.events.push(event.into_raw_event()); self } + /// Add room account data in bulk. + pub fn add_account_data_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.account_data.events.extend(events); + self + } + /// Set the room summary. pub fn set_room_summary(mut self, summary: JsonValue) -> Self { self.inner.summary = from_json_value(summary).unwrap(); diff --git a/crates/matrix-sdk-test/src/event_builder/left_room.rs b/crates/matrix-sdk-test/src/event_builder/left_room.rs index 57710392e..13c7e4d70 100644 --- a/crates/matrix-sdk-test/src/event_builder/left_room.rs +++ b/crates/matrix-sdk-test/src/event_builder/left_room.rs @@ -1,4 +1,9 @@ -use ruma::{api::client::sync::sync_events::v3::LeftRoom, OwnedRoomId}; +use ruma::{ + api::client::sync::sync_events::v3::LeftRoom, + events::{AnyRoomAccountDataEvent, AnySyncRoomEvent, AnySyncStateEvent}, + serde::Raw, + OwnedRoomId, +}; use super::{RoomAccountDataTestEvent, StateTestEvent, TimelineTestEvent}; use crate::test_json; @@ -23,6 +28,27 @@ impl LeftRoomBuilder { self } + /// Add events in bulk to the timeline. + pub fn add_timeline_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.timeline.events.extend(events); + self + } + + /// Add state events in bulk to the timeline. + /// + /// This is a convenience method that casts `Raw` to + /// `Raw` and calls `LeftRoom::add_timeline_bulk()`. + pub fn add_timeline_state_bulk(self, events: I) -> Self + where + I: IntoIterator>, + { + let events = events.into_iter().map(|event| event.cast()); + self.add_timeline_bulk(events) + } + /// Set the timeline as limited. pub fn set_timeline_limited(mut self) -> Self { self.inner.timeline.limited = true; @@ -41,11 +67,29 @@ impl LeftRoomBuilder { self } + /// Add events in bulk to the state. + pub fn add_state_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.state.events.extend(events); + self + } + /// Add room account data. pub fn add_account_data(mut self, event: RoomAccountDataTestEvent) -> Self { self.inner.account_data.events.push(event.into_raw_event()); self } + + /// Add room account data in bulk. + pub fn add_account_data_bulk(mut self, events: I) -> Self + where + I: IntoIterator>, + { + self.inner.account_data.events.extend(events); + self + } } impl Default for LeftRoomBuilder { diff --git a/crates/matrix-sdk-test/src/event_builder/mod.rs b/crates/matrix-sdk-test/src/event_builder/mod.rs index 21fd9619a..6484d3989 100644 --- a/crates/matrix-sdk-test/src/event_builder/mod.rs +++ b/crates/matrix-sdk-test/src/event_builder/mod.rs @@ -136,6 +136,15 @@ impl EventBuilder { self } + /// Add presence in bulk. + pub fn add_presence_bulk(&mut self, events: I) -> &mut Self + where + I: IntoIterator>, + { + self.presence.extend(events); + self + } + /// Add global account data. pub fn add_global_account_data_event( &mut self, @@ -151,6 +160,15 @@ impl EventBuilder { self } + /// Add global account data in bulk. + pub fn add_global_account_data_bulk(&mut self, events: I) -> &mut Self + where + I: IntoIterator>, + { + self.account_data.extend(events); + self + } + /// Builds a sync response as a JSON Value containing the events we queued /// so far. /// From c0a7b1732499885c6f1cbee4b808471269426613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 18 Jul 2022 12:31:35 +0200 Subject: [PATCH 2/3] test: Add method to create room member events in bulk --- .../matrix-sdk-test/src/event_builder/bulk.rs | 43 +++++++++++++++++++ .../matrix-sdk-test/src/event_builder/mod.rs | 2 + crates/matrix-sdk-test/src/lib.rs | 6 +-- 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 crates/matrix-sdk-test/src/event_builder/bulk.rs diff --git a/crates/matrix-sdk-test/src/event_builder/bulk.rs b/crates/matrix-sdk-test/src/event_builder/bulk.rs new file mode 100644 index 000000000..5ddf10d56 --- /dev/null +++ b/crates/matrix-sdk-test/src/event_builder/bulk.rs @@ -0,0 +1,43 @@ +use std::ops::Range; + +use ruma::{ + events::{room::member::MembershipState, AnySyncStateEvent}, + serde::Raw, +}; +use serde_json::{from_value as from_json_value, json}; + +/// Create `m.room.member` events in the given range. +/// +/// The user IDs are generated as `@user_{idx}:{server}`, with `idx` being the +/// current value in `range`, so providing the same range in several method +/// calls will create events that replace the previous state. +/// +/// The event IDs are generated as `$roommember_{batch}_{idx}` so it's important +/// to increment `batch` between method calls to avoid having two events with +/// the same event ID. +/// +/// This method can be used as input for room builders with +/// `add_timeline_state_bulk()` or `add_state_bulk()`. +pub fn bulk_room_members<'a>( + batch: usize, + range: Range, + server: &'a str, + membership: &'a MembershipState, +) -> impl Iterator> + 'a { + range.map(move |idx| { + let user_id = format!("@user_{idx}:{server}"); + let event_id = format!("$roommember_{batch}_{idx}"); + let ts = 151800000 + batch * 100 + idx; + from_json_value(json!({ + "content": { + "membership": membership, + }, + "event_id": event_id, + "origin_server_ts": ts, + "sender": user_id, + "state_key": user_id, + "type": "m.room.member", + })) + .unwrap() + }) +} diff --git a/crates/matrix-sdk-test/src/event_builder/mod.rs b/crates/matrix-sdk-test/src/event_builder/mod.rs index 6484d3989..4af354fe2 100644 --- a/crates/matrix-sdk-test/src/event_builder/mod.rs +++ b/crates/matrix-sdk-test/src/event_builder/mod.rs @@ -16,11 +16,13 @@ use serde_json::{from_value as from_json_value, json, Value as JsonValue}; use super::test_json; +mod bulk; mod invited_room; mod joined_room; mod left_room; mod test_event; +pub use bulk::bulk_room_members; pub use invited_room::InvitedRoomBuilder; pub use joined_room::JoinedRoomBuilder; pub use left_room::LeftRoomBuilder; diff --git a/crates/matrix-sdk-test/src/lib.rs b/crates/matrix-sdk-test/src/lib.rs index cc3cb6b6c..cbef86c99 100644 --- a/crates/matrix-sdk-test/src/lib.rs +++ b/crates/matrix-sdk-test/src/lib.rs @@ -9,9 +9,9 @@ mod event_builder; pub mod test_json; pub use event_builder::{ - EphemeralTestEvent, EventBuilder, GlobalAccountDataTestEvent, InvitedRoomBuilder, - JoinedRoomBuilder, LeftRoomBuilder, PresenceTestEvent, RoomAccountDataTestEvent, - StateTestEvent, StrippedStateTestEvent, TimelineTestEvent, + bulk_room_members, EphemeralTestEvent, EventBuilder, GlobalAccountDataTestEvent, + InvitedRoomBuilder, JoinedRoomBuilder, LeftRoomBuilder, PresenceTestEvent, + RoomAccountDataTestEvent, StateTestEvent, StrippedStateTestEvent, TimelineTestEvent, }; /// Embedded sync response files From b98e3d80a0006b508043a28e8ac0c2669ecd6437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 18 Jul 2022 13:38:30 +0200 Subject: [PATCH 3/3] test(sdk): Split tests for permalinks --- .../tests/integration/room/common.rs | 400 +++++++++--------- 1 file changed, 189 insertions(+), 211 deletions(-) diff --git a/crates/matrix-sdk/tests/integration/room/common.rs b/crates/matrix-sdk/tests/integration/room/common.rs index aa8505fa8..ac855e524 100644 --- a/crates/matrix-sdk/tests/integration/room/common.rs +++ b/crates/matrix-sdk/tests/integration/room/common.rs @@ -1,13 +1,15 @@ use std::time::Duration; use matrix_sdk::{config::SyncSettings, DisplayName, RoomMember}; -use matrix_sdk_test::{async_test, test_json}; +use matrix_sdk_test::{ + async_test, bulk_room_members, test_json, EventBuilder, JoinedRoomBuilder, TimelineTestEvent, +}; use ruma::{ event_id, - events::{AnySyncStateEvent, StateEventType}, + events::{room::member::MembershipState, AnySyncStateEvent, StateEventType}, room_id, }; -use serde_json::{json, Value as JsonValue}; +use serde_json::json; use wiremock::{ matchers::{header, method, path_regex}, Mock, ResponseTemplate, @@ -361,92 +363,26 @@ async fn room_timeline() { } #[async_test] -async fn room_permalink() { - fn sync_response(index: u8, room_timeline_events: &[JsonValue]) -> JsonValue { - json!({ - "device_one_time_keys_count": {}, - "next_batch": format!("s526_47314_0_7_1_1_1_11444_{}", index + 1), - "device_lists": { - "changed": [], - "left": [] - }, - "account_data": { - "events": [] - }, - "rooms": { - "invite": {}, - "join": { - "!test_room:127.0.0.1": { - "summary": {}, - "account_data": { - "events": [] - }, - "ephemeral": { - "events": [] - }, - "state": { - "events": [] - }, - "timeline": { - "events": room_timeline_events, - "limited": false, - "prev_batch": format!("s526_47314_0_7_1_1_1_11444_{}", index - 1), - }, - "unread_notifications": { - "highlight_count": 0, - "notification_count": 0, - } - } - }, - "leave": {} - }, - "to_device": { - "events": [] - }, - "presence": { - "events": [] - } - }) - } - - fn room_member_events(nb: usize, server: &str) -> Vec { - let mut events = Vec::with_capacity(nb); - for i in 0..nb { - let id = format!("${server}{i}"); - let user = format!("@user{i}:{server}"); - events.push(json!({ - "content": { - "membership": "join", - }, - "event_id": id, - "origin_server_ts": 151800140, - "sender": user, - "state_key": user, - "type": "m.room.member", - })) - } - events - } - +async fn room_route() { let (client, server) = logged_in_client().await; + let mut ev_builder = EventBuilder::new(); + let room_id = room_id!("!test_room:127.0.0.1"); // Without elligible server - let mut sync_index = 1; - let res = sync_response( - sync_index, - &[ - json!({ + ev_builder.add_joined_room( + JoinedRoomBuilder::new(room_id) + .add_timeline_event(TimelineTestEvent::Custom(json!({ "content": { "creator": "@creator:127.0.0.1", "room_version": "6", }, "event_id": "$151957878228ekrDs", "origin_server_ts": 15195787, - "sender": "@creator:localhost", + "sender": "@creator:127.0.0.1", "state_key": "", "type": "m.room.create", - }), - json!({ + }))) + .add_timeline_event(TimelineTestEvent::Custom(json!({ "content": { "membership": "join", }, @@ -455,110 +391,79 @@ async fn room_permalink() { "sender": "@creator:127.0.0.1", "state_key": "@creator:127.0.0.1", "type": "m.room.member", - }), - ], + }))), ); - mock_sync(&server, res, None).await; - client.sync_once(SyncSettings::new()).await.unwrap(); - let room = client.get_room(room_id!("!test_room:127.0.0.1")).unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1" - ); - assert_eq!( - room.matrix_permalink(true).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?action=join" - ); + mock_sync(&server, ev_builder.build_json_sync_response(), None).await; + client.sync_once(SyncSettings::new()).await.unwrap(); + let room = client.get_room(room_id).unwrap(); + + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 0); // With a single elligible server - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ - "content": { - "membership": "join", - }, - "event_id": "$151800140517rfvjc", - "origin_server_ts": 151800140, - "sender": "@example:localhost", - "state_key": "@example:localhost", - "type": "m.room.member", - })], - ); + let mut batch = 0; + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_state_bulk( + bulk_room_members(batch, 0..1, "localhost", &MembershipState::Join), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=localhost" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=localhost" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 1); + assert_eq!(route[0], "localhost"); // With two elligible servers - sync_index += 1; - let res = sync_response(sync_index, &room_member_events(15, "notarealhs")); + batch += 1; + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_state_bulk( + bulk_room_members(batch, 0..15, "notarealhs", &MembershipState::Join), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=notarealhs&via=localhost" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=notarealhs&via=localhost" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 2); + assert_eq!(route[0], "notarealhs"); + assert_eq!(route[1], "localhost"); // With three elligible servers - sync_index += 1; - let res = sync_response(sync_index, &room_member_events(5, "mymatrix")); + batch += 1; + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_state_bulk( + bulk_room_members(batch, 0..5, "mymatrix", &MembershipState::Join), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=notarealhs&via=mymatrix&via=localhost" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=notarealhs&via=mymatrix&via=localhost" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 3); + assert_eq!(route[0], "notarealhs"); + assert_eq!(route[1], "mymatrix"); + assert_eq!(route[2], "localhost"); // With four elligible servers - sync_index += 1; - let res = sync_response(sync_index, &room_member_events(10, "yourmatrix")); + batch += 1; + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_state_bulk( + bulk_room_members(batch, 0..10, "yourmatrix", &MembershipState::Join), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=notarealhs&via=yourmatrix&via=mymatrix" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=notarealhs&via=yourmatrix&via=mymatrix" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 3); + assert_eq!(route[0], "notarealhs"); + assert_eq!(route[1], "yourmatrix"); + assert_eq!(route[2], "mymatrix"); // With power levels - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ "content": { "users": { - "@example:localhost": 50, + "@user_0:localhost": 50, }, }, "event_id": "$15139375512JaHAW", @@ -566,30 +471,25 @@ async fn room_permalink() { "sender": "@creator:127.0.0.1", "state_key": "", "type": "m.room.power_levels", - })], - ); + })), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=localhost&via=notarealhs&via=yourmatrix" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=localhost&via=notarealhs&via=yourmatrix" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 3); + assert_eq!(route[0], "localhost"); + assert_eq!(route[1], "notarealhs"); + assert_eq!(route[2], "yourmatrix"); // With higher power levels - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ "content": { "users": { - "@example:localhost": 50, - "@user0:mymatrix": 70, + "@user_0:localhost": 50, + "@user_2:mymatrix": 70, }, }, "event_id": "$15139375512JaHAZ", @@ -597,26 +497,21 @@ async fn room_permalink() { "sender": "@creator:127.0.0.1", "state_key": "", "type": "m.room.power_levels", - })], - ); + })), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); - assert_eq!( - room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=mymatrix&via=notarealhs&via=yourmatrix" - ); - assert_eq!( - room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=mymatrix&via=notarealhs&via=yourmatrix" - ); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 3); + assert_eq!(route[0], "mymatrix"); + assert_eq!(route[1], "notarealhs"); + assert_eq!(route[2], "yourmatrix"); // With server ACLs - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ "content": { "allow": ["*"], "allow_ip_literals": true, @@ -627,38 +522,69 @@ async fn room_permalink() { "sender": "@creator:127.0.0.1", "state_key": "", "type": "m.room.server_acl", - })], - ); + })), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); + let route = room.route().await.unwrap(); + assert_eq!(route.len(), 3); + assert_eq!(route[0], "mymatrix"); + assert_eq!(route[1], "yourmatrix"); + assert_eq!(route[2], "localhost"); +} + +#[async_test] +async fn room_permalink() { + let (client, server) = logged_in_client().await; + let mut ev_builder = EventBuilder::new(); + let room_id = room_id!("!test_room:127.0.0.1"); + + // Without aliases + ev_builder.add_joined_room( + JoinedRoomBuilder::new(room_id) + .add_timeline_state_bulk(bulk_room_members( + 0, + 0..1, + "localhost", + &MembershipState::Join, + )) + .add_timeline_state_bulk(bulk_room_members( + 1, + 0..5, + "notarealhs", + &MembershipState::Join, + )), + ); + mock_sync(&server, ev_builder.build_json_sync_response(), None).await; + client.sync_once(SyncSettings::new()).await.unwrap(); + let room = client.get_room(room_id).unwrap(); + assert_eq!( room.matrix_to_permalink().await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1?via=mymatrix&via=yourmatrix&via=localhost" + "https://matrix.to/#/%21test_room%3A127.0.0.1?via=notarealhs&via=localhost" ); assert_eq!( room.matrix_permalink(false).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1?via=mymatrix&via=yourmatrix&via=localhost" + "matrix:roomid/test_room:127.0.0.1?via=notarealhs&via=localhost" ); // With an alternative alias - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ "content": { "alt_aliases": ["#alias:localhost"], }, "event_id": "$15139375513VdeRF", "origin_server_ts": 151393755, - "sender": "@example:localhost", + "sender": "@user_0:localhost", "state_key": "", "type": "m.room.canonical_alias", - })], - ); + })), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); assert_eq!( @@ -668,23 +594,21 @@ async fn room_permalink() { assert_eq!(room.matrix_permalink(false).await.unwrap().to_string(), "matrix:r/alias:localhost"); // With a canonical alias - sync_index += 1; - let res = sync_response( - sync_index, - &[json!({ + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ "content": { "alias": "#canonical:localhost", "alt_aliases": ["#alias:localhost"], }, "event_id": "$15139375513VdeRF", "origin_server_ts": 151393755, - "sender": "@example:localhost", + "sender": "@user_0:localhost", "state_key": "", "type": "m.room.canonical_alias", - })], - ); + })), + )); let sync_token = client.sync_token().await.unwrap(); - mock_sync(&server, res, Some(sync_token.clone())).await; + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); assert_eq!( @@ -699,14 +623,68 @@ async fn room_permalink() { room.matrix_permalink(true).await.unwrap().to_string(), "matrix:r/canonical:localhost?action=join" ); +} +#[async_test] +async fn room_event_permalink() { + let (client, server) = logged_in_client().await; + let mut ev_builder = EventBuilder::new(); + let room_id = room_id!("!test_room:127.0.0.1"); let event_id = event_id!("$15139375512JaHAW"); + + // Without aliases + ev_builder.add_joined_room( + JoinedRoomBuilder::new(room_id) + .add_timeline_state_bulk(bulk_room_members( + 0, + 0..1, + "localhost", + &MembershipState::Join, + )) + .add_timeline_state_bulk(bulk_room_members( + 1, + 0..5, + "notarealhs", + &MembershipState::Join, + )), + ); + mock_sync(&server, ev_builder.build_json_sync_response(), None).await; + client.sync_once(SyncSettings::new()).await.unwrap(); + let room = client.get_room(room_id).unwrap(); + assert_eq!( room.matrix_to_event_permalink(event_id).await.unwrap().to_string(), - "https://matrix.to/#/%21test_room%3A127.0.0.1/%2415139375512JaHAW?via=mymatrix&via=yourmatrix&via=localhost" + "https://matrix.to/#/%21test_room%3A127.0.0.1/%2415139375512JaHAW?via=notarealhs&via=localhost" ); assert_eq!( room.matrix_event_permalink(event_id).await.unwrap().to_string(), - "matrix:roomid/test_room:127.0.0.1/e/15139375512JaHAW?via=mymatrix&via=yourmatrix&via=localhost" + "matrix:roomid/test_room:127.0.0.1/e/15139375512JaHAW?via=notarealhs&via=localhost" + ); + + // Adding an alias doesn't change anything + ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event( + TimelineTestEvent::Custom(json!({ + "content": { + "alias": "#canonical:localhost", + "alt_aliases": ["#alias:localhost"], + }, + "event_id": "$15139375513VdeRF", + "origin_server_ts": 151393755, + "sender": "@user_0:localhost", + "state_key": "", + "type": "m.room.canonical_alias", + })), + )); + let sync_token = client.sync_token().await.unwrap(); + mock_sync(&server, ev_builder.build_json_sync_response(), Some(sync_token.clone())).await; + client.sync_once(SyncSettings::new().token(sync_token)).await.unwrap(); + + assert_eq!( + room.matrix_to_event_permalink(event_id).await.unwrap().to_string(), + "https://matrix.to/#/%21test_room%3A127.0.0.1/%2415139375512JaHAW?via=notarealhs&via=localhost" + ); + assert_eq!( + room.matrix_event_permalink(event_id).await.unwrap().to_string(), + "matrix:roomid/test_room:127.0.0.1/e/15139375512JaHAW?via=notarealhs&via=localhost" ); }