mithril_aggregator_client/query/get/
get_protocol_configuration.rs

1use async_trait::async_trait;
2use reqwest::StatusCode;
3
4use mithril_common::entities::Epoch;
5use mithril_common::messages::ProtocolConfigurationMessage;
6
7use crate::AggregatorHttpClientResult;
8use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
9
10/// Query to get the protocol configuration of a given epoch
11pub struct GetProtocolConfigurationQuery {
12    epoch: Epoch,
13}
14
15impl GetProtocolConfigurationQuery {
16    /// Instantiate a query to get the current epoch settings
17    pub fn epoch(epoch: Epoch) -> Self {
18        Self { epoch }
19    }
20}
21
22#[cfg_attr(target_family = "wasm", async_trait(?Send))]
23#[cfg_attr(not(target_family = "wasm"), async_trait)]
24impl AggregatorQuery for GetProtocolConfigurationQuery {
25    type Response = Option<ProtocolConfigurationMessage>;
26    type Body = ();
27
28    fn method() -> QueryMethod {
29        QueryMethod::Get
30    }
31
32    fn route(&self) -> String {
33        format!("protocol-configuration/{}", self.epoch)
34    }
35
36    async fn handle_response(
37        &self,
38        context: QueryContext,
39    ) -> AggregatorHttpClientResult<Self::Response> {
40        match context.response.status() {
41            StatusCode::OK => context.response.parse_json_option().await,
42            StatusCode::NOT_FOUND => Ok(None),
43            _ => Err(context.unhandled_status_code().await),
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use serde_json::json;
51
52    use mithril_common::test::double::Dummy;
53
54    use crate::AggregatorHttpClientError;
55    use crate::test::{assert_error_matches, setup_server_and_client};
56
57    use super::*;
58
59    #[tokio::test]
60    async fn test_ok_200() {
61        let (server, client) = setup_server_and_client();
62        let message_expected = ProtocolConfigurationMessage::dummy();
63        let _server_mock = server.mock(|when, then| {
64            when.path("/protocol-configuration/42");
65            then.status(200).body(json!(message_expected).to_string());
66        });
67
68        let message = client
69            .send(GetProtocolConfigurationQuery::epoch(Epoch(42)))
70            .await
71            .unwrap();
72
73        assert_eq!(Some(message_expected), message);
74    }
75
76    #[tokio::test]
77    async fn test_ok_404() {
78        let (server, client) = setup_server_and_client();
79        let _server_mock = server.mock(|when, then| {
80            when.any_request();
81            then.status(404);
82        });
83
84        let message = client
85            .send(GetProtocolConfigurationQuery::epoch(Epoch(42)))
86            .await
87            .unwrap();
88
89        assert_eq!(None, message);
90    }
91
92    #[tokio::test]
93    async fn test_ko_500() {
94        let (server, client) = setup_server_and_client();
95        let _server_mock = server.mock(|when, then| {
96            when.any_request();
97            then.status(500).body("an error occurred");
98        });
99
100        let error = client
101            .send(GetProtocolConfigurationQuery::epoch(Epoch(42)))
102            .await
103            .expect_err("should throw a error");
104
105        assert_error_matches!(error, AggregatorHttpClientError::RemoteServerTechnical(_));
106    }
107}