feat(delta): test harness for web server

This commit is contained in:
Paul Makles
2023-08-27 13:01:21 +01:00
parent 73f7b8f007
commit 0542788567
8 changed files with 76 additions and 28 deletions

View File

@@ -8,14 +8,16 @@ use serde::Deserialize;
static CONFIG_BUILDER: Lazy<RwLock<Config>> = 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()
})
});

View File

@@ -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()
};

View File

@@ -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<String>, 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 {

View File

@@ -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<Build> {
// 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
}

View File

@@ -25,7 +25,7 @@ pub fn mount(mut rocket: Rocket<Build>) -> Rocket<Build> {
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<Build>) -> Rocket<Build> {
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(),

View File

@@ -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<Json<RevoltConfig>> {
}))
}
/// 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);
}
}

View File

@@ -1 +1,2 @@
pub mod ratelimiter;
pub mod test;

View 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
}
}