apollo_router/plugin/test/
service.rs1#![allow(dead_code, unreachable_pub)]
2#![allow(missing_docs)] #[cfg(test)]
5use std::sync::Arc;
6
7use futures::Future;
8use http::Request as HyperRequest;
9use http::Response as HyperResponse;
10
11use crate::services::ExecutionRequest;
12use crate::services::ExecutionResponse;
13#[cfg(test)]
14use crate::services::HasSchema;
15use crate::services::RouterRequest;
16use crate::services::RouterResponse;
17use crate::services::SubgraphRequest;
18use crate::services::SubgraphResponse;
19use crate::services::SupergraphRequest;
20use crate::services::SupergraphResponse;
21use crate::services::router::Body;
22#[cfg(test)]
23use crate::spec::Schema;
24
25macro_rules! mock_service {
27 ($name:ident, $request_type:ty, $response_type:ty) => {
28 paste::item! {
29 mockall::mock! {
30 #[derive(Debug)]
31 #[allow(dead_code)]
32 pub [<$name Service>] {
33 pub fn call(&mut self, req: $request_type) -> Result<$response_type, tower::BoxError>;
34 }
35
36 #[allow(dead_code)]
37 impl Clone for [<$name Service>] {
38 fn clone(&self) -> [<Mock $name Service>];
39 }
40 }
41
42 impl tower::Service<$request_type> for [<Mock $name Service>] {
44 type Response = $response_type;
45 type Error = tower::BoxError;
46 type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
47
48 fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), tower::BoxError>> {
49 std::task::Poll::Ready(Ok(()))
50 }
51 fn call(&mut self, req: $request_type) -> Self::Future {
52 let r = self.call(req);
53 Box::pin(async move { r })
54 }
55 }
56 }
57 };
58}
59
60macro_rules! mock_async_service {
61 ($name:ident, $request_type:tt < $req_generic:tt > , $response_type:tt < $res_generic:tt >) => {
62 paste::item! {
63 mockall::mock! {
64 #[derive(Debug)]
65 #[allow(dead_code)]
66 pub [<$name Service>] {
67 pub fn call(&mut self, req: $request_type<$req_generic>) -> impl Future<Output = Result<$response_type<$res_generic>, tower::BoxError>> + Send + 'static;
68 }
69
70 #[allow(dead_code)]
71 impl Clone for [<$name Service>] {
72 fn clone(&self) -> [<Mock $name Service>];
73 }
74 }
75
76
77 impl tower::Service<$request_type<$req_generic>> for [<Mock $name Service>] {
79 type Response = $response_type<$res_generic>;
80 type Error = tower::BoxError;
81 type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
82
83 fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), tower::BoxError>> {
84 std::task::Poll::Ready(Ok(()))
85 }
86 fn call(&mut self, req: $request_type<$req_generic>) -> Self::Future {
87 Box::pin(self.call(req))
88 }
89 }
90 }
91 };
92}
93
94#[cfg(test)]
95impl HasSchema for MockSupergraphService {
96 fn schema(&self) -> Arc<crate::spec::Schema> {
97 Arc::new(
98 Schema::parse(
99 include_str!("../../testdata/supergraph.graphql"),
100 &Default::default(),
101 )
102 .unwrap(),
103 )
104 }
105}
106
107mock_service!(Router, RouterRequest, RouterResponse);
108mock_service!(Supergraph, SupergraphRequest, SupergraphResponse);
109mock_service!(Execution, ExecutionRequest, ExecutionResponse);
110mock_service!(Subgraph, SubgraphRequest, SubgraphResponse);
111mock_async_service!(HttpClient, HyperRequest<Body>, HyperResponse<Body>);
112
113#[cfg(test)]
117pub(crate) use internal::MockInternalHttpClientService;
118#[cfg(test)]
119mod internal {
120 use futures::Future;
121 use http::Request as HyperRequest;
122 use http::Response as HyperResponse;
123
124 use crate::services::router::body::RouterBody;
125
126 mock_async_service!(
127 InternalHttpClient,
128 HyperRequest<RouterBody>,
129 HyperResponse<RouterBody>
130 );
131}