Skip to main content

oxidite_testing/
server.rs

1use oxidite_core::{Router, OxiditeRequest, OxiditeResponse, Result};
2use bytes::Bytes;
3use http_body_util::{BodyExt, Full};
4use tower::Service;
5
6/// Test server for integration testing
7pub struct TestServer<S> {
8    service: S,
9}
10
11impl<S> TestServer<S>
12where
13    S: Service<OxiditeRequest, Response = OxiditeResponse> + Clone + Send + 'static,
14    S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
15    S::Future: Send,
16{
17    /// Create a new test server from a service
18    pub fn new(service: S) -> Self {
19        Self { service }
20    }
21
22    /// Send a request to the test server
23    pub async fn call(&mut self, request: OxiditeRequest) -> Result<OxiditeResponse> {
24        use tower::ServiceExt;
25        self.service
26            .ready()
27            .await
28            .map_err(|e| oxidite_core::Error::InternalServerError(format!("Service not ready: {:?}", e.into())))?
29            .call(request)
30            .await
31            .map_err(|e| oxidite_core::Error::InternalServerError(format!("Request failed: {:?}", e.into())))
32    }
33
34    /// Send a plain HTTP test request after converting its body to Oxidite's boxed body.
35    pub async fn call_http(&mut self, request: http::Request<Full<Bytes>>) -> Result<OxiditeResponse> {
36        let (parts, body) = request.into_parts();
37        let request = http::Request::from_parts(parts, body.map_err(|e| match e {}).boxed());
38        self.call(request).await
39    }
40}
41
42/// Helper to test a router
43pub fn test_router(router: Router) -> TestServer<Router> {
44    TestServer::new(router)
45}