use super::*;
use crate::test_support::json_server;
const BODY: &str = r#"{"ok": true}"#;
async fn read_from(server: &wiremock::MockServer, max_bytes: u64) -> Result<String, ReadError> {
let response = client(Duration::from_secs(5))
.expect("a client builds")
.get(format!("{}/api.json", server.uri()))
.send()
.await
.expect("the mock server answers");
read_bounded(response, max_bytes).await
}
#[tokio::test]
async fn a_body_exactly_at_the_limit_is_within_it() {
let server = json_server("/api.json", 200, BODY).await;
let body = read_from(&server, BODY.len() as u64)
.await
.expect("a body exactly at the limit is within it");
assert_eq!(body, BODY);
}
#[tokio::test]
async fn a_body_one_byte_over_the_limit_is_refused() {
let server = json_server("/api.json", 200, BODY).await;
let err = read_from(&server, BODY.len() as u64 - 1)
.await
.expect_err("a body past the limit is refused");
assert!(matches!(err, ReadError::Transport(_)), "got {err:?}");
assert!(err.to_string().contains("limit"), "and says why: {err}");
}
#[tokio::test]
async fn a_declared_length_past_the_limit_is_refused_before_the_body_is_read() {
let server = wiremock::MockServer::start().await;
wiremock::Mock::given(wiremock::matchers::method("GET"))
.and(wiremock::matchers::path("/api.json"))
.respond_with(wiremock::ResponseTemplate::new(200).set_body_string(BODY))
.mount(&server)
.await;
let err = read_from(&server, 4).await.expect_err("refused");
assert!(
err.to_string().contains("declares"),
"the header check is what refused it, not the streaming cap: {err}"
);
}
#[tokio::test]
async fn a_response_declaring_no_length_is_still_bounded() {
let server = wiremock::MockServer::start().await;
wiremock::Mock::given(wiremock::matchers::method("GET"))
.and(wiremock::matchers::path("/api.json"))
.respond_with(
wiremock::ResponseTemplate::new(200)
.set_body_string(BODY)
.append_header("transfer-encoding", "chunked"),
)
.mount(&server)
.await;
let err = read_from(&server, 4).await.expect_err("refused");
assert!(
err.to_string().contains("exceeded"),
"the streaming cap is what refused it: {err}"
);
}
#[tokio::test]
async fn a_body_that_is_not_utf8_is_malformed_rather_than_transport() {
let server = wiremock::MockServer::start().await;
wiremock::Mock::given(wiremock::matchers::method("GET"))
.and(wiremock::matchers::path("/api.json"))
.respond_with(wiremock::ResponseTemplate::new(200).set_body_bytes(vec![0xff, 0xfe, 0xfd]))
.mount(&server)
.await;
let err = read_from(&server, 1024).await.expect_err("not text");
assert!(matches!(err, ReadError::Malformed(_)), "got {err:?}");
}
#[tokio::test]
async fn a_client_carries_the_timeout_it_was_built_with() {
let err = client(Duration::from_millis(50))
.expect("a client builds")
.get("http://127.0.0.1:9/api.json")
.send()
.await
.expect_err("nothing is listening");
assert!(err.is_connect() || err.is_timeout(), "got {err:?}");
}