e2e_test_client/
lib.rs

1use std::time::Duration;
2
3use e2e_test_model::{
4    CreateExecutionRequest, CreateStepRequest, Execution, GetExecutionsRequest, Step,
5};
6pub use reqwest::header::HeaderValue;
7use uuid::Uuid;
8
9pub mod model {
10    pub use e2e_test_model::*;
11}
12
13pub struct Config {
14    pub base_url: String,
15    pub api_header: Option<(String, HeaderValue)>,
16}
17
18pub struct Client {
19    inner: reqwest_middleware::ClientWithMiddleware,
20    config: Config,
21}
22
23impl Client {
24    pub fn new(config: Config) -> reqwest::Result<Self> {
25        let inner = reqwest::Client::builder()
26            .timeout(Duration::from_secs(15))
27            .connect_timeout(Duration::from_secs(30))
28            .build()?;
29        let retry_policy = reqwest_retry::policies::ExponentialBackoff {
30            max_n_retries: 5,
31            min_retry_interval: Duration::from_millis(100),
32            max_retry_interval: Duration::from_secs(5),
33            backoff_exponent: 2,
34        };
35        let retry_transient_middleware =
36            reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy);
37        let inner = reqwest_middleware::ClientBuilder::new(inner)
38            .with(retry_transient_middleware)
39            .build();
40
41        let mut config = config;
42        if let Some((_, ref mut api_key)) = config.api_header {
43            api_key.set_sensitive(true);
44        }
45
46        Ok(Self { inner, config })
47    }
48
49    pub async fn get_executions(
50        &self,
51        params: &GetExecutionsRequest,
52    ) -> reqwest_middleware::Result<Vec<Execution>> {
53        let resp = self
54            .inner
55            .get(self.url("/test-warehouse/executions"))
56            .base_headers(&self.config)
57            .query(&params)
58            .send()
59            .await?
60            .json()
61            .await?;
62
63        Ok(resp)
64    }
65
66    pub async fn post_execution(
67        &self,
68        body: &CreateExecutionRequest,
69    ) -> reqwest_middleware::Result<Execution> {
70        let resp = self
71            .inner
72            .post(self.url("/test-warehouse/executions"))
73            .base_headers(&self.config)
74            .json(body)
75            .send()
76            .await?
77            .json()
78            .await?;
79
80        Ok(resp)
81    }
82
83    pub async fn post_step(
84        &self,
85        uuid: &Uuid,
86        body: &CreateStepRequest,
87    ) -> reqwest_middleware::Result<Step> {
88        let url = format!("/test-warehouse/executions/{}/steps", uuid);
89        let resp = self
90            .inner
91            .post(self.url(&url))
92            .base_headers(&self.config)
93            .json(body)
94            .send()
95            .await?
96            .json()
97            .await?;
98
99        Ok(resp)
100    }
101
102    fn url(&self, uri: &str) -> String {
103        format!("{}{}", self.config.base_url, uri)
104    }
105}
106
107trait BaseHeaders {
108    fn base_headers(self, config: &Config) -> Self;
109}
110
111impl BaseHeaders for reqwest_middleware::RequestBuilder {
112    fn base_headers(self, config: &Config) -> Self {
113        if let Some((ref header, ref api_key)) = config.api_header {
114            self.header(header, api_key)
115        } else {
116            self
117        }
118    }
119}