use toxi_core::{Router, ToxiRequest, ToxiResponse, Result};
use bytes::Bytes;
use http_body_util::{BodyExt, Full};
use tower::Service;
pub struct TestServer<S> {
service: S,
}
impl<S> Clone for TestServer<S>
where
S: Clone,
{
fn clone(&self) -> Self {
Self {
service: self.service.clone(),
}
}
}
impl<S> TestServer<S>
where
S: Service<ToxiRequest, Response = ToxiResponse> + Clone + Send + 'static,
S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
S::Future: Send,
{
pub fn new(service: S) -> Self {
Self { service }
}
pub async fn call(&mut self, request: ToxiRequest) -> Result<ToxiResponse> {
use tower::ServiceExt;
self.service
.ready()
.await
.map_err(|e| toxi_core::Error::InternalServerError(format!("Service not ready: {:?}", e.into())))?
.call(request)
.await
.map_err(|e| toxi_core::Error::InternalServerError(format!("Request failed: {:?}", e.into())))
}
pub async fn call_http(&mut self, request: http::Request<Full<Bytes>>) -> Result<ToxiResponse> {
let (parts, body) = request.into_parts();
let request = http::Request::from_parts(parts, body.map_err(|e| match e {}).boxed());
self.call(request).await
}
}
pub fn test_router(router: Router) -> TestServer<Router> {
TestServer::new(router)
}