mithril_client/
cardano_stake_distribution_client.rs1use std::sync::Arc;
76
77use crate::common::{Epoch, EpochSpecifier};
78use crate::{CardanoStakeDistribution, CardanoStakeDistributionListItem, MithrilResult};
79
80pub struct CardanoStakeDistributionClient {
82 aggregator_requester: Arc<dyn CardanoStakeDistributionAggregatorRequest>,
83}
84
85#[cfg_attr(test, mockall::automock)]
87#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
88#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
89pub trait CardanoStakeDistributionAggregatorRequest: Send + Sync {
90 async fn list_latest(&self) -> MithrilResult<Vec<CardanoStakeDistributionListItem>>;
92
93 async fn get_by_hash(&self, hash: &str) -> MithrilResult<Option<CardanoStakeDistribution>>;
95
96 async fn get_by_epoch(
98 &self,
99 specifier: EpochSpecifier,
100 ) -> MithrilResult<Option<CardanoStakeDistribution>>;
101}
102
103impl CardanoStakeDistributionClient {
104 pub fn new(aggregator_requester: Arc<dyn CardanoStakeDistributionAggregatorRequest>) -> Self {
106 Self {
107 aggregator_requester,
108 }
109 }
110
111 pub async fn list(&self) -> MithrilResult<Vec<CardanoStakeDistributionListItem>> {
113 self.aggregator_requester.list_latest().await
114 }
115
116 pub async fn get(&self, hash: &str) -> MithrilResult<Option<CardanoStakeDistribution>> {
118 self.aggregator_requester.get_by_hash(hash).await
119 }
120
121 pub async fn get_by_epoch(
123 &self,
124 epoch: Epoch,
125 ) -> MithrilResult<Option<CardanoStakeDistribution>> {
126 self.aggregator_requester
127 .get_by_epoch(EpochSpecifier::Number(epoch))
128 .await
129 }
130
131 pub async fn get_for_latest_epoch(&self) -> MithrilResult<Option<CardanoStakeDistribution>> {
133 self.aggregator_requester.get_by_epoch(EpochSpecifier::Latest).await
134 }
135
136 pub async fn get_for_latest_epoch_with_offset(
138 &self,
139 offset: u64,
140 ) -> MithrilResult<Option<CardanoStakeDistribution>> {
141 self.aggregator_requester
142 .get_by_epoch(EpochSpecifier::LatestMinusOffset(offset))
143 .await
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use mockall::predicate::eq;
150
151 use mithril_common::test::mock_extensions::MockBuilder;
152
153 use crate::common::test::Dummy;
154
155 use super::*;
156
157 #[tokio::test]
158 async fn list_cardano_stake_distributions_returns_messages() {
159 let aggregator_requester =
160 MockBuilder::<MockCardanoStakeDistributionAggregatorRequest>::configure(|mock| {
161 let messages = vec![
162 CardanoStakeDistributionListItem {
163 hash: "hash-123".to_string(),
164 ..Dummy::dummy()
165 },
166 CardanoStakeDistributionListItem {
167 hash: "hash-456".to_string(),
168 ..Dummy::dummy()
169 },
170 ];
171 mock.expect_list_latest().return_once(|| Ok(messages));
172 });
173 let client = CardanoStakeDistributionClient::new(aggregator_requester);
174
175 let messages = client.list().await.unwrap();
176
177 assert_eq!(2, messages.len());
178 assert_eq!("hash-123".to_string(), messages[0].hash);
179 assert_eq!("hash-456".to_string(), messages[1].hash);
180 }
181
182 #[tokio::test]
183 async fn get_cardano_stake_distribution_returns_message() {
184 let aggregator_requester =
185 MockBuilder::<MockCardanoStakeDistributionAggregatorRequest>::configure(|mock| {
186 let message = CardanoStakeDistribution {
187 hash: "hash_1".to_string(),
188 certificate_hash: "certificate_123".to_string(),
189 ..Dummy::dummy()
190 };
191 mock.expect_get_by_hash()
192 .with(eq(message.hash.clone()))
193 .return_once(|_| Ok(Some(message)));
194 });
195 let client = CardanoStakeDistributionClient::new(aggregator_requester);
196
197 let cardano_stake_distribution = client
198 .get("hash_1")
199 .await
200 .unwrap()
201 .expect("This test returns a Cardano stake distribution");
202
203 assert_eq!("hash_1", &cardano_stake_distribution.hash);
204 assert_eq!(
205 "certificate_123",
206 &cardano_stake_distribution.certificate_hash
207 );
208 }
209
210 #[tokio::test]
211 async fn get_cardano_stake_distribution_by_epoch_returns_message() {
212 let aggregator_requester =
213 MockBuilder::<MockCardanoStakeDistributionAggregatorRequest>::configure(|mock| {
214 let message = CardanoStakeDistribution {
215 hash: "hash_2".to_string(),
216 epoch: Epoch(2),
217 ..Dummy::dummy()
218 };
219 mock.expect_get_by_epoch()
220 .with(eq(EpochSpecifier::Number(Epoch(2))))
221 .return_once(|_| Ok(Some(message)));
222 });
223 let client = CardanoStakeDistributionClient::new(aggregator_requester);
224
225 let cardano_stake_distribution = client
226 .get_by_epoch(Epoch(2))
227 .await
228 .unwrap()
229 .expect("This test returns a Cardano stake distribution");
230
231 assert_eq!("hash_2", &cardano_stake_distribution.hash);
232 assert_eq!(Epoch(2), &cardano_stake_distribution.epoch);
233 }
234
235 #[tokio::test]
236 async fn get_cardano_stake_distribution_for_latest_epoch_returns_message() {
237 let aggregator_requester =
238 MockBuilder::<MockCardanoStakeDistributionAggregatorRequest>::configure(|mock| {
239 let message = CardanoStakeDistribution {
240 hash: "hash_3".to_string(),
241 epoch: Epoch(3),
242 ..Dummy::dummy()
243 };
244 mock.expect_get_by_epoch()
245 .with(eq(EpochSpecifier::Latest))
246 .return_once(|_| Ok(Some(message)));
247 });
248 let client = CardanoStakeDistributionClient::new(aggregator_requester);
249
250 let cardano_stake_distribution = client
251 .get_for_latest_epoch()
252 .await
253 .unwrap()
254 .expect("This test returns a Cardano stake distribution");
255
256 assert_eq!("hash_3", &cardano_stake_distribution.hash);
257 assert_eq!(Epoch(3), &cardano_stake_distribution.epoch);
258 }
259
260 #[tokio::test]
261 async fn get_cardano_stake_distribution_for_latest_with_offset_epoch_returns_message() {
262 let aggregator_requester =
263 MockBuilder::<MockCardanoStakeDistributionAggregatorRequest>::configure(|mock| {
264 let message = CardanoStakeDistribution {
265 hash: "hash_4".to_string(),
266 epoch: Epoch(4),
267 ..Dummy::dummy()
268 };
269 mock.expect_get_by_epoch()
270 .with(eq(EpochSpecifier::LatestMinusOffset(4)))
271 .return_once(|_| Ok(Some(message)));
272 });
273 let client = CardanoStakeDistributionClient::new(aggregator_requester);
274
275 let cardano_stake_distribution = client
276 .get_for_latest_epoch_with_offset(4)
277 .await
278 .unwrap()
279 .expect("This test returns a Cardano stake distribution");
280
281 assert_eq!("hash_4", &cardano_stake_distribution.hash);
282 assert_eq!(Epoch(4), &cardano_stake_distribution.epoch);
283 }
284}