Skip to main content

mold_server/
test_support.rs

1//! Lightweight in-process test client for catalog route integration tests.
2//! Avoids the full hyper boot — uses `tower::ServiceExt::oneshot` directly.
3
4use axum::body::Body;
5use axum::http::{Request, StatusCode};
6use tower::ServiceExt;
7
8pub struct TestResponse {
9    pub status: StatusCode,
10    pub body: String,
11}
12
13pub struct TestApp {
14    router: axum::Router,
15}
16
17impl TestApp {
18    /// Build an empty AppState (catalog endpoints proxy live HF/Civitai;
19    /// tests that exercise live behaviour point catalog_live_civitai_base
20    /// at a wiremock instance via `with_civitai_base`).
21    pub async fn with_seeded_catalog() -> Self {
22        let state = crate::state::AppState::for_tests();
23        let router = crate::routes::create_router(state);
24        Self { router }
25    }
26
27    pub async fn get(&self, uri: &str) -> TestResponse {
28        let req = Request::builder().uri(uri).body(Body::empty()).unwrap();
29        let resp = self.router.clone().oneshot(req).await.unwrap();
30        let status = resp.status();
31        let bytes = axum::body::to_bytes(resp.into_body(), 1024 * 1024)
32            .await
33            .unwrap();
34        let body = String::from_utf8(bytes.to_vec()).unwrap();
35        TestResponse { status, body }
36    }
37
38    pub async fn post_json(&self, uri: &str, body: &str) -> TestResponse {
39        let req = Request::builder()
40            .method("POST")
41            .uri(uri)
42            .header("content-type", "application/json")
43            .body(Body::from(body.to_string()))
44            .unwrap();
45        let resp = self.router.clone().oneshot(req).await.unwrap();
46        let status = resp.status();
47        let bytes = axum::body::to_bytes(resp.into_body(), 1024 * 1024)
48            .await
49            .unwrap();
50        let body = String::from_utf8(bytes.to_vec()).unwrap();
51        TestResponse { status, body }
52    }
53}