// Shared test helpers. Each integration test binary picks the subset it needs, // so dead-code lints on the unused helpers fire per-binary; suppress at the // module level. #![allow(dead_code)] use std::sync::Arc; use axum::body::Body; use axum::http::{header, Request}; use axum::Router; use http_body_util::BodyExt; use serde_json::json; use sqlx::PgPool; use tempfile::TempDir; use tower::ServiceExt; use mangalord::app::{router, AppState}; use mangalord::config::AuthConfig; use mangalord::storage::LocalStorage; pub struct Harness { pub app: Router, // Kept alive for the lifetime of the test so the temp dir is not dropped. pub _storage_dir: TempDir, } pub fn harness(pool: PgPool) -> Harness { let storage_dir = tempfile::tempdir().expect("tempdir"); let state = AppState { db: pool, storage: Arc::new(LocalStorage::new(storage_dir.path())), auth: AuthConfig { cookie_secure: false, ..AuthConfig::default() }, }; Harness { app: router(state), _storage_dir: storage_dir } } pub async fn body_json(response: axum::response::Response) -> serde_json::Value { let bytes = response.into_body().collect().await.unwrap().to_bytes(); serde_json::from_slice(&bytes).expect("body is JSON") } pub fn get(uri: &str) -> Request
{ Request::builder().uri(uri).body(Body::empty()).unwrap() } pub fn get_with_cookie(uri: &str, cookie: &str) -> Request { Request::builder() .uri(uri) .header(header::COOKIE, cookie) .body(Body::empty()) .unwrap() } pub fn get_with_bearer(uri: &str, token: &str) -> Request { Request::builder() .uri(uri) .header(header::AUTHORIZATION, format!("Bearer {token}")) .body(Body::empty()) .unwrap() } pub fn post_json(uri: &str, body: serde_json::Value) -> Request { Request::builder() .method("POST") .uri(uri) .header(header::CONTENT_TYPE, "application/json") .body(Body::from(body.to_string())) .unwrap() } pub fn post_json_with_cookie( uri: &str, body: serde_json::Value, cookie: &str, ) -> Request { Request::builder() .method("POST") .uri(uri) .header(header::CONTENT_TYPE, "application/json") .header(header::COOKIE, cookie) .body(Body::from(body.to_string())) .unwrap() } pub fn post_json_with_bearer( uri: &str, body: serde_json::Value, token: &str, ) -> Request { Request::builder() .method("POST") .uri(uri) .header(header::CONTENT_TYPE, "application/json") .header(header::AUTHORIZATION, format!("Bearer {token}")) .body(Body::from(body.to_string())) .unwrap() } pub fn delete_with_cookie(uri: &str, cookie: &str) -> Request { Request::builder() .method("DELETE") .uri(uri) .header(header::COOKIE, cookie) .body(Body::empty()) .unwrap() } /// Extracts the `mangalord_session` cookie from a response's Set-Cookie /// headers as a `name=value` pair suitable for use in a follow-up `Cookie` /// request header. Returns `None` if no such cookie was set. pub fn extract_session_cookie(response: &axum::response::Response) -> Option