improved tests
Some checks failed
CI/CD Pipeline / lint (push) Successful in 3m45s
CI/CD Pipeline / integration-tests (push) Failing after 55s
CI/CD Pipeline / unit-tests (push) Failing after 1m1s
CI/CD Pipeline / e2e-tests (push) Has been skipped
CI/CD Pipeline / build (push) Has been skipped

This commit is contained in:
2026-03-15 13:01:53 +02:00
parent 8ade39ae2d
commit 780e8b1c43
6 changed files with 396 additions and 0 deletions

View File

@@ -175,3 +175,140 @@ pub async fn run() -> anyhow::Result<()> {
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use axum::{body::Body, http::Request, routing::get};
use tower::ServiceExt;
use std::sync::Mutex;
static ENV_LOCK: Mutex<()> = Mutex::new(());
#[tokio::test]
async fn test_cors_blocks_unknown_origin() {
let _guard = ENV_LOCK.lock().unwrap();
unsafe { std::env::set_var("ALLOWED_ORIGINS", "http://localhost:3000") };
let app = Router::new()
.route("/test", get(|| async { "ok" }))
.layer(
CorsLayer::new()
.allow_origin(parse_allowed_origins())
.allow_methods([Method::GET])
.allow_credentials(true),
);
let response = app
.oneshot(
Request::builder()
.method("OPTIONS")
.uri("/test")
.header("Origin", "http://evil.com")
.header("Access-Control-Request-Method", "GET")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
let acao = response
.headers()
.get("access-control-allow-origin")
.map(|v| v.to_str().unwrap_or(""));
assert!(acao.is_none() || acao == Some(""), "CORS should not allow http://evil.com");
unsafe { std::env::remove_var("ALLOWED_ORIGINS") };
}
#[tokio::test]
async fn test_cors_allows_configured_origin() {
let _guard = ENV_LOCK.lock().unwrap();
unsafe { std::env::set_var("ALLOWED_ORIGINS", "http://localhost:3000,http://mydomain.com") };
let app = Router::new()
.route("/test", get(|| async { "ok" }))
.layer(
CorsLayer::new()
.allow_origin(parse_allowed_origins())
.allow_methods([Method::GET])
.allow_credentials(true),
);
let response = app
.oneshot(
Request::builder()
.method("OPTIONS")
.uri("/test")
.header("Origin", "http://mydomain.com")
.header("Access-Control-Request-Method", "GET")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
let acao = response
.headers()
.get("access-control-allow-origin")
.map(|v| v.to_str().unwrap_or(""));
assert_eq!(acao, Some("http://mydomain.com"));
unsafe { std::env::remove_var("ALLOWED_ORIGINS") };
}
#[tokio::test]
async fn test_login_rejects_wrong_password() {
let _guard = ENV_LOCK.lock().unwrap();
unsafe { std::env::set_var("ADMIN_PASSWORD", "correct-horse-battery-staple") };
let admin_state = AdminAuthState::new();
let app = Router::new()
.route("/login", axum::routing::post(login_handler).with_state(admin_state));
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/login")
.header("Content-Type", "application/json")
.body(Body::from(r#"{"password":"wrong"}"#))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
unsafe { std::env::remove_var("ADMIN_PASSWORD") };
}
#[tokio::test]
async fn test_login_accepts_correct_password() {
let _guard = ENV_LOCK.lock().unwrap();
unsafe { std::env::set_var("ADMIN_PASSWORD", "correct-horse-battery-staple") };
let admin_state = AdminAuthState::new();
let app = Router::new()
.route("/login", axum::routing::post(login_handler).with_state(admin_state));
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/login")
.header("Content-Type", "application/json")
.body(Body::from(r#"{"password":"correct-horse-battery-staple"}"#))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let cookie = response.headers().get("set-cookie").unwrap().to_str().unwrap();
assert!(cookie.contains("madbase_admin_session="));
assert!(cookie.contains("HttpOnly"));
assert!(cookie.contains("SameSite=Strict"));
unsafe { std::env::remove_var("ADMIN_PASSWORD") };
}
}