use hyper::StatusCode;
use mini_serve::{body, handler, json, RouteBuilder, ServeError};
use hyper::body::Bytes;
use hyper::Response;
#[tokio::test]
async fn an_in_memory_body_is_framed_by_content_length_not_chunked() {
let payload = "hello, framing";
let app = RouteBuilder::stateless()
.get(
"/bytes",
handler(move |_req, _state| async move {
Ok::<_, ServeError>(Response::new(body(Bytes::from(payload))))
}),
)
.seal();
let port = app.bind_ephemeral().await.unwrap();
let response = reqwest::get(format!("http://127.0.0.1:{port}/bytes")).await.unwrap();
assert_eq!(
response.headers().get("content-length").map(|v| v.to_str().unwrap()),
Some(payload.len().to_string().as_str()),
"an in-memory body must carry its exact length"
);
assert!(
!response.headers().contains_key("transfer-encoding"),
"a known-length body must not be chunked: {:?}",
response.headers()
);
assert_eq!(response.text().await.unwrap(), payload);
}
#[tokio::test]
async fn a_json_body_keeps_its_content_length() {
let app = RouteBuilder::stateless()
.get(
"/json",
handler(|_req, _state| async {
json(StatusCode::OK, &serde_json::json!({"ok": true}))
}),
)
.seal();
let port = app.bind_ephemeral().await.unwrap();
let response = reqwest::get(format!("http://127.0.0.1:{port}/json")).await.unwrap();
let len: usize = response
.headers()
.get("content-length")
.expect("json responses must be length-framed")
.to_str()
.unwrap()
.parse()
.unwrap();
let text = response.text().await.unwrap();
assert_eq!(len, text.len(), "declared length must match the body sent");
}
#[tokio::test]
async fn head_reports_the_length_of_the_get_it_mirrors() {
let payload = "a body of known size";
let app = RouteBuilder::stateless()
.get(
"/thing",
handler(move |_req, _state| async move {
Ok::<_, ServeError>(Response::new(body(Bytes::from(payload))))
}),
)
.seal();
let port = app.bind_ephemeral().await.unwrap();
let client = reqwest::Client::new();
let url = format!("http://127.0.0.1:{port}/thing");
let get = client.get(&url).send().await.unwrap();
let get_len = get.headers().get("content-length").cloned();
let head = client.head(&url).send().await.unwrap();
assert_eq!(head.headers().get("content-length"), get_len.as_ref());
assert!(!head.headers().contains_key("transfer-encoding"));
assert!(head.text().await.unwrap().is_empty(), "HEAD must send no body");
}