use serde::de::DeserializeOwned;
use http::StatusCode;
use http_body_util::BodyExt;
pub struct TestResponse {
status: StatusCode,
body: Vec<u8>,
}
impl TestResponse {
pub fn new(status: StatusCode, body: Vec<u8>) -> Self {
Self { status, body }
}
pub fn status(&self) -> StatusCode {
self.status
}
pub fn body(&self) -> &[u8] {
&self.body
}
pub fn text(&self) -> Result<String, std::string::FromUtf8Error> {
String::from_utf8(self.body.clone())
}
pub fn text_lossy(&self) -> String {
String::from_utf8_lossy(&self.body).to_string()
}
pub fn json<T: DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
serde_json::from_slice(&self.body)
}
pub fn is_success(&self) -> bool {
self.status.is_success()
}
pub fn assert_status(&self, expected: StatusCode) {
assert_eq!(
self.status, expected,
"expected status {}, got {}",
expected, self.status
);
}
pub fn assert_success(&self) {
assert!(
self.is_success(),
"expected successful status, got {}",
self.status
);
}
pub async fn from_oxidite_response(response: oxidite_core::OxiditeResponse) -> Self {
let response = response.into_inner();
let status = response.status();
let body = response.into_body();
let bytes = body
.collect()
.await
.expect("failed to collect response body")
.to_bytes();
Self::new(status, bytes.to_vec())
}
}
#[cfg(test)]
mod tests {
use super::TestResponse;
use http::StatusCode;
#[test]
fn text_lossy_handles_binary() {
let response = TestResponse::new(StatusCode::OK, vec![0xff, 0xfe, b'A']);
let text = response.text_lossy();
assert!(text.contains('A'));
}
#[tokio::test]
async fn from_oxidite_response_collects_body() {
let response = oxidite_core::OxiditeResponse::text("hello");
let test_response = TestResponse::from_oxidite_response(response).await;
assert_eq!(test_response.status(), StatusCode::OK);
assert_eq!(test_response.text().expect("text"), "hello");
}
}