etopay_sdk/core/
exchange.rs1use super::Sdk;
2use crate::{backend::dlt::get_exchange_rate, error::Result};
3use log::info;
4use rust_decimal::Decimal;
5
6impl Sdk {
7 pub async fn get_exchange_rate(&self) -> Result<Decimal> {
14 info!("Fetching exchange rate from viviswap");
15 let _user = self.get_user().await?;
16
17 let access_token = self
18 .access_token
19 .as_ref()
20 .ok_or(crate::error::Error::MissingAccessToken)?;
21 let config = self.config.as_ref().ok_or(crate::Error::MissingConfig)?;
22 let network = self.active_network.clone().ok_or(crate::Error::MissingNetwork)?;
23 let exchange_rate = get_exchange_rate(config, access_token, network.key).await?;
24 Ok(exchange_rate)
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use crate::core::core_testing_utils::handle_error_test_cases;
31 use crate::testing_utils::{IOTA_NETWORK_KEY, example_api_networks};
32 use crate::types::users::ActiveUser;
33 use crate::{
34 core::Sdk,
35 error::Result,
36 testing_utils::{
37 AUTH_PROVIDER, HEADER_X_APP_NAME, TOKEN, USERNAME, example_exchange_rate_response, example_get_user,
38 set_config,
39 },
40 types::users::KycType,
41 wallet_manager::MockWalletManager,
42 };
43 use api_types::api::viviswap::detail::SwapPaymentDetailKey;
44 use mockito::Matcher;
45 use rstest::rstest;
46 use rust_decimal::Decimal;
47
48 #[rstest]
49 #[case::success(Ok(example_exchange_rate_response().course.course.0))]
50 #[case::repo_init_error(Err(crate::Error::UserRepoNotInitialized))]
51 #[case::unauthorized(Err(crate::Error::MissingAccessToken))]
52 #[case::missing_config(Err(crate::Error::MissingConfig))]
53 #[tokio::test]
54 async fn test_get_exchange_rate(#[case] expected: Result<Decimal>) {
55 let (mut srv, config, _cleanup) = set_config().await;
57 let mut sdk = Sdk::new(config).unwrap();
58 let mut mock_server = None;
59
60 match &expected {
61 Ok(_) => {
62 let mock_user_repo = example_get_user(SwapPaymentDetailKey::Iota, false, 1, KycType::Undefined);
63 sdk.repo = Some(Box::new(mock_user_repo));
64 sdk.active_user = Some(crate::types::users::ActiveUser {
65 username: USERNAME.into(),
66 wallet_manager: Box::new(MockWalletManager::new()),
67 mnemonic_derivation_options: Default::default(),
68 });
69 sdk.access_token = Some(TOKEN.clone());
70 sdk.set_networks(example_api_networks());
71 sdk.set_network(IOTA_NETWORK_KEY.to_string()).await.unwrap();
72
73 let body = serde_json::to_string(&example_exchange_rate_response()).unwrap();
74 mock_server = Some(
75 srv.mock("GET", "/api/courses")
76 .match_header(HEADER_X_APP_NAME, AUTH_PROVIDER)
77 .match_header("authorization", format!("Bearer {}", TOKEN.as_str()).as_str())
78 .match_query(Matcher::Exact("network_key=IOTA".to_string()))
79 .with_status(200)
80 .with_body(&body)
81 .expect(1)
82 .create(),
83 );
84 }
85 Err(error) => {
86 handle_error_test_cases(error, &mut sdk, 1, 1).await;
87 }
88 }
89
90 let response = sdk.get_exchange_rate().await;
92
93 match expected {
95 Ok(resp) => {
96 assert_eq!(response.unwrap(), resp);
97 }
98 Err(ref expected_err) => {
99 assert_eq!(response.err().unwrap().to_string(), expected_err.to_string());
100 }
101 }
102 if let Some(m) = mock_server {
103 m.assert();
104 }
105 }
106
107 #[tokio::test]
108 async fn it_should_get_exchange_rate() {
109 let (mut srv, config, _cleanup) = set_config().await;
111 let mut sdk = Sdk::new(config).unwrap();
112 sdk.set_networks(example_api_networks());
113 sdk.set_network(IOTA_NETWORK_KEY.to_string()).await.unwrap();
114
115 sdk.repo = Some(Box::new(example_get_user(
116 SwapPaymentDetailKey::Iota,
117 false,
118 1,
119 KycType::Undefined, )));
121 sdk.active_user = Some(get_active_user());
122 sdk.access_token = Some(TOKEN.clone());
123
124 let exchange_rate_mock_response = example_exchange_rate_response();
126 let body = serde_json::to_string(&exchange_rate_mock_response).unwrap();
127 let get_exchange_rate = srv
128 .mock("GET", "/api/courses?network_key=IOTA")
129 .match_header(HEADER_X_APP_NAME, AUTH_PROVIDER)
130 .match_header("authorization", format!("Bearer {}", TOKEN.as_str()).as_str())
131 .with_status(200)
132 .with_body(&body)
133 .with_header("content-type", "application/json")
134 .with_body(&body)
135 .create();
136
137 let result = sdk.get_exchange_rate().await;
139
140 result.unwrap();
142 get_exchange_rate.assert();
143 }
144
145 fn get_active_user() -> ActiveUser {
147 ActiveUser {
148 username: USERNAME.into(),
149 wallet_manager: Box::new(MockWalletManager::new()),
150 mnemonic_derivation_options: Default::default(),
151 }
152 }
153}