From 05427885674d8c0d80595b4903a2db8b5fff4a3a Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 27 Aug 2023 13:01:21 +0100 Subject: [PATCH] feat(delta): test harness for web server --- crates/core/config/src/lib.rs | 18 +++++++------ .../src/models/channel_webhooks/model.rs | 2 +- crates/core/database/src/tasks/web_push.rs | 7 ++--- crates/delta/src/main.rs | 22 ++++++++++------ crates/delta/src/routes/mod.rs | 4 +-- crates/delta/src/routes/root.rs | 24 ++++++++++++----- crates/delta/src/util/mod.rs | 1 + crates/delta/src/util/test.rs | 26 +++++++++++++++++++ 8 files changed, 76 insertions(+), 28 deletions(-) create mode 100644 crates/delta/src/util/test.rs diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index bc459290..3bd5c019 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -8,14 +8,16 @@ use serde::Deserialize; static CONFIG_BUILDER: Lazy> = Lazy::new(|| { RwLock::new({ - Config::builder() - .add_source(File::from_str( - include_str!("../Revolt.toml"), - FileFormat::Toml, - )) - .add_source(File::new("revolt.toml", FileFormat::Toml)) - .build() - .unwrap() + let mut builder = Config::builder().add_source(File::from_str( + include_str!("../Revolt.toml"), + FileFormat::Toml, + )); + + if std::path::Path::new("revolt.toml").exists() { + builder = builder.add_source(File::new("revolt.toml", FileFormat::Toml)); + } + + builder.build().unwrap() }) }); diff --git a/crates/core/database/src/models/channel_webhooks/model.rs b/crates/core/database/src/models/channel_webhooks/model.rs index 52a03317..568326d6 100644 --- a/crates/core/database/src/models/channel_webhooks/model.rs +++ b/crates/core/database/src/models/channel_webhooks/model.rs @@ -134,7 +134,7 @@ mod tests { id: webhook_id.to_string(), name: "Webhook Name".to_string(), channel_id: channel_id.to_string(), - avatar: Some(Default::default()), + avatar: None, ..Default::default() }; diff --git a/crates/core/database/src/tasks/web_push.rs b/crates/core/database/src/tasks/web_push.rs index 1d833ad8..fa74a3ca 100644 --- a/crates/core/database/src/tasks/web_push.rs +++ b/crates/core/database/src/tasks/web_push.rs @@ -2,12 +2,12 @@ use std::collections::HashSet; use authifier::Database; use base64::{ - alphabet, engine::{self}, Engine as _, }; use deadqueue::limited::Queue; use once_cell::sync::Lazy; +use revolt_config::config; use revolt_presence::filter_online; use web_push::{ ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, @@ -47,9 +47,10 @@ pub async fn queue(recipients: Vec, payload: String) { /// Start a new worker pub async fn worker(db: Database) { + let config = config().await; let client = IsahcWebPushClient::new().unwrap(); - let key = engine::GeneralPurpose::new(&alphabet::URL_SAFE, engine::general_purpose::NO_PAD) - .decode(std::env::var("REVOLT_VAPID_PRIVATE_KEY").unwrap()) + let key = engine::general_purpose::URL_SAFE_NO_PAD + .decode(config.api.vapid.private_key) .expect("valid `VAPID_PRIVATE_KEY`"); loop { diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 38406a0d..f517f29b 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -8,6 +8,7 @@ extern crate serde_json; pub mod routes; pub mod util; +use rocket::{Build, Rocket}; use rocket_cors::{AllowedOrigins, CorsOptions}; use rocket_prometheus::PrometheusMetrics; use std::net::Ipv4Addr; @@ -19,14 +20,7 @@ use revolt_quark::events::client::EventV1; use revolt_quark::DatabaseInfo; use rocket::data::ToByteUnit; -#[launch] -async fn rocket() -> _ { - // Configure logging and environment - revolt_quark::configure!(); - - // Ensure environment variables are present - revolt_quark::variables::delta::preflight_checks(); - +pub async fn web() -> Rocket { // Setup database let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); db.migrate_database().await.unwrap(); @@ -109,3 +103,15 @@ async fn rocket() -> _ { ..Default::default() }) } + +#[launch] +async fn rocket() -> _ { + // Configure logging and environment + revolt_quark::configure!(); + + // Ensure environment variables are present + revolt_quark::variables::delta::preflight_checks(); + + // Start web server + web().await +} diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 7b3f3e4c..b9b0fac0 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -25,7 +25,7 @@ pub fn mount(mut rocket: Rocket) -> Rocket { mount_endpoints_and_merged_docs! { rocket, "/".to_owned(), settings, "/" => (vec![], custom_openapi_spec()), - "" => openapi_get_routes_spec![root::root, root::ping], + "" => openapi_get_routes_spec![root::root], "/admin" => admin::routes(), "/users" => users::routes(), "/bots" => bots::routes(), @@ -46,7 +46,7 @@ pub fn mount(mut rocket: Rocket) -> Rocket { mount_endpoints_and_merged_docs! { rocket, "/".to_owned(), settings, "/" => (vec![], custom_openapi_spec()), - "" => openapi_get_routes_spec![root::root, root::ping], + "" => openapi_get_routes_spec![root::root], "/admin" => admin::routes(), "/users" => users::routes(), "/bots" => bots::routes(), diff --git a/crates/delta/src/routes/root.rs b/crates/delta/src/routes/root.rs index c6743142..978a040b 100644 --- a/crates/delta/src/routes/root.rs +++ b/crates/delta/src/routes/root.rs @@ -4,7 +4,6 @@ use revolt_quark::variables::delta::{ }; use revolt_quark::Result; -use rocket::http::Status; use rocket::serde::json::Json; use serde::Serialize; @@ -138,9 +137,22 @@ pub async fn root() -> Result> { })) } -/// Example endpoint. -#[openapi(skip)] -#[get("/ping")] -pub async fn ping(/*_limitguard: Ratelimiter*/) -> Status { - Status::Ok +#[cfg(test)] +mod test { + use crate::rocket; + use rocket::http::Status; + + #[rocket::async_test] + async fn hello_world() { + let harness = crate::util::test::TestHarness::new().await; + let response = harness.get("/").dispatch().await; + assert_eq!(response.status(), Status::Ok); + } + + #[rocket::async_test] + async fn hello_world_concurrent() { + let harness = crate::util::test::TestHarness::new().await; + let response = harness.get("/").dispatch().await; + assert_eq!(response.status(), Status::Ok); + } } diff --git a/crates/delta/src/util/mod.rs b/crates/delta/src/util/mod.rs index 8f8380fa..6ee3a7f6 100644 --- a/crates/delta/src/util/mod.rs +++ b/crates/delta/src/util/mod.rs @@ -1 +1,2 @@ pub mod ratelimiter; +pub mod test; diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs new file mode 100644 index 00000000..d4567275 --- /dev/null +++ b/crates/delta/src/util/test.rs @@ -0,0 +1,26 @@ +use rocket::local::asynchronous::Client; +use std::ops::Deref; + +pub struct TestHarness { + client: Client, +} + +impl TestHarness { + pub async fn new() -> TestHarness { + dotenv::dotenv().ok(); + + let client = Client::tracked(crate::web().await) + .await + .expect("valid rocket instance"); + + TestHarness { client } + } +} + +impl Deref for TestHarness { + type Target = Client; + + fn deref(&self) -> &Self::Target { + &self.client + } +}