diff --git a/crates/core/src/account/service.rs b/crates/core/src/account/service.rs index bc42d8a..fad30a4 100644 --- a/crates/core/src/account/service.rs +++ b/crates/core/src/account/service.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use matrix::client::resources::session::Session; +use matrix::{admin::resources::user::UserService, client::resources::session::Session}; use tracing::instrument; use url::Url; use uuid::Uuid; @@ -8,7 +8,7 @@ use validator::{Validate, ValidationError}; use matrix::{ admin::resources::{ - user::{ListUsersParams, LoginAsUserDto, ThreePid, User as MatrixUser, UserCreateDto}, + user::{CreateUserBody, ListUsersQuery, LoginAsUserBody, ThreePid}, user_id::UserId, }, Client as MatrixAdminClient, @@ -118,9 +118,9 @@ impl AccountService { /// Matrix Server pub async fn is_email_available(&self, email: &str) -> Result { let user_id = UserId::new(email, self.admin.server_name()); - let exists = MatrixUser::list( + let exists = UserService::list( &self.admin, - ListUsersParams { + ListUsersQuery { user_id: Some(user_id.to_string()), ..Default::default() }, @@ -212,10 +212,10 @@ impl AccountService { Error::Unknown })?; - MatrixUser::create( + UserService::create( &self.admin, user_id.clone(), - UserCreateDto { + CreateUserBody { displayname: Some(dto.username), password: dto.password.to_string(), logout_devices: false, @@ -239,7 +239,7 @@ impl AccountService { Error::Unknown })?; - let matrix_account = MatrixUser::query_user_account(&self.admin, user_id.clone()) + let matrix_account = UserService::query_user_account(&self.admin, user_id.clone()) .await .map_err(|err| { tracing::error!(?err, "Failed to query user account"); @@ -266,7 +266,7 @@ impl AccountService { /// Creates an access token for the given user pub async fn issue_user_token(&self, user_id: UserId) -> Result { let credentials = - MatrixUser::login_as_user(&self.admin, user_id.clone(), LoginAsUserDto::default()) + UserService::login_as_user(&self.admin, user_id.clone(), LoginAsUserBody::default()) .await .map_err(|err| { tracing::error!(?err, ?user_id, "Failed to login as user"); @@ -283,7 +283,7 @@ impl AccountService { tracing::error!(?err, "Failed to get session from matrix as client"); Error::Unknown })?; - let matrix_account = MatrixUser::query_user_account(&self.admin, session.user_id.clone()) + let matrix_account = UserService::query_user_account(&self.admin, session.user_id.clone()) .await .map_err(|err| { tracing::error!(?err, "Failed to query user account"); diff --git a/crates/core/src/room/service.rs b/crates/core/src/room/service.rs index 1219732..6ba2a82 100644 --- a/crates/core/src/room/service.rs +++ b/crates/core/src/room/service.rs @@ -51,7 +51,7 @@ impl RoomService { .await { Ok(room) => Ok(Room { - room_id: room.room_id, + room_id: room.room_id.to_string(), }), Err(err) => { tracing::error!("Failed to create public room: {}", err); diff --git a/crates/matrix/src/admin/resources/room.rs b/crates/matrix/src/admin/resources/room.rs index 7bb46e2..a603f23 100644 --- a/crates/matrix/src/admin/resources/room.rs +++ b/crates/matrix/src/admin/resources/room.rs @@ -223,9 +223,7 @@ impl RoomService { /// Refer: https://matrix-org.github.io/synapse/latest/admin_api/rooms.html#list-room-api #[instrument(skip(client))] pub async fn get_all(client: &Client, query: ListRoomQuery) -> Result { - let resp = client - .get_query("/_synapse/admin/v1/rooms", &query) - .await?; + let resp = client.get_query("/_synapse/admin/v1/rooms", &query).await?; if resp.status().is_success() { return Ok(resp.json().await?); diff --git a/crates/matrix/src/admin/resources/user.rs b/crates/matrix/src/admin/resources/user.rs index c44da3b..03bd5a7 100644 --- a/crates/matrix/src/admin/resources/user.rs +++ b/crates/matrix/src/admin/resources/user.rs @@ -53,7 +53,7 @@ pub struct User { } #[derive(Debug, Serialize, Deserialize)] -pub struct UserCreateBody { +pub struct CreateUserBody { pub password: String, pub logout_devices: bool, pub displayname: Option, @@ -102,7 +102,7 @@ pub struct ListUsersResponse { } #[derive(Debug, Serialize, Deserialize)] -pub struct UserUpdateBody { +pub struct UpdateUserBody { pub password: String, pub logout_devices: bool, pub displayname: Option, @@ -174,7 +174,7 @@ impl UserService { /// /// Refer: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#create-or-modify-account #[instrument(skip(client, body))] - pub async fn create(client: &Client, user_id: UserId, body: UserCreateBody) -> Result { + pub async fn create(client: &Client, user_id: UserId, body: CreateUserBody) -> Result { let resp = client .put_json( format!("/_synapse/admin/v2/users/{user_id}", user_id = user_id), @@ -197,9 +197,7 @@ impl UserService { /// Refer: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#list-accounts #[instrument(skip(client))] pub async fn list(client: &Client, query: ListUsersQuery) -> Result { - let resp = client - .get_query("/_synapse/admin/v2/users", &query) - .await?; + let resp = client.get_query("/_synapse/admin/v2/users", &query).await?; if resp.status().is_success() { return Ok(resp.json().await?); @@ -214,7 +212,7 @@ impl UserService { /// /// Refer: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#create-or-modify-account #[instrument(skip(client))] - pub async fn update(client: &Client, user_id: UserId, body: UserUpdateBody) -> Result { + pub async fn update(client: &Client, user_id: UserId, body: UpdateUserBody) -> Result { let resp = client .put_json( format!("/_synapse/admin/v2/users/{user_id}", user_id = user_id), diff --git a/crates/matrix/src/client/resources/room.rs b/crates/matrix/src/client/resources/room.rs index c12baf7..a14a4df 100644 --- a/crates/matrix/src/client/resources/room.rs +++ b/crates/matrix/src/client/resources/room.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use ruma_common::{serde::Raw, OwnedUserId, RoomId, RoomOrAliasId}; +use ruma_common::{serde::Raw, OwnedRoomId, OwnedUserId, RoomId, RoomOrAliasId}; use ruma_events::{room::power_levels::RoomPowerLevelsEventContent, AnyInitialStateEvent}; use serde::{Deserialize, Serialize}; use tracing::instrument; @@ -86,12 +86,12 @@ pub struct RoomKickOrBanBody { #[derive(Debug, Deserialize)] pub struct CreateRoomResponse { - pub room_id: String, + pub room_id: OwnedRoomId, } #[derive(Debug, Deserialize)] pub struct JoinRoomResponse { - pub room_id: String, + pub room_id: OwnedRoomId, } #[derive(Debug, Deserialize)] diff --git a/crates/test/src/matrix/mod.rs b/crates/test/src/matrix/mod.rs index 92168cd..c4a8b79 100644 --- a/crates/test/src/matrix/mod.rs +++ b/crates/test/src/matrix/mod.rs @@ -1,3 +1,4 @@ mod room_admin; mod room_client; mod shared_token_registration; +mod util; diff --git a/crates/test/src/matrix/room_admin.rs b/crates/test/src/matrix/room_admin.rs index dd103a1..cd7bd73 100644 --- a/crates/test/src/matrix/room_admin.rs +++ b/crates/test/src/matrix/room_admin.rs @@ -1,186 +1,45 @@ -use std::str::FromStr; - -use commune::{account::service::CreateUnverifiedAccountDto, room::model::Room}; -use matrix::{ - admin::resources::room::{DeleteBody, ListBody, ListResponse, RoomService as AdminRoomService}, - ruma_common::{OwnedRoomId, OwnedUserId}, - Client, +use matrix::admin::resources::room::{ + ListRoomQuery, ListRoomResponse, RoomService as AdminRoomService, }; -use commune::{room::service::CreateRoomDto, util::secret::Secret}; - -use crate::tools::environment::Environment; - -struct Sample { - id: String, - user_id: OwnedUserId, - room_id: OwnedRoomId, -} - -async fn create_accounts( - env: &Environment, - amount: usize, - seed: u64, -) -> Vec<(String, (OwnedUserId, String))> { - let mut result = Vec::with_capacity(amount); - - for i in 0..amount { - let id = format!("{seed}-{i}"); - - let account_dto = CreateUnverifiedAccountDto { - username: format!("{id}-username"), - password: Secret::new("verysecure".to_owned()), - email: format!("{id}-email@matrix.org"), - }; - - let account = env - .commune - .account - .register_unverified(account_dto) - .await - .unwrap(); - let access_token = env - .commune - .account - .issue_user_token(account.user_id.clone()) - .await - .unwrap(); - - let user_id = OwnedUserId::from_str(&account.user_id.to_string()).unwrap(); - result.push((id, (user_id, access_token))); - } - - result -} - -async fn create_rooms(env: &Environment, accounts: &[(String, String)]) -> Vec { - let mut result = Vec::with_capacity(accounts.len()); - - for (id, access_token) in accounts { - let room_dto = CreateRoomDto { - name: format!("{id}-room-name"), - topic: format!("{id}-room-topic"), - alias: format!("{id}-room-alias"), - }; - let Room { room_id } = env - .commune - .room - .create_public_room(&Secret::new(access_token.clone()), room_dto) - .await - .unwrap(); - - result.push(OwnedRoomId::from_str(&room_id).unwrap()); - } - - result -} - -async fn remove_rooms(client: &Client) { - let ListResponse { rooms, .. } = AdminRoomService::get_all(client, ListBody::default()) - .await - .unwrap(); - let room_names: Vec<_> = rooms - .iter() - .map(|r| r.name.clone().unwrap_or(r.room_id.to_string())) - .collect(); - - tracing::info!(?room_names, "purging all rooms!"); - - for room in rooms { - AdminRoomService::delete_room( - client, - room.room_id.as_ref(), - DeleteBody { - new_room: None, - block: true, - purge: true, - }, - ) - .await - .unwrap(); - } -} - #[cfg(test)] mod tests { - use std::sync::Once; - use matrix::{ - admin::resources::room::{MessagesBody, OrderBy}, + admin::resources::room::{MessagesQuery, OrderBy}, ruma_common::{RoomId, ServerName}, - ruma_events::AnyStateEvent, }; - use rand::Rng; use tokio::sync::OnceCell; - use super::*; + use crate::matrix::util::{self, Test}; - pub struct Test { - env: Environment, - samples: Vec, - // seed: u64, - } + use super::*; - static TRACING: Once = Once::new(); static TEST: OnceCell = OnceCell::const_new(); - async fn init() -> Test { - TRACING.call_once(|| { - let _ = tracing_subscriber::fmt::try_init(); - }); - - let mut env = Environment::new().await; - let seed = rand::thread_rng().gen(); - - env.client - .set_token(env.config.synapse_admin_token.clone()) - .unwrap(); - remove_rooms(&env.client).await; - - let accounts = create_accounts(&env, 4, seed).await; - let rooms = create_rooms( - &env, - accounts - .iter() - .map(|(id, (_, access_token))| (id.clone(), access_token.clone())) - .collect::>() - .as_slice(), - ) - .await; - let samples = accounts - .into_iter() - .zip(rooms.into_iter()) - .map(|((id, (user_id, _)), room_id)| Sample { - id, - user_id, - room_id, - }) - .collect(); - - Test { env, samples } - } - #[tokio::test] async fn get_all_rooms() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + samples, + server_name, + client, + } = TEST.get_or_init(util::init).await; - let ListResponse { rooms: resp, .. } = - AdminRoomService::get_all(&env.client, ListBody::default()) + let ListRoomResponse { rooms: resp, .. } = + AdminRoomService::get_all(client, ListRoomQuery::default()) .await .unwrap(); assert_eq!( samples .iter() - .map(|s| Some(format!("{id}-room-name", id = &s.id))) + .map(|s| Some(format!("{id}-room-name", id = s.user_id.localpart()))) .collect::>(), resp.iter().map(|r| r.name.clone()).collect::>(), ); assert_eq!( samples .iter() - .map(|s| format!("#{id}-room-alias:{host}", id = &s.id)) + .map(|s| format!("#{id}-room-alias:{server_name}", id = s.user_id.localpart())) .collect::>(), resp.iter() .map(|r| r.canonical_alias.clone().unwrap()) @@ -191,9 +50,9 @@ mod tests { resp.iter().map(|r| &r.room_id).collect::>(), ); - let ListResponse { rooms: resp, .. } = AdminRoomService::get_all( - &env.client, - ListBody { + let ListRoomResponse { rooms: resp, .. } = AdminRoomService::get_all( + client, + ListRoomQuery { order_by: OrderBy::Creator, ..Default::default() }, @@ -215,11 +74,11 @@ mod tests { #[tokio::test] #[should_panic] async fn get_all_rooms_err() { - let Test { env, .. } = TEST.get_or_init(init).await; + let Test { client, .. } = TEST.get_or_init(util::init).await; let _ = AdminRoomService::get_all( - &env.client, - ListBody { + client, + ListRoomQuery { from: Some(u64::MAX), ..Default::default() }, @@ -230,26 +89,37 @@ mod tests { #[tokio::test] async fn get_room_details() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + samples, + server_name, + client, + } = TEST.get_or_init(util::init).await; let magic_number = Box::into_raw(Box::new(12345)) as usize % samples.len(); let rand = samples.get(magic_number).unwrap(); - let resp = AdminRoomService::get_one(&env.client, &rand.room_id) + let resp = AdminRoomService::get_one(client, &rand.room_id) .await .unwrap(); - assert_eq!(Some(format!("{}-room-name", rand.id)), resp.name); assert_eq!( - Some(format!("#{}-room-alias:{host}", rand.id)), + Some(format!("{}-room-name", rand.user_id.localpart())), + resp.name + ); + assert_eq!( + Some(format!( + "#{}-room-alias:{server_name}", + rand.user_id.localpart() + )), resp.canonical_alias, ); + assert_eq!(Some(rand.user_id.to_string()), resp.creator); assert_eq!( - Some(format!("{}-room-topic", rand.id)), + Some(format!("{}-room-topic", rand.user_id.localpart())), resp.details.and_then(|d| d.topic), ); + assert_eq!(resp.join_rules, Some("public".into())); assert!(!resp.public); @@ -259,27 +129,34 @@ mod tests { #[tokio::test] #[should_panic] async fn get_room_details_err() { - let Test { env, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + server_name, + client, + .. + } = TEST.get_or_init(util::init).await; - let _ = - AdminRoomService::get_one(&env.client, &RoomId::new(&ServerName::parse(host).unwrap())) - .await - .unwrap(); + let _ = AdminRoomService::get_one( + client, + &RoomId::new(&ServerName::parse(server_name).unwrap()), + ) + .await + .unwrap(); } #[tokio::test] async fn get_room_events() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; let magic_number = Box::into_raw(Box::new(12345)) as usize % samples.len(); let rand = samples.get(magic_number).unwrap(); - let resp = AdminRoomService::get_room_events::( - &env.client, + let resp = AdminRoomService::get_room_events( + client, &rand.room_id, // no idea what the type is - MessagesBody { + MessagesQuery { from: "".into(), to: Default::default(), limit: Default::default(), @@ -297,13 +174,16 @@ mod tests { #[tokio::test] #[should_panic] async fn get_room_events_err() { - let Test { env, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + server_name, + client, + .. + } = TEST.get_or_init(util::init).await; - let _ = AdminRoomService::get_room_events::( - &env.client, - <&RoomId>::try_from(host).unwrap(), - MessagesBody { + let _ = AdminRoomService::get_room_events( + client, + <&RoomId>::try_from(server_name.as_str()).unwrap(), + MessagesQuery { from: "".into(), to: Default::default(), limit: Default::default(), @@ -317,12 +197,14 @@ mod tests { #[tokio::test] async fn get_state_events() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; let magic_number = Box::into_raw(Box::new(12345)) as usize % samples.len(); let rand = samples.get(magic_number).unwrap(); - let resp = AdminRoomService::get_state(&env.client, &rand.room_id) + let resp = AdminRoomService::get_state(client, &rand.room_id) .await .unwrap(); @@ -335,22 +217,28 @@ mod tests { #[tokio::test] #[should_panic] async fn get_state_events_err() { - let Test { env, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + server_name, + client, + .. + } = TEST.get_or_init(util::init).await; - let _ = AdminRoomService::get_state(&env.client, <&RoomId>::try_from(host).unwrap()) - .await - .unwrap(); + let _ = + AdminRoomService::get_state(client, <&RoomId>::try_from(server_name.as_str()).unwrap()) + .await + .unwrap(); } #[tokio::test] async fn get_members() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; let magic_number = Box::into_raw(Box::new(12345)) as usize % samples.len(); let rand = samples.get(magic_number).unwrap(); - let resp = AdminRoomService::get_members(&env.client, &rand.room_id) + let resp = AdminRoomService::get_members(client, &rand.room_id) .await .unwrap(); @@ -360,11 +248,17 @@ mod tests { #[tokio::test] #[should_panic] async fn get_members_err() { - let Test { env, .. } = TEST.get_or_init(init).await; - let host = env.config.synapse_server_name.as_str(); + let Test { + server_name, + client, + .. + } = TEST.get_or_init(util::init).await; - let _ = AdminRoomService::get_members(&env.client, <&RoomId>::try_from(host).unwrap()) - .await - .unwrap(); + let _ = AdminRoomService::get_members( + client, + <&RoomId>::try_from(server_name.as_str()).unwrap(), + ) + .await + .unwrap(); } } diff --git a/crates/test/src/matrix/room_client.rs b/crates/test/src/matrix/room_client.rs index 0cd6bec..7a636fd 100644 --- a/crates/test/src/matrix/room_client.rs +++ b/crates/test/src/matrix/room_client.rs @@ -1,111 +1,7 @@ -use std::str::FromStr; - -use commune::{account::service::CreateUnverifiedAccountDto, room::model::Room}; -use matrix::{ - admin::resources::room::{DeleteBody, ListBody, ListResponse, RoomService as AdminRoomService}, - ruma_common::{OwnedRoomId, OwnedUserId}, - Client, -}; - -use commune::{room::service::CreateRoomDto, util::secret::Secret}; - -use crate::tools::environment::Environment; - -struct Sample { - id: String, - user_id: OwnedUserId, - room_id: OwnedRoomId, - access_token: String, -} - -async fn create_accounts( - env: &Environment, - amount: usize, - seed: u64, -) -> Vec<(String, (OwnedUserId, String))> { - let mut result = Vec::with_capacity(amount); - - for i in 0..amount { - let id = format!("{seed}-{i}"); - - let account_dto = CreateUnverifiedAccountDto { - username: format!("{id}-username"), - password: Secret::new("verysecure".to_owned()), - email: format!("{id}-email@matrix.org"), - }; - - let account = env - .commune - .account - .register_unverified(account_dto) - .await - .unwrap(); - let access_token = env - .commune - .account - .issue_user_token(account.user_id.clone()) - .await - .unwrap(); - - let user_id = OwnedUserId::from_str(&account.user_id.to_string()).unwrap(); - result.push((id, (user_id, access_token))); - } - - result -} - -async fn create_rooms(env: &Environment, accounts: &[(String, String)]) -> Vec { - let mut result = Vec::with_capacity(accounts.len()); - - for (id, access_token) in accounts { - let room_dto = CreateRoomDto { - name: format!("{id}-room-name"), - topic: format!("{id}-room-topic"), - alias: format!("{id}-room-alias"), - }; - - let Room { room_id } = env - .commune - .room - .create_public_room(&Secret::new(access_token.clone()), room_dto) - .await - .unwrap(); - - result.push(OwnedRoomId::from_str(&room_id).unwrap()); - } - - result -} - -async fn remove_rooms(client: &Client) { - let ListResponse { rooms, .. } = AdminRoomService::get_all(client, ListBody::default()) - .await - .unwrap(); - let room_names: Vec<_> = rooms - .iter() - .map(|r| r.name.clone().unwrap_or(r.room_id.to_string())) - .collect(); - - tracing::info!(?room_names, "purging all rooms!"); - - for room in rooms { - AdminRoomService::delete_room( - client, - room.room_id.as_ref(), - DeleteBody { - new_room: None, - block: true, - purge: true, - }, - ) - .await - .unwrap(); - } -} +use matrix::ruma_common::{OwnedRoomId, OwnedUserId}; #[cfg(test)] mod tests { - use std::sync::Once; use matrix::{ admin::resources::room::RoomService as AdminRoomService, @@ -115,69 +11,31 @@ mod tests { }, ruma_common::OwnedRoomOrAliasId, }; - use rand::Rng; use tokio::sync::OnceCell; - use super::*; + use crate::matrix::util::{self, Test}; - pub struct Test { - env: Environment, - samples: Vec, - } - - static TRACING: Once = Once::new(); + use super::*; static TEST: OnceCell = OnceCell::const_new(); - async fn init() -> Test { - TRACING.call_once(|| { - let _ = tracing_subscriber::fmt::try_init(); - }); - - let mut env = Environment::new().await; - let seed = rand::thread_rng().gen(); - - env.client - .set_token(env.config.synapse_admin_token.clone()) - .unwrap(); - remove_rooms(&env.client).await; - - let accounts = create_accounts(&env, 4, seed).await; - let rooms = create_rooms( - &env, - accounts - .iter() - .map(|(id, (_, access_token))| (id.clone(), access_token.clone())) - .collect::>() - .as_slice(), - ) - .await; - let samples = accounts - .into_iter() - .zip(rooms.into_iter()) - .map(|((id, (user_id, access_token)), room_id)| Sample { - id, - user_id, - room_id, - access_token, - }) - .collect(); - - Test { env, samples } - } - async fn join_helper() -> Vec<( OwnedRoomId, Vec, Vec>, )> { - let Test { env, samples, .. } = TEST.get_or_init(init).await; + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; let mut result = Vec::with_capacity(samples.len()); for sample in samples { - let client = env.client.clone(); + let client = client.clone(); - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); let mut resps = Vec::with_capacity(guests.len()); for guest in guests.iter() { @@ -206,10 +64,7 @@ mod tests { #[tokio::test] async fn join_all_rooms() { - let Test { env, .. } = TEST.get_or_init(init).await; - - let mut admin = env.client.clone(); - admin.set_token(&env.config.synapse_admin_token).unwrap(); + let Test { client: admin, .. } = TEST.get_or_init(util::init).await; // first join let result = join_helper().await; @@ -236,17 +91,21 @@ mod tests { #[tokio::test] async fn leave_all_rooms() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; - let mut admin = env.client.clone(); - admin.set_token(&env.config.synapse_admin_token).unwrap(); + let admin = client.clone(); let mut result = Vec::with_capacity(samples.len()); for sample in samples { - let client = env.client.clone(); + let client = client.clone(); - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); for guest in guests { let client = client.clone(); @@ -284,15 +143,17 @@ mod tests { #[tokio::test] async fn forget_all_rooms() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; - - let mut admin = env.client.clone(); - admin.set_token(&env.config.synapse_admin_token).unwrap(); + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; for sample in samples { - let client = env.client.clone(); + let client = client.clone(); - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); for guest in guests { let client = client.clone(); @@ -309,6 +170,7 @@ mod tests { } // check whether all guests are still not present anymore the room + let admin = client.clone(); for sample in samples { let room_id = &sample.room_id; @@ -329,7 +191,7 @@ mod tests { // confirm a room can't be forgotten if we didn't leave first for sample in samples { - let client = env.client.clone(); + let client = client.clone(); let room_id = &sample.room_id; let resp = RoomService::forget( @@ -346,10 +208,9 @@ mod tests { #[tokio::test] async fn kick_all_guests() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; - - let mut admin = env.client.clone(); - admin.set_token(&env.config.synapse_admin_token).unwrap(); + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; // second join let result = join_helper().await; @@ -357,6 +218,7 @@ mod tests { tracing::info!(?rooms, "joining all guests"); // check whether all guests are in the room and joined the expected room + let admin = client.clone(); for (room_id, guests, resps) in result.iter() { let mut resp = AdminRoomService::get_members(&admin, room_id) .await @@ -374,10 +236,13 @@ mod tests { } for sample in samples { - let client = env.client.clone(); + let client = client.clone(); let room_id = &sample.room_id; - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); for guest in guests { let client = client.clone(); @@ -416,10 +281,9 @@ mod tests { #[tokio::test] async fn ban_all_guests() { - let Test { env, samples, .. } = TEST.get_or_init(init).await; - - let mut admin = env.client.clone(); - admin.set_token(&env.config.synapse_admin_token).unwrap(); + let Test { + samples, client, .. + } = TEST.get_or_init(util::init).await; // third join let result = join_helper().await; @@ -427,6 +291,7 @@ mod tests { tracing::info!(?rooms, "joining all guests"); // check whether all guests are in the room and joined the expected room + let admin = client.clone(); for (room_id, guests, resps) in result.iter() { let mut resp = AdminRoomService::get_members(&admin, room_id) .await @@ -444,9 +309,12 @@ mod tests { } for sample in samples { - let client = env.client.clone(); + let client = client.clone(); - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); for guest in guests { let client = client.clone(); @@ -492,9 +360,12 @@ mod tests { } for sample in samples { - let client = env.client.clone(); + let client = client.clone(); - let guests: Vec<_> = samples.iter().filter(|g| g.id != sample.id).collect(); + let guests: Vec<_> = samples + .iter() + .filter(|g| g.user_id != sample.user_id) + .collect(); for guest in guests { let client = client.clone(); diff --git a/crates/test/src/matrix/util.rs b/crates/test/src/matrix/util.rs new file mode 100644 index 0000000..b7609dd --- /dev/null +++ b/crates/test/src/matrix/util.rs @@ -0,0 +1,166 @@ +use std::str::FromStr; + +use matrix::{ + admin::resources::{ + room::{DeleteQuery, ListRoomQuery, ListRoomResponse, RoomService as AdminRoomService}, + user::{ + CreateUserBody, LoginAsUserBody, LoginAsUserResponse, UserService as AdminUserService, + }, + user_id::UserId, + }, + client::resources::room::{CreateRoomBody, Room, RoomPreset}, + ruma_common::{OwnedRoomId, OwnedUserId}, + Client, +}; + +use rand::Rng; + +use crate::tools::environment::Environment; + +pub struct Test { + pub samples: Vec, + pub server_name: String, + pub client: Client, +} + +pub struct Sample { + pub user_id: OwnedUserId, + pub room_id: OwnedRoomId, + pub access_token: String, +} + +async fn create_accounts( + client: &Client, + server_name: String, + amount: usize, + seed: u64, +) -> Vec<(OwnedUserId, String)> { + let mut result = Vec::with_capacity(amount); + + for i in 0..amount { + let user_id = UserId::new(format!("{seed}-{i}"), server_name.clone()); + let password = "verysecure".to_owned(); + + let body = CreateUserBody { + password, + logout_devices: false, + displayname: None, + avatar_url: None, + threepids: vec![], + external_ids: vec![], + admin: false, + deactivated: false, + user_type: None, + locked: false, + }; + AdminUserService::create(&client, user_id.clone(), body) + .await + .unwrap(); + + let body = LoginAsUserBody::default(); + let LoginAsUserResponse { access_token } = + AdminUserService::login_as_user(&client, user_id.clone(), body) + .await + .unwrap(); + + let user_id = OwnedUserId::from_str(&user_id.to_string()).unwrap(); + result.push((user_id, access_token)); + } + + result +} + +async fn create_rooms(client: &Client, accounts: &[(OwnedUserId, String)]) -> Vec { + let mut result = Vec::with_capacity(accounts.len()); + + for (user_id, access_token) in accounts { + let id = user_id.localpart(); + let preset = Some(RoomPreset::PublicChat); + + let name = format!("{id}-room-name"); + let topic = format!("{id}-room-topic"); + let room_alias_name = format!("{id}-room-alias"); + + let body = CreateRoomBody { + name, + topic, + room_alias_name, + preset, + ..Default::default() + }; + let resp = Room::create(client, access_token, body).await.unwrap(); + + result.push(resp.room_id); + } + + result +} + +async fn remove_rooms(client: &Client) { + let ListRoomResponse { rooms, .. } = + AdminRoomService::get_all(client, ListRoomQuery::default()) + .await + .unwrap(); + let room_names: Vec<_> = rooms + .iter() + .map(|r| r.name.clone().unwrap_or(r.room_id.to_string())) + .collect(); + + tracing::info!(?room_names, "purging all rooms!"); + + for room in rooms { + AdminRoomService::delete_room( + client, + room.room_id.as_ref(), + DeleteQuery { + new_room: None, + block: true, + purge: true, + }, + ) + .await + .unwrap(); + } +} + +pub async fn init() -> Test { + let _ = tracing_subscriber::fmt::try_init(); + + let seed = rand::thread_rng().gen(); + + let env = Environment::new().await; + + let server_name = env.config.synapse_server_name.clone(); + let admin_token = env.config.synapse_admin_token.clone(); + let mut client = env.client.clone(); + + client.set_token(admin_token).unwrap(); + remove_rooms(&client).await; + + let accounts = create_accounts(&client, server_name.clone(), 4, seed).await; + let rooms = create_rooms( + &client, + accounts + .iter() + .map(|(user_id, access_token)| (user_id.clone(), access_token.clone())) + .collect::>() + .as_slice(), + ) + .await; + + let samples = accounts + .into_iter() + .zip(rooms.into_iter()) + .map(|((user_id, access_token), room_id)| Sample { + user_id, + room_id, + access_token, + }) + .collect(); + + Test { + samples, + server_name, + client, + } +}