mithril_aggregator_client/
external_trait_impls.rs1use anyhow::{Context, anyhow};
2use async_trait::async_trait;
3
4use mithril_common::certificate_chain::{CertificateRetriever, CertificateRetrieverError};
5use mithril_common::entities::Certificate;
6
7use crate::AggregatorHttpClient;
8use crate::query::GetCertificateQuery;
9
10#[cfg_attr(target_family = "wasm", async_trait(?Send))]
11#[cfg_attr(not(target_family = "wasm"), async_trait)]
12impl CertificateRetriever for AggregatorHttpClient {
13 async fn get_certificate_details(
14 &self,
15 certificate_hash: &str,
16 ) -> Result<Certificate, CertificateRetrieverError> {
17 let message = self
18 .send(GetCertificateQuery::by_hash(certificate_hash))
19 .await
20 .with_context(|| {
21 format!("Failed to retrieve certificate with hash: '{certificate_hash}'")
22 })
23 .map_err(CertificateRetrieverError)?
24 .ok_or(CertificateRetrieverError(anyhow!(
25 "Certificate does not exist: '{certificate_hash}'"
26 )))?;
27
28 message.try_into().map_err(CertificateRetrieverError)
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use mithril_common::{
35 entities::ServerError, messages::CertificateMessage, test::double::Dummy,
36 };
37
38 use super::*;
39
40 #[tokio::test]
41 async fn test_retrieve_certificate_that_exist() {
42 let certificate_message = CertificateMessage::dummy();
43 let expected_certificate = certificate_message.clone().try_into().unwrap();
44
45 let (server, client) = crate::test::setup_server_and_client();
46 server.mock(|when, then| {
47 when.method(httpmock::Method::GET)
48 .path(format!("/certificate/{}", certificate_message.hash));
49 then.status(200)
50 .body(serde_json::to_string(&certificate_message).unwrap());
51 });
52
53 let certificate = client
54 .get_certificate_details(&certificate_message.hash)
55 .await
56 .unwrap();
57
58 assert_eq!(certificate, expected_certificate);
59 }
60
61 #[tokio::test]
62 async fn test_retrieve_certificate_that_does_not_exist() {
63 let (server, client) = crate::test::setup_server_and_client();
64 server.mock(|when, then| {
65 when.method(httpmock::Method::GET);
66 then.status(404);
67 });
68
69 let error = client.get_certificate_details("whatever").await.unwrap_err();
70
71 assert!(
72 format!("{error:?}").contains("Certificate does not exist"),
73 "Error message should contain 'Certificate does not exist', error:\n{error:?}",
74 );
75 }
76
77 #[tokio::test]
78 async fn test_retrieve_certificate_when_request_fails() {
79 let (server, client) = crate::test::setup_server_and_client();
80 server.mock(|when, then| {
81 when.method(httpmock::Method::GET);
82 then.status(500)
83 .body(serde_json::to_string(&ServerError::new("an error")).unwrap());
84 });
85
86 let error = client.get_certificate_details("whatever").await.unwrap_err();
87
88 assert!(
89 format!("{error:?}").contains("Failed to retrieve certificate with hash"),
90 "Error message should contain 'Failed to retrieve certificate with hash', error:\n{error:?}",
91 );
92 }
93}