use axum::{
Router,
body::{Body, to_bytes},
http::{HeaderMap, Method, Request},
response::Response,
};
use serde_json::Value;
use tower::ServiceExt;
use maincopy_server::{
domain::publication::PublicLedgerProjection,
frontend_assets::embedded_manifest,
render::{SiteSnapshotReader, compile_content_catalog, render_site_shell},
web::{PublicState, Readiness},
};
use markdown_compiler::{ContentTreeLimits, discover_content_tree, prepare_content};
pub fn public_state(readiness: Readiness) -> PublicState {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("examples/content");
let tree = discover_content_tree(&root, ContentTreeLimits::default())
.expect("example content tree must be discoverable");
let content = prepare_content(&tree).expect("example content and assets must prepare");
let catalog = std::sync::Arc::new(
compile_content_catalog(&content).expect("example catalog must compile"),
);
let ledger = PublicLedgerProjection::empty();
let shell = render_site_shell(catalog, embedded_manifest(), &ledger)
.expect("empty public shell must render");
let snapshot = shell
.into_snapshot()
.expect("empty public snapshot must build");
PublicState {
snapshots: SiteSnapshotReader::from_snapshot(snapshot),
readiness,
}
}
pub async fn get(app: Router, path: &str) -> Response {
request(app, Method::GET, path).await
}
pub async fn request(app: Router, method: Method, path: &str) -> Response {
request_with_headers(app, method, path, HeaderMap::new()).await
}
pub async fn request_with_headers(
app: Router,
method: Method,
path: &str,
headers: HeaderMap,
) -> Response {
let mut request = Request::builder()
.method(method)
.uri(path)
.body(Body::empty())
.expect("test request must be valid");
*request.headers_mut() = headers;
app.oneshot(request)
.await
.expect("router must produce a response")
}
pub async fn body_bytes(response: Response) -> axum::body::Bytes {
to_bytes(response.into_body(), usize::MAX)
.await
.expect("response body must be readable")
}
pub async fn json_body(response: Response) -> Value {
let body = body_bytes(response).await;
serde_json::from_slice(&body).expect("response body must be valid JSON")
}