diff options
Diffstat (limited to 'tests/integration.rs')
-rw-r--r-- | tests/integration.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/tests/integration.rs b/tests/integration.rs new file mode 100644 index 0000000..afded52 --- /dev/null +++ b/tests/integration.rs @@ -0,0 +1,73 @@ +use std::env; + +use anyhow::Context; +use base64::URL_SAFE_NO_PAD; +use chrono::{Duration, Utc}; +use futures::channel::oneshot::channel; +use minor_skulk::{build, db::Db}; +use password_hash::rand_core::OsRng; +use rand::RngCore; +use rocket::{ + fairing::AdHoc, + tokio::{process::Command, spawn}, +}; + +#[macro_use] +extern crate rocket; +extern crate anyhow; + +async fn run_pytest(markers: &'static str, invite: bool) -> anyhow::Result<()> { + dotenv::dotenv().ok(); + // at this point this is only a test runner to be used by the nix build. + env::set_var("ROCKET_LOG_LEVEL", "off"); + + let (tx, rx) = channel(); + let rocket = build().await?.attach(AdHoc::on_liftoff("notify startup", move |rocket| { + Box::pin(async move { + // add an invite code as-if generated during startup and move it to an + // env var, emulating the user looking at the logs and copying the code. + // invite_only needs this to function. + if invite { + let db = rocket.state::<Db>().unwrap(); + let tx = db.begin().await.unwrap(); + let mut code = [0; 32]; + OsRng.fill_bytes(&mut code); + let code = base64::encode_config(code, URL_SAFE_NO_PAD); + tx.add_invite_code(&code, Utc::now() + Duration::minutes(5)).await.unwrap(); + tx.commit().await.unwrap(); + env::set_var("INVITE_CODE", code); + } + + tx.send(()).unwrap(); + }) + })); + + spawn(async move { rocket.launch().await }); + let test = spawn(async move { + rx.await.expect("test trigger failed"); + let mut child = Command::new("pytest") + .arg("-vvv") + .arg("-m") + .arg(markers) + .spawn() + .expect("failed to spawn"); + child.wait().await + }); + + assert!(test.await.context("starting pytest")?.context("running pytest")?.success()); + + Ok(()) +} + +#[async_test] +async fn open() -> anyhow::Result<()> { + env::set_var("ROCKET_INVITE_ONLY", "false"); + run_pytest("not invite", false).await +} + +#[async_test] +async fn invite_only() -> anyhow::Result<()> { + env::set_var("ROCKET_INVITE_ONLY", "true"); + env::set_var("ROCKET_INVITE_ADMIN_ADDRESS", "test.account@test-auth"); + run_pytest("invite", true).await +} |