diff --git a/Cargo.lock b/Cargo.lock index 1b248de..532f500 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,16 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde 1.0.210", + "serde_json", +] + [[package]] name = "async-channel" version = "1.9.0" @@ -284,6 +294,12 @@ dependencies = [ "uuid 0.4.0", ] +[[package]] +name = "auto-future" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373" + [[package]] name = "autocfg" version = "1.4.0" @@ -300,7 +316,7 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "hyper 1.5.2", @@ -333,7 +349,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "mime", @@ -345,6 +361,36 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-test" +version = "16.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e3a443d2608936a02a222da7b746eb412fede7225b3030b64fe9be99eab8dc" +dependencies = [ + "anyhow", + "assert-json-diff", + "auto-future", + "axum", + "bytes", + "bytesize", + "cookie", + "http 1.2.0", + "http-body-util", + "hyper 1.5.2", + "hyper-util", + "mime", + "pretty_assertions", + "reserve-port", + "rust-multipart-rfc7578_2", + "serde 1.0.210", + "serde_json", + "serde_urlencoded", + "smallvec", + "tokio", + "tower", + "url", +] + [[package]] name = "az" version = "1.2.1" @@ -483,9 +529,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "cairo-rs" @@ -697,6 +749,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + [[package]] name = "cookie-factory" version = "0.3.3" @@ -901,6 +963,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -1918,9 +1995,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -1945,7 +2022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -1956,7 +2033,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "pin-project-lite", ] @@ -2012,7 +2089,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "httparse", "httpdate", @@ -2020,6 +2097,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[package]] @@ -2042,13 +2120,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", + "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "hyper 1.5.2", "pin-project-lite", + "socket2", "tokio", "tower-service", + "tracing", ] [[package]] @@ -2589,6 +2670,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -2964,6 +3051,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -2973,6 +3066,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "pretty_env_logger" version = "0.5.0" @@ -3264,6 +3367,16 @@ dependencies = [ "winreg", ] +[[package]] +name = "reserve-port" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9838134a2bfaa8e1f40738fcc972ac799de6e0e06b5157acb95fc2b05a0ea283" +dependencies = [ + "lazy_static", + "thiserror 1.0.64", +] + [[package]] name = "result-extended" version = "0.1.0" @@ -3316,6 +3429,22 @@ dependencies = [ "rusqlite", ] +[[package]] +name = "rust-multipart-rfc7578_2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b748410c0afdef2ebbe3685a6a862e2ee937127cdaae623336a459451c8d57" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "http 0.2.12", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror 1.0.64", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4054,6 +4183,37 @@ dependencies = [ "weezl", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde 1.0.210", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "timezone-testing" version = "0.1.0" @@ -4088,9 +4248,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -4285,7 +4445,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "rand 0.8.5", @@ -4500,6 +4660,7 @@ dependencies = [ "async-trait", "authdb", "axum", + "axum-test", "cool_asserts", "futures", "include_dir", @@ -4879,6 +5040,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yansi-term" version = "0.1.2" diff --git a/visions/server/Cargo.toml b/visions/server/Cargo.toml index fd52875..8d1d27e 100644 --- a/visions/server/Cargo.toml +++ b/visions/server/Cargo.toml @@ -10,6 +10,7 @@ async-std = { version = "1.13.0" } async-trait = { version = "0.1.83" } authdb = { path = "../../authdb/" } axum = { version = "0.7.9" } +axum-test = "16.4.1" futures = { version = "0.3.31" } include_dir = { version = "0.7.4" } lazy_static = { version = "1.5.0" } diff --git a/visions/server/src/handlers/mod.rs b/visions/server/src/handlers/mod.rs index b7ad690..6d33a58 100644 --- a/visions/server/src/handlers/mod.rs +++ b/visions/server/src/handlers/mod.rs @@ -13,9 +13,9 @@ use crate::{ types::{AppError, FatalError}, }; -#[derive(Serialize)] -struct HealthCheck { - ok: bool, +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct HealthCheck { + pub ok: bool, } pub async fn healthcheck(core: Core) -> Vec { @@ -40,7 +40,7 @@ pub async fn check_password(core: Core, req: Json) -> (StatusCode, let Json(AuthRequest { username, password }) = req; match core.auth(&username, &password).await { ResultExt::Ok(session_id) => (StatusCode::OK, Json(Some(session_id))), - ResultExt::Err(err) => (StatusCode::UNAUTHORIZED, Json(None)), + ResultExt::Err(_err) => (StatusCode::UNAUTHORIZED, Json(None)), ResultExt::Fatal(err) => panic!("Fatal: {}", err), } } diff --git a/visions/server/src/main.rs b/visions/server/src/main.rs index 2ed2b87..84524e6 100644 --- a/visions/server/src/main.rs +++ b/visions/server/src/main.rs @@ -2,15 +2,14 @@ use core::Core; use std::path::PathBuf; use asset_db::FsAssets; -use axum::{routing::{get, post}, Router, Json}; use database::DbConn; mod asset_db; mod core; mod database; mod filters; -mod handlers; -use handlers::{ healthcheck, check_password, AuthRequest}; +pub mod handlers; +pub mod routes; mod types; #[tokio::main] @@ -25,19 +24,7 @@ pub async fn main() { let conn = DbConn::new(Some("/home/savanni/game.db")); let core = Core::new(FsAssets::new(PathBuf::from("/home/savanni/Pictures")), conn); - let app = Router::new().route( - "/api/v1/health", - get({ - let core = core.clone(); - move || healthcheck(core) - }), - ).route( - "/api/v1/auth", - post({ - let core = core.clone(); - move |req: Json| handlers::check_password(core, req) - }), - ); + let app = routes::routes(core); let listener = tokio::net::TcpListener::bind("127.0.0.1:8001") .await diff --git a/visions/server/src/routes.rs b/visions/server/src/routes.rs new file mode 100644 index 0000000..c644c58 --- /dev/null +++ b/visions/server/src/routes.rs @@ -0,0 +1,54 @@ +use axum::{routing::{get, post}, Json, Router}; + +use crate::{ + core::Core, + handlers::{check_password, healthcheck, AuthRequest}, +}; + +pub fn routes(core: Core) -> Router { + Router::new() + .route( + "/api/v1/health", + get({ + let core = core.clone(); + move || healthcheck(core) + }), + ) + .route( + "/api/v1/auth", + post({ + let core = core.clone(); + move |req: Json| check_password(core, req) + }), + ) +} + +#[cfg(test)] +mod test { + use std::path::PathBuf; + + use axum_test::TestServer; + + use crate::{asset_db::FsAssets, core::Core, database::DbConn}; + use super::*; + + fn setup() -> (Core, TestServer) { + let memory_db: Option = None; + let conn = DbConn::new(memory_db); + let core = Core::new(FsAssets::new(PathBuf::from("/home/savanni/Pictures")), conn); + let app = routes(core.clone()); + let server = TestServer::new(app).unwrap(); + (core, server) + } + + #[tokio::test] + async fn it_returns_a_healthcheck() { + let (_core, server) = setup(); + let response = server.get("/api/v1/health").await; + response.assert_status_ok(); + + let b: crate::handlers::HealthCheck = response.json(); + + assert_eq!(b, crate::handlers::HealthCheck { ok: false }); + } +}