Skip to content

Commit a07587d

Browse files
committed
feat(aggregator-client): add missing queries needed by a follower aggregator
Add `GetCertificatesListQuery` and `GetEpochSettingsQuery`
1 parent 9fe35e4 commit a07587d

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use anyhow::anyhow;
2+
use async_trait::async_trait;
3+
use reqwest::StatusCode;
4+
5+
use mithril_common::messages::CertificateListMessage;
6+
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8+
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
9+
10+
/// Query to get a list of certificates
11+
pub struct GetCertificatesListQuery {}
12+
13+
impl GetCertificatesListQuery {
14+
/// Instantiate a query to get the latest certificates list
15+
pub fn latest() -> Self {
16+
Self {}
17+
}
18+
}
19+
20+
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
21+
#[cfg_attr(not(target_family = "wasm"), async_trait)]
22+
impl AggregatorQuery for GetCertificatesListQuery {
23+
type Response = CertificateListMessage;
24+
type Body = ();
25+
26+
fn method() -> QueryMethod {
27+
QueryMethod::Get
28+
}
29+
30+
fn route(&self) -> String {
31+
"certificates".to_string()
32+
}
33+
34+
async fn handle_response(
35+
&self,
36+
context: QueryContext,
37+
) -> AggregatorHttpClientResult<Self::Response> {
38+
match context.response.status() {
39+
StatusCode::OK => match context.response.json::<CertificateListMessage>().await {
40+
Ok(message) => Ok(message),
41+
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
42+
},
43+
_ => Err(context.unhandled_status_code().await),
44+
}
45+
}
46+
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use serde_json::json;
51+
52+
use mithril_common::messages::CertificateListItemMessage;
53+
use mithril_common::test::double::Dummy;
54+
55+
use crate::test::{assert_error_matches, setup_server_and_client};
56+
57+
use super::*;
58+
59+
#[tokio::test]
60+
async fn test_latest_certificates_list_ok_200() {
61+
let (server, client) = setup_server_and_client();
62+
let expected_list = vec![
63+
CertificateListItemMessage::dummy(),
64+
CertificateListItemMessage::dummy(),
65+
];
66+
let _server_mock = server.mock(|when, then| {
67+
when.path("/certificates");
68+
then.status(200).body(json!(expected_list).to_string());
69+
});
70+
71+
let fetched_list = client.send(GetCertificatesListQuery::latest()).await.unwrap();
72+
73+
assert_eq!(expected_list, fetched_list);
74+
}
75+
76+
#[tokio::test]
77+
async fn test_latest_certificates_list_ko_500() {
78+
let (server, client) = setup_server_and_client();
79+
let _server_mock = server.mock(|when, then| {
80+
when.path("/certificates");
81+
then.status(500).body("an error occurred");
82+
});
83+
84+
let error = client.send(GetCertificatesListQuery::latest()).await.unwrap_err();
85+
86+
assert_error_matches!(error, AggregatorHttpClientError::RemoteServerTechnical(_));
87+
}
88+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use anyhow::anyhow;
2+
use async_trait::async_trait;
3+
use reqwest::StatusCode;
4+
5+
use mithril_common::messages::EpochSettingsMessage;
6+
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8+
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
9+
10+
/// Query to get the current epoch settings
11+
pub struct GetEpochSettingsQuery {}
12+
13+
impl GetEpochSettingsQuery {
14+
/// Instantiate a query to get the current epoch settings
15+
pub fn current() -> Self {
16+
Self {}
17+
}
18+
}
19+
20+
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
21+
#[cfg_attr(not(target_family = "wasm"), async_trait)]
22+
impl AggregatorQuery for GetEpochSettingsQuery {
23+
type Response = EpochSettingsMessage;
24+
type Body = ();
25+
26+
fn method() -> QueryMethod {
27+
QueryMethod::Get
28+
}
29+
30+
fn route(&self) -> String {
31+
"epoch-settings".to_string()
32+
}
33+
34+
async fn handle_response(
35+
&self,
36+
context: QueryContext,
37+
) -> AggregatorHttpClientResult<Self::Response> {
38+
match context.response.status() {
39+
StatusCode::OK => match context.response.json::<EpochSettingsMessage>().await {
40+
Ok(message) => Ok(message),
41+
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
42+
},
43+
_ => Err(context.unhandled_status_code().await),
44+
}
45+
}
46+
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use serde_json::json;
51+
52+
use mithril_common::test::double::Dummy;
53+
54+
use crate::test::{assert_error_matches, setup_server_and_client};
55+
56+
use super::*;
57+
58+
#[tokio::test]
59+
async fn test_epoch_settings_ok_200() {
60+
let (server, client) = setup_server_and_client();
61+
let epoch_settings_expected = EpochSettingsMessage::dummy();
62+
let _server_mock = server.mock(|when, then| {
63+
when.path("/epoch-settings");
64+
then.status(200).body(json!(epoch_settings_expected).to_string());
65+
});
66+
67+
let epoch_settings = client.send(GetEpochSettingsQuery::current()).await.unwrap();
68+
assert_eq!(epoch_settings_expected, epoch_settings);
69+
}
70+
71+
#[tokio::test]
72+
async fn test_epoch_settings_ko_500() {
73+
let (server, client) = setup_server_and_client();
74+
let _server_mock = server.mock(|when, then| {
75+
when.path("/epoch-settings");
76+
then.status(500).body("an error occurred");
77+
});
78+
79+
let error = client.send(GetEpochSettingsQuery::current()).await.unwrap_err();
80+
81+
assert_error_matches!(error, AggregatorHttpClientError::RemoteServerTechnical(_));
82+
}
83+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
mod get_certificate;
2+
mod get_certificates_list;
3+
mod get_epoch_settings;
24

35
pub use get_certificate::*;
6+
pub use get_certificates_list::*;
7+
pub use get_epoch_settings::*;

0 commit comments

Comments
 (0)