From 537c147c4b46de772287e92b534a39711b29fefd Mon Sep 17 00:00:00 2001 From: phazeschift <51278042+phazeschift@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:52:02 -0700 Subject: [PATCH 1/3] test: Add tests for invite/fetch Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> --- .../delta/src/routes/invites/invite_fetch.rs | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/crates/delta/src/routes/invites/invite_fetch.rs b/crates/delta/src/routes/invites/invite_fetch.rs index a56c30bb..9fcfd6b5 100644 --- a/crates/delta/src/routes/invites/invite_fetch.rs +++ b/crates/delta/src/routes/invites/invite_fetch.rs @@ -76,3 +76,188 @@ pub async fn fetch(db: &State, target: Reference) -> Result code, + _ => unreachable!(), + }; + let response = harness + .client + .get(format!("/invites/{}", invite_code)) + .dispatch() + .await; + assert_eq!(response.status(), Status::Ok); + let invite_response: InviteResponse = response.into_json().await.expect("`FetchInvite`"); + match invite_response { + InviteResponse::Group { + code, + channel_id, + user_name, + .. + } => { + assert_eq!(code, invite_code); + assert_eq!(channel_id, group.id()); + assert_eq!(user_name, user.username); + } + _ => unreachable!(), + } + } + + #[rocket::async_test] + async fn fail_fetch_missing_invite() { + let harness = TestHarness::new().await; + let response = harness + .client + .get(format!("/invites/{}", TestHarness::rand_string())) + .dispatch() + .await; + assert_eq!(response.status(), Status::NotFound); + } + + #[rocket::async_test] + async fn success_fetch_text_channel_invite() { + let harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + let (_, channels) = Server::create( + &harness.db, + DataCreateServer { + name: "Test Server".to_string(), + ..Default::default() + }, + &user, + true, + ) + .await + .expect("Failed to create test server"); + + let channel = channels.first().expect("Server Channel"); + let create_response = harness + .client + .post(format!("/channels/{}/invites", channel.id())) + .header(Header::new("x-session-token", session.token.to_string())) + .dispatch() + .await; + assert_eq!(create_response.status(), Status::Ok); + let invite_from_create: Invite = create_response.into_json().await.expect("`Invite`"); + let invite_code = match invite_from_create { + Invite::Server { code, .. } => code, + _ => unreachable!(), + }; + let response = harness + .client + .get(format!("/invites/{}", invite_code)) + .dispatch() + .await; + assert_eq!(response.status(), Status::Ok); + let invite_response: InviteResponse = response.into_json().await.expect("`FetchInvite`"); + match invite_response { + InviteResponse::Server { + code, + channel_id, + user_name, + .. + } => { + assert_eq!(code, invite_code); + assert_eq!(channel_id, channel.id()); + assert_eq!(user_name, user.username); + } + _ => unreachable!(), + }; + } + + #[rocket::async_test] + async fn success_fetch_voice_channel_invite() { + let harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + let (server, _) = Server::create( + &harness.db, + DataCreateServer { + name: "Test Server".to_string(), + ..Default::default() + }, + &user, + true, + ) + .await + .expect("Failed to create test server"); + let server_mut: &mut Server = &mut server.clone(); + + let channel = Channel::create_server_channel( + &harness.db, + server_mut, + DataCreateServerChannel { + channel_type: LegacyServerChannelType::Voice, + name: "Voice Channel".to_string(), + description: None, + nsfw: Some(false), + }, + true, + ) + .await + .expect("Failed to make new channel"); + let create_response = harness + .client + .post(format!("/channels/{}/invites", channel.id())) + .header(Header::new("x-session-token", session.token.to_string())) + .dispatch() + .await; + assert_eq!(create_response.status(), Status::Ok); + let invite_from_create: Invite = create_response.into_json().await.expect("`Invite`"); + let invite_code = match invite_from_create { + Invite::Server { code, .. } => code, + _ => unreachable!(), + }; + let response = harness + .client + .get(format!("/invites/{}", invite_code)) + .dispatch() + .await; + assert_eq!(response.status(), Status::Ok); + let invite_response: InviteResponse = response.into_json().await.expect("`FetchInvite`"); + match invite_response { + InviteResponse::Server { + code, + channel_id, + user_name, + .. + } => { + assert_eq!(code, invite_code); + assert_eq!(channel_id, channel.id()); + assert_eq!(user_name, user.username); + } + _ => unreachable!(), + }; + } +} From ac05fb385ca67d98d3295875b1f0abac8254fa3f Mon Sep 17 00:00:00 2001 From: phazeschift <51278042+phazeschift@users.noreply.github.com> Date: Sat, 15 Mar 2025 18:47:04 -0700 Subject: [PATCH 2/3] test: add utilities for common setup Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> --- .../delta/src/routes/invites/invite_fetch.rs | 69 +++++++------------ crates/delta/src/util/test.rs | 69 ++++++++++++++++++- 2 files changed, 92 insertions(+), 46 deletions(-) diff --git a/crates/delta/src/routes/invites/invite_fetch.rs b/crates/delta/src/routes/invites/invite_fetch.rs index 9fcfd6b5..306a680e 100644 --- a/crates/delta/src/routes/invites/invite_fetch.rs +++ b/crates/delta/src/routes/invites/invite_fetch.rs @@ -82,10 +82,9 @@ mod test { use crate::{rocket, util::test::TestHarness}; use revolt_database::{Channel, Server}; use revolt_models::v0::{ - DataCreateGroup, DataCreateServer, DataCreateServerChannel, Invite, InviteResponse, - LegacyServerChannelType, + DataCreateGroup, DataCreateServerChannel, Invite, InviteResponse, LegacyServerChannelType, }; - use rocket::http::{Header, Status}; + use rocket::http::Status; #[rocket::async_test] async fn success_fetch_group_invite() { @@ -101,12 +100,13 @@ mod test { ) .await .expect("`Channel`"); - let create_response = harness - .client - .post(format!("/channels/{}/invites", group.id())) - .header(Header::new("x-session-token", session.token.to_string())) - .dispatch() - .await; + let create_response = TestHarness::with_session( + session, + harness + .client + .post(format!("/channels/{}/invites", group.id())), + ) + .await; assert_eq!(create_response.status(), Status::Ok); let invite_from_create: Invite = create_response.into_json().await.expect("`Invite`"); let invite_code = match invite_from_create { @@ -150,25 +150,15 @@ mod test { async fn success_fetch_text_channel_invite() { let harness = TestHarness::new().await; let (_, session, user) = harness.new_user().await; - let (_, channels) = Server::create( - &harness.db, - DataCreateServer { - name: "Test Server".to_string(), - ..Default::default() - }, - &user, - true, - ) - .await - .expect("Failed to create test server"); - + let (_, channels) = harness.new_server(&user).await; let channel = channels.first().expect("Server Channel"); - let create_response = harness - .client - .post(format!("/channels/{}/invites", channel.id())) - .header(Header::new("x-session-token", session.token.to_string())) - .dispatch() - .await; + let create_response = TestHarness::with_session( + session, + harness + .client + .post(format!("/channels/{}/invites", channel.id())), + ) + .await; assert_eq!(create_response.status(), Status::Ok); let invite_from_create: Invite = create_response.into_json().await.expect("`Invite`"); let invite_code = match invite_from_create { @@ -201,17 +191,7 @@ mod test { async fn success_fetch_voice_channel_invite() { let harness = TestHarness::new().await; let (_, session, user) = harness.new_user().await; - let (server, _) = Server::create( - &harness.db, - DataCreateServer { - name: "Test Server".to_string(), - ..Default::default() - }, - &user, - true, - ) - .await - .expect("Failed to create test server"); + let (server, _) = harness.new_server(&user).await; let server_mut: &mut Server = &mut server.clone(); let channel = Channel::create_server_channel( @@ -227,12 +207,13 @@ mod test { ) .await .expect("Failed to make new channel"); - let create_response = harness - .client - .post(format!("/channels/{}/invites", channel.id())) - .header(Header::new("x-session-token", session.token.to_string())) - .dispatch() - .await; + let create_response = TestHarness::with_session( + session, + harness + .client + .post(format!("/channels/{}/invites", channel.id())), + ) + .await; assert_eq!(create_response.status(), Status::Ok); let invite_from_create: Invite = create_response.into_json().await.expect("`Invite`"); let invite_code = match invite_from_create { diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs index 325a7ccf..192aecc2 100644 --- a/crates/delta/src/util/test.rs +++ b/crates/delta/src/util/test.rs @@ -5,9 +5,13 @@ use authifier::{ use futures::StreamExt; use rand::Rng; use redis_kiss::redis::aio::PubSub; -use revolt_database::{events::client::EventV1, Database, User, AMQP}; +use revolt_database::util::idempotency::IdempotencyKey; +use revolt_database::{ + events::client::EventV1, Channel, Database, Member, Message, Server, User, AMQP, +}; use revolt_models::v0; -use rocket::local::asynchronous::Client; +use rocket::http::Header; +use rocket::local::asynchronous::{Client, LocalRequest, LocalResponse}; pub struct TestHarness { pub client: Client, @@ -104,6 +108,67 @@ impl TestHarness { (account, session, user) } + pub async fn new_server(&self, user: &User) -> (Server, Vec) { + Server::create( + &self.db, + v0::DataCreateServer { + name: "Test Server".to_string(), + ..Default::default() + }, + user, + true, + ) + .await + .expect("Failed to create test server") + } + + pub async fn new_message( + &self, + user: &User, + server: &Server, + channels: Vec, + ) -> (Channel, Member, Message) { + let (member, channels) = Member::create(&self.db, server, user, Some(channels)) + .await + .expect("Failed to create member"); + let channel = &channels[0]; + let message = Message::create_from_api( + &self.db, + None, + channel.clone(), + v0::DataMessageSend { + content: Some("Test message".to_string()), + nonce: None, + attachments: None, + replies: None, + embeds: None, + masquerade: None, + interactions: None, + flags: None, + }, + v0::MessageAuthor::User(&user.clone().into(&self.db, Some(user)).await), + Some(user.clone().into(&self.db, Some(user)).await), + Some(member.clone().into()), + user.limits().await, + IdempotencyKey::unchecked_from_string("0".to_string()), + false, + false, + ) + .await + .expect("Failed to create message"); + (channel.clone(), member, message) + } + + pub async fn with_session<'c>( + session: Session, + request: LocalRequest<'c>, + ) -> LocalResponse<'c> { + request + .header(Header::new("x-session-token", session.token.to_string())) + .dispatch() + .await + } + pub async fn wait_for_event(&mut self, topic: &str, predicate: F) -> EventV1 where F: Fn(&EventV1) -> bool, From 714fba7ea6b48e74e19da6259ca46905e3d7b145 Mon Sep 17 00:00:00 2001 From: phazeschift <51278042+phazeschift@users.noreply.github.com> Date: Sun, 16 Mar 2025 14:15:45 -0700 Subject: [PATCH 3/3] test: add delete server channel test Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> --- .../src/routes/channels/channel_delete.rs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/delta/src/routes/channels/channel_delete.rs b/crates/delta/src/routes/channels/channel_delete.rs index 86dea166..ca09ae2b 100644 --- a/crates/delta/src/routes/channels/channel_delete.rs +++ b/crates/delta/src/routes/channels/channel_delete.rs @@ -99,5 +99,26 @@ mod test { // TEST: member leaves group (no delete) // TEST: no effect with saved messages // TEST: DM set to inactive - // TEST: server channel deleted + + #[rocket::async_test] + async fn success_delete_channel() { + let mut harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + let (_, channels) = harness.new_server(&user).await; + let response = TestHarness::with_session( + session, + harness + .client + .delete(format!("/channels/{}", channels[0].id())), + ) + .await; + assert_eq!(response.status(), Status::NoContent); + drop(response); + harness + .wait_for_event(channels[0].id(), |event| match event { + EventV1::ChannelDelete { id, .. } => id == channels[0].id(), + _ => false, + }) + .await; + } }