use bytes::Bytes;
use http::HeaderMap;
use http::HeaderName;
use http::HeaderValue;
use http::Method;
use serde::Serialize;
use tower::Service;
use volter_core::BoxBody;
use volter_core::Request;
use volter_router::Router;
use crate::response::TestResponse;
pub struct TestRequestBuilder<S> {
pub(crate) router: Router<S>,
pub(crate) method: Method,
pub(crate) path: String,
pub(crate) headers: HeaderMap,
pub(crate) body: Option<Bytes>,
}
impl<S: Clone + Send + 'static> TestRequestBuilder<S> {
pub fn header(mut self, name: HeaderName, value: HeaderValue) -> Self {
self.headers.append(name, value);
self
}
pub fn json<T: Serialize>(mut self, value: &T) -> Self {
let bytes = serde_json::to_vec(value).unwrap_or_else(|_| Vec::new());
self.headers.insert(
http::header::CONTENT_TYPE,
HeaderValue::from_static("application/json"),
);
self.body = Some(Bytes::from(bytes));
self
}
pub fn body(mut self, body: impl Into<Bytes>) -> Self {
self.body = Some(body.into());
self
}
pub async fn send(mut self) -> TestResponse {
let request = self.build_request();
let response = self
.router
.call(request)
.await
.unwrap_or_else(|never| match never {});
TestResponse::new(response)
}
fn build_request(&self) -> Request<BoxBody> {
let body: BoxBody = match &self.body {
Some(bytes) => volter_core::full_body(bytes.clone()),
None => volter_core::empty_body(),
};
let mut request = Request::builder()
.method(self.method.clone())
.uri(&self.path)
.body(body)
.unwrap_or_else(|_| Request::new(volter_core::empty_body()));
for (name, value) in &self.headers {
request.headers_mut().insert(name, value.clone());
}
request
}
}