feat(delta): test harness for web server
This commit is contained in:
@@ -8,14 +8,16 @@ use serde::Deserialize;
|
|||||||
|
|
||||||
static CONFIG_BUILDER: Lazy<RwLock<Config>> = Lazy::new(|| {
|
static CONFIG_BUILDER: Lazy<RwLock<Config>> = Lazy::new(|| {
|
||||||
RwLock::new({
|
RwLock::new({
|
||||||
Config::builder()
|
let mut builder = Config::builder().add_source(File::from_str(
|
||||||
.add_source(File::from_str(
|
include_str!("../Revolt.toml"),
|
||||||
include_str!("../Revolt.toml"),
|
FileFormat::Toml,
|
||||||
FileFormat::Toml,
|
));
|
||||||
))
|
|
||||||
.add_source(File::new("revolt.toml", FileFormat::Toml))
|
if std::path::Path::new("revolt.toml").exists() {
|
||||||
.build()
|
builder = builder.add_source(File::new("revolt.toml", FileFormat::Toml));
|
||||||
.unwrap()
|
}
|
||||||
|
|
||||||
|
builder.build().unwrap()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ mod tests {
|
|||||||
id: webhook_id.to_string(),
|
id: webhook_id.to_string(),
|
||||||
name: "Webhook Name".to_string(),
|
name: "Webhook Name".to_string(),
|
||||||
channel_id: channel_id.to_string(),
|
channel_id: channel_id.to_string(),
|
||||||
avatar: Some(Default::default()),
|
avatar: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use authifier::Database;
|
use authifier::Database;
|
||||||
use base64::{
|
use base64::{
|
||||||
alphabet,
|
|
||||||
engine::{self},
|
engine::{self},
|
||||||
Engine as _,
|
Engine as _,
|
||||||
};
|
};
|
||||||
use deadqueue::limited::Queue;
|
use deadqueue::limited::Queue;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use revolt_config::config;
|
||||||
use revolt_presence::filter_online;
|
use revolt_presence::filter_online;
|
||||||
use web_push::{
|
use web_push::{
|
||||||
ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder,
|
ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder,
|
||||||
@@ -47,9 +47,10 @@ pub async fn queue(recipients: Vec<String>, payload: String) {
|
|||||||
|
|
||||||
/// Start a new worker
|
/// Start a new worker
|
||||||
pub async fn worker(db: Database) {
|
pub async fn worker(db: Database) {
|
||||||
|
let config = config().await;
|
||||||
let client = IsahcWebPushClient::new().unwrap();
|
let client = IsahcWebPushClient::new().unwrap();
|
||||||
let key = engine::GeneralPurpose::new(&alphabet::URL_SAFE, engine::general_purpose::NO_PAD)
|
let key = engine::general_purpose::URL_SAFE_NO_PAD
|
||||||
.decode(std::env::var("REVOLT_VAPID_PRIVATE_KEY").unwrap())
|
.decode(config.api.vapid.private_key)
|
||||||
.expect("valid `VAPID_PRIVATE_KEY`");
|
.expect("valid `VAPID_PRIVATE_KEY`");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ extern crate serde_json;
|
|||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
|
use rocket::{Build, Rocket};
|
||||||
use rocket_cors::{AllowedOrigins, CorsOptions};
|
use rocket_cors::{AllowedOrigins, CorsOptions};
|
||||||
use rocket_prometheus::PrometheusMetrics;
|
use rocket_prometheus::PrometheusMetrics;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
@@ -19,14 +20,7 @@ use revolt_quark::events::client::EventV1;
|
|||||||
use revolt_quark::DatabaseInfo;
|
use revolt_quark::DatabaseInfo;
|
||||||
use rocket::data::ToByteUnit;
|
use rocket::data::ToByteUnit;
|
||||||
|
|
||||||
#[launch]
|
pub async fn web() -> Rocket<Build> {
|
||||||
async fn rocket() -> _ {
|
|
||||||
// Configure logging and environment
|
|
||||||
revolt_quark::configure!();
|
|
||||||
|
|
||||||
// Ensure environment variables are present
|
|
||||||
revolt_quark::variables::delta::preflight_checks();
|
|
||||||
|
|
||||||
// Setup database
|
// Setup database
|
||||||
let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap();
|
let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap();
|
||||||
db.migrate_database().await.unwrap();
|
db.migrate_database().await.unwrap();
|
||||||
@@ -109,3 +103,15 @@ async fn rocket() -> _ {
|
|||||||
..Default::default()
|
..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
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub fn mount(mut rocket: Rocket<Build>) -> Rocket<Build> {
|
|||||||
mount_endpoints_and_merged_docs! {
|
mount_endpoints_and_merged_docs! {
|
||||||
rocket, "/".to_owned(), settings,
|
rocket, "/".to_owned(), settings,
|
||||||
"/" => (vec![], custom_openapi_spec()),
|
"/" => (vec![], custom_openapi_spec()),
|
||||||
"" => openapi_get_routes_spec![root::root, root::ping],
|
"" => openapi_get_routes_spec![root::root],
|
||||||
"/admin" => admin::routes(),
|
"/admin" => admin::routes(),
|
||||||
"/users" => users::routes(),
|
"/users" => users::routes(),
|
||||||
"/bots" => bots::routes(),
|
"/bots" => bots::routes(),
|
||||||
@@ -46,7 +46,7 @@ pub fn mount(mut rocket: Rocket<Build>) -> Rocket<Build> {
|
|||||||
mount_endpoints_and_merged_docs! {
|
mount_endpoints_and_merged_docs! {
|
||||||
rocket, "/".to_owned(), settings,
|
rocket, "/".to_owned(), settings,
|
||||||
"/" => (vec![], custom_openapi_spec()),
|
"/" => (vec![], custom_openapi_spec()),
|
||||||
"" => openapi_get_routes_spec![root::root, root::ping],
|
"" => openapi_get_routes_spec![root::root],
|
||||||
"/admin" => admin::routes(),
|
"/admin" => admin::routes(),
|
||||||
"/users" => users::routes(),
|
"/users" => users::routes(),
|
||||||
"/bots" => bots::routes(),
|
"/bots" => bots::routes(),
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use revolt_quark::variables::delta::{
|
|||||||
};
|
};
|
||||||
use revolt_quark::Result;
|
use revolt_quark::Result;
|
||||||
|
|
||||||
use rocket::http::Status;
|
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@@ -138,9 +137,22 @@ pub async fn root() -> Result<Json<RevoltConfig>> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Example endpoint.
|
#[cfg(test)]
|
||||||
#[openapi(skip)]
|
mod test {
|
||||||
#[get("/ping")]
|
use crate::rocket;
|
||||||
pub async fn ping(/*_limitguard: Ratelimiter*/) -> Status {
|
use rocket::http::Status;
|
||||||
Status::Ok
|
|
||||||
|
#[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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod ratelimiter;
|
pub mod ratelimiter;
|
||||||
|
pub mod test;
|
||||||
|
|||||||
26
crates/delta/src/util/test.rs
Normal file
26
crates/delta/src/util/test.rs
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user