1#![allow(unused_imports)]
15use async_trait::async_trait;
16use derive_builder::Builder;
17use reqwest;
18use rust_decimal::prelude::*;
19use serde::{Deserialize, Serialize};
20use serde_json::{Value, json};
21use std::collections::BTreeMap;
22
23use crate::common::{
24 config::ConfigurationRestApi,
25 models::{ParamBuildError, RestApiResponse},
26 utils::send_request,
27};
28use crate::simple_earn::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait BfusdApi: Send + Sync {
34 async fn get_bfusd_account(
35 &self,
36 params: GetBfusdAccountParams,
37 ) -> anyhow::Result<RestApiResponse<models::GetBfusdAccountResponse>>;
38 async fn get_bfusd_quota_details(
39 &self,
40 params: GetBfusdQuotaDetailsParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetBfusdQuotaDetailsResponse>>;
42 async fn get_bfusd_rate_history(
43 &self,
44 params: GetBfusdRateHistoryParams,
45 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRateHistoryResponse>>;
46 async fn get_bfusd_redemption_history(
47 &self,
48 params: GetBfusdRedemptionHistoryParams,
49 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRedemptionHistoryResponse>>;
50 async fn get_bfusd_rewards_history(
51 &self,
52 params: GetBfusdRewardsHistoryParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRewardsHistoryResponse>>;
54 async fn get_bfusd_subscription_history(
55 &self,
56 params: GetBfusdSubscriptionHistoryParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetBfusdSubscriptionHistoryResponse>>;
58 async fn redeem_bfusd(
59 &self,
60 params: RedeemBfusdParams,
61 ) -> anyhow::Result<RestApiResponse<models::RedeemBfusdResponse>>;
62 async fn subscribe_bfusd(
63 &self,
64 params: SubscribeBfusdParams,
65 ) -> anyhow::Result<RestApiResponse<models::SubscribeBfusdResponse>>;
66}
67
68#[derive(Debug, Clone)]
69pub struct BfusdApiClient {
70 configuration: ConfigurationRestApi,
71}
72
73impl BfusdApiClient {
74 pub fn new(configuration: ConfigurationRestApi) -> Self {
75 Self { configuration }
76 }
77}
78
79#[allow(non_camel_case_types)]
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub enum GetBfusdSubscriptionHistoryAssetEnum {
82 #[serde(rename = "USDC")]
83 Usdc,
84 #[serde(rename = "USDT")]
85 Usdt,
86}
87
88impl GetBfusdSubscriptionHistoryAssetEnum {
89 #[must_use]
90 pub fn as_str(&self) -> &'static str {
91 match self {
92 Self::Usdc => "USDC",
93 Self::Usdt => "USDT",
94 }
95 }
96}
97
98impl std::str::FromStr for GetBfusdSubscriptionHistoryAssetEnum {
99 type Err = Box<dyn std::error::Error + Send + Sync>;
100
101 fn from_str(s: &str) -> Result<Self, Self::Err> {
102 match s {
103 "USDC" => Ok(Self::Usdc),
104 "USDT" => Ok(Self::Usdt),
105 other => Err(format!("invalid GetBfusdSubscriptionHistoryAssetEnum: {}", other).into()),
106 }
107 }
108}
109
110#[allow(non_camel_case_types)]
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub enum RedeemBfusdTypeEnum {
113 #[serde(rename = "FAST")]
114 Fast,
115 #[serde(rename = "STANDARD")]
116 Standard,
117}
118
119impl RedeemBfusdTypeEnum {
120 #[must_use]
121 pub fn as_str(&self) -> &'static str {
122 match self {
123 Self::Fast => "FAST",
124 Self::Standard => "STANDARD",
125 }
126 }
127}
128
129impl std::str::FromStr for RedeemBfusdTypeEnum {
130 type Err = Box<dyn std::error::Error + Send + Sync>;
131
132 fn from_str(s: &str) -> Result<Self, Self::Err> {
133 match s {
134 "FAST" => Ok(Self::Fast),
135 "STANDARD" => Ok(Self::Standard),
136 other => Err(format!("invalid RedeemBfusdTypeEnum: {}", other).into()),
137 }
138 }
139}
140
141#[derive(Clone, Debug, Builder, Deserialize, Default)]
146#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
147pub struct GetBfusdAccountParams {
148 #[builder(setter(into), default)]
153 #[serde(rename = "recvWindow", default)]
154 pub recv_window: Option<i64>,
155}
156
157impl GetBfusdAccountParams {
158 #[must_use]
161 pub fn builder() -> GetBfusdAccountParamsBuilder {
162 GetBfusdAccountParamsBuilder::default()
163 }
164}
165#[derive(Clone, Debug, Builder, Deserialize, Default)]
170#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
171pub struct GetBfusdQuotaDetailsParams {
172 #[builder(setter(into), default)]
177 #[serde(rename = "recvWindow", default)]
178 pub recv_window: Option<i64>,
179}
180
181impl GetBfusdQuotaDetailsParams {
182 #[must_use]
185 pub fn builder() -> GetBfusdQuotaDetailsParamsBuilder {
186 GetBfusdQuotaDetailsParamsBuilder::default()
187 }
188}
189#[derive(Clone, Debug, Builder, Deserialize, Default)]
194#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
195pub struct GetBfusdRateHistoryParams {
196 #[builder(setter(into), default)]
201 #[serde(rename = "startTime", default)]
202 pub start_time: Option<i64>,
203 #[builder(setter(into), default)]
208 #[serde(rename = "endTime", default)]
209 pub end_time: Option<i64>,
210 #[builder(setter(into), default)]
214 #[serde(rename = "current", default)]
215 pub current: Option<i64>,
216 #[builder(setter(into), default)]
220 #[serde(rename = "size", default)]
221 pub size: Option<i64>,
222 #[builder(setter(into), default)]
227 #[serde(rename = "recvWindow", default)]
228 pub recv_window: Option<i64>,
229}
230
231impl GetBfusdRateHistoryParams {
232 #[must_use]
235 pub fn builder() -> GetBfusdRateHistoryParamsBuilder {
236 GetBfusdRateHistoryParamsBuilder::default()
237 }
238}
239#[derive(Clone, Debug, Builder, Deserialize, Default)]
244#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
245pub struct GetBfusdRedemptionHistoryParams {
246 #[builder(setter(into), default)]
251 #[serde(rename = "startTime", default)]
252 pub start_time: Option<i64>,
253 #[builder(setter(into), default)]
258 #[serde(rename = "endTime", default)]
259 pub end_time: Option<i64>,
260 #[builder(setter(into), default)]
264 #[serde(rename = "current", default)]
265 pub current: Option<i64>,
266 #[builder(setter(into), default)]
270 #[serde(rename = "size", default)]
271 pub size: Option<i64>,
272 #[builder(setter(into), default)]
277 #[serde(rename = "recvWindow", default)]
278 pub recv_window: Option<i64>,
279}
280
281impl GetBfusdRedemptionHistoryParams {
282 #[must_use]
285 pub fn builder() -> GetBfusdRedemptionHistoryParamsBuilder {
286 GetBfusdRedemptionHistoryParamsBuilder::default()
287 }
288}
289#[derive(Clone, Debug, Builder, Deserialize, Default)]
294#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
295pub struct GetBfusdRewardsHistoryParams {
296 #[builder(setter(into), default)]
301 #[serde(rename = "startTime", default)]
302 pub start_time: Option<i64>,
303 #[builder(setter(into), default)]
308 #[serde(rename = "endTime", default)]
309 pub end_time: Option<i64>,
310 #[builder(setter(into), default)]
314 #[serde(rename = "current", default)]
315 pub current: Option<i64>,
316 #[builder(setter(into), default)]
320 #[serde(rename = "size", default)]
321 pub size: Option<i64>,
322 #[builder(setter(into), default)]
327 #[serde(rename = "recvWindow", default)]
328 pub recv_window: Option<i64>,
329}
330
331impl GetBfusdRewardsHistoryParams {
332 #[must_use]
335 pub fn builder() -> GetBfusdRewardsHistoryParamsBuilder {
336 GetBfusdRewardsHistoryParamsBuilder::default()
337 }
338}
339#[derive(Clone, Debug, Builder, Deserialize, Default)]
344#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
345pub struct GetBfusdSubscriptionHistoryParams {
346 #[builder(setter(into), default)]
351 #[serde(rename = "asset", default)]
352 pub asset: Option<GetBfusdSubscriptionHistoryAssetEnum>,
353 #[builder(setter(into), default)]
358 #[serde(rename = "startTime", default)]
359 pub start_time: Option<i64>,
360 #[builder(setter(into), default)]
365 #[serde(rename = "endTime", default)]
366 pub end_time: Option<i64>,
367 #[builder(setter(into), default)]
371 #[serde(rename = "current", default)]
372 pub current: Option<i64>,
373 #[builder(setter(into), default)]
377 #[serde(rename = "size", default)]
378 pub size: Option<i64>,
379 #[builder(setter(into), default)]
384 #[serde(rename = "recvWindow", default)]
385 pub recv_window: Option<i64>,
386}
387
388impl GetBfusdSubscriptionHistoryParams {
389 #[must_use]
392 pub fn builder() -> GetBfusdSubscriptionHistoryParamsBuilder {
393 GetBfusdSubscriptionHistoryParamsBuilder::default()
394 }
395}
396#[derive(Clone, Debug, Builder, Deserialize)]
401#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
402pub struct RedeemBfusdParams {
403 #[builder(setter(into))]
407 #[serde(rename = "amount")]
408 pub amount: rust_decimal::Decimal,
409 #[builder(setter(into))]
413 #[serde(rename = "type")]
414 pub r#type: RedeemBfusdTypeEnum,
415 #[builder(setter(into), default)]
419 #[serde(rename = "recvWindow", default)]
420 pub recv_window: Option<i64>,
421}
422
423impl RedeemBfusdParams {
424 #[must_use]
432 pub fn builder(
433 amount: rust_decimal::Decimal,
434 r#type: RedeemBfusdTypeEnum,
435 ) -> RedeemBfusdParamsBuilder {
436 RedeemBfusdParamsBuilder::default()
437 .amount(amount)
438 .r#type(r#type)
439 }
440}
441#[derive(Clone, Debug, Builder, Deserialize)]
446#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
447pub struct SubscribeBfusdParams {
448 #[builder(setter(into))]
453 #[serde(rename = "asset")]
454 pub asset: String,
455 #[builder(setter(into))]
459 #[serde(rename = "amount")]
460 pub amount: rust_decimal::Decimal,
461 #[builder(setter(into), default)]
465 #[serde(rename = "recvWindow", default)]
466 pub recv_window: Option<i64>,
467}
468
469impl SubscribeBfusdParams {
470 #[must_use]
478 pub fn builder(asset: String, amount: rust_decimal::Decimal) -> SubscribeBfusdParamsBuilder {
479 SubscribeBfusdParamsBuilder::default()
480 .asset(asset)
481 .amount(amount)
482 }
483}
484
485#[async_trait]
486impl BfusdApi for BfusdApiClient {
487 async fn get_bfusd_account(
488 &self,
489 params: GetBfusdAccountParams,
490 ) -> anyhow::Result<RestApiResponse<models::GetBfusdAccountResponse>> {
491 let GetBfusdAccountParams { recv_window } = params;
492
493 let mut query_params = BTreeMap::new();
494 let body_params = BTreeMap::new();
495
496 if let Some(rw) = recv_window {
497 query_params.insert("recvWindow".to_string(), json!(rw));
498 }
499
500 send_request::<models::GetBfusdAccountResponse>(
501 &self.configuration,
502 "/sapi/v1/bfusd/account",
503 reqwest::Method::GET,
504 query_params,
505 body_params,
506 if HAS_TIME_UNIT {
507 self.configuration.time_unit
508 } else {
509 None
510 },
511 true,
512 )
513 .await
514 }
515
516 async fn get_bfusd_quota_details(
517 &self,
518 params: GetBfusdQuotaDetailsParams,
519 ) -> anyhow::Result<RestApiResponse<models::GetBfusdQuotaDetailsResponse>> {
520 let GetBfusdQuotaDetailsParams { recv_window } = params;
521
522 let mut query_params = BTreeMap::new();
523 let body_params = BTreeMap::new();
524
525 if let Some(rw) = recv_window {
526 query_params.insert("recvWindow".to_string(), json!(rw));
527 }
528
529 send_request::<models::GetBfusdQuotaDetailsResponse>(
530 &self.configuration,
531 "/sapi/v1/bfusd/quota",
532 reqwest::Method::GET,
533 query_params,
534 body_params,
535 if HAS_TIME_UNIT {
536 self.configuration.time_unit
537 } else {
538 None
539 },
540 true,
541 )
542 .await
543 }
544
545 async fn get_bfusd_rate_history(
546 &self,
547 params: GetBfusdRateHistoryParams,
548 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRateHistoryResponse>> {
549 let GetBfusdRateHistoryParams {
550 start_time,
551 end_time,
552 current,
553 size,
554 recv_window,
555 } = params;
556
557 let mut query_params = BTreeMap::new();
558 let body_params = BTreeMap::new();
559
560 if let Some(rw) = start_time {
561 query_params.insert("startTime".to_string(), json!(rw));
562 }
563
564 if let Some(rw) = end_time {
565 query_params.insert("endTime".to_string(), json!(rw));
566 }
567
568 if let Some(rw) = current {
569 query_params.insert("current".to_string(), json!(rw));
570 }
571
572 if let Some(rw) = size {
573 query_params.insert("size".to_string(), json!(rw));
574 }
575
576 if let Some(rw) = recv_window {
577 query_params.insert("recvWindow".to_string(), json!(rw));
578 }
579
580 send_request::<models::GetBfusdRateHistoryResponse>(
581 &self.configuration,
582 "/sapi/v1/bfusd/history/rateHistory",
583 reqwest::Method::GET,
584 query_params,
585 body_params,
586 if HAS_TIME_UNIT {
587 self.configuration.time_unit
588 } else {
589 None
590 },
591 true,
592 )
593 .await
594 }
595
596 async fn get_bfusd_redemption_history(
597 &self,
598 params: GetBfusdRedemptionHistoryParams,
599 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRedemptionHistoryResponse>> {
600 let GetBfusdRedemptionHistoryParams {
601 start_time,
602 end_time,
603 current,
604 size,
605 recv_window,
606 } = params;
607
608 let mut query_params = BTreeMap::new();
609 let body_params = BTreeMap::new();
610
611 if let Some(rw) = start_time {
612 query_params.insert("startTime".to_string(), json!(rw));
613 }
614
615 if let Some(rw) = end_time {
616 query_params.insert("endTime".to_string(), json!(rw));
617 }
618
619 if let Some(rw) = current {
620 query_params.insert("current".to_string(), json!(rw));
621 }
622
623 if let Some(rw) = size {
624 query_params.insert("size".to_string(), json!(rw));
625 }
626
627 if let Some(rw) = recv_window {
628 query_params.insert("recvWindow".to_string(), json!(rw));
629 }
630
631 send_request::<models::GetBfusdRedemptionHistoryResponse>(
632 &self.configuration,
633 "/sapi/v1/bfusd/history/redemptionHistory",
634 reqwest::Method::GET,
635 query_params,
636 body_params,
637 if HAS_TIME_UNIT {
638 self.configuration.time_unit
639 } else {
640 None
641 },
642 true,
643 )
644 .await
645 }
646
647 async fn get_bfusd_rewards_history(
648 &self,
649 params: GetBfusdRewardsHistoryParams,
650 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRewardsHistoryResponse>> {
651 let GetBfusdRewardsHistoryParams {
652 start_time,
653 end_time,
654 current,
655 size,
656 recv_window,
657 } = params;
658
659 let mut query_params = BTreeMap::new();
660 let body_params = BTreeMap::new();
661
662 if let Some(rw) = start_time {
663 query_params.insert("startTime".to_string(), json!(rw));
664 }
665
666 if let Some(rw) = end_time {
667 query_params.insert("endTime".to_string(), json!(rw));
668 }
669
670 if let Some(rw) = current {
671 query_params.insert("current".to_string(), json!(rw));
672 }
673
674 if let Some(rw) = size {
675 query_params.insert("size".to_string(), json!(rw));
676 }
677
678 if let Some(rw) = recv_window {
679 query_params.insert("recvWindow".to_string(), json!(rw));
680 }
681
682 send_request::<models::GetBfusdRewardsHistoryResponse>(
683 &self.configuration,
684 "/sapi/v1/bfusd/history/rewardsHistory",
685 reqwest::Method::GET,
686 query_params,
687 body_params,
688 if HAS_TIME_UNIT {
689 self.configuration.time_unit
690 } else {
691 None
692 },
693 true,
694 )
695 .await
696 }
697
698 async fn get_bfusd_subscription_history(
699 &self,
700 params: GetBfusdSubscriptionHistoryParams,
701 ) -> anyhow::Result<RestApiResponse<models::GetBfusdSubscriptionHistoryResponse>> {
702 let GetBfusdSubscriptionHistoryParams {
703 asset,
704 start_time,
705 end_time,
706 current,
707 size,
708 recv_window,
709 } = params;
710
711 let mut query_params = BTreeMap::new();
712 let body_params = BTreeMap::new();
713
714 if let Some(rw) = asset {
715 query_params.insert("asset".to_string(), json!(rw));
716 }
717
718 if let Some(rw) = start_time {
719 query_params.insert("startTime".to_string(), json!(rw));
720 }
721
722 if let Some(rw) = end_time {
723 query_params.insert("endTime".to_string(), json!(rw));
724 }
725
726 if let Some(rw) = current {
727 query_params.insert("current".to_string(), json!(rw));
728 }
729
730 if let Some(rw) = size {
731 query_params.insert("size".to_string(), json!(rw));
732 }
733
734 if let Some(rw) = recv_window {
735 query_params.insert("recvWindow".to_string(), json!(rw));
736 }
737
738 send_request::<models::GetBfusdSubscriptionHistoryResponse>(
739 &self.configuration,
740 "/sapi/v1/bfusd/history/subscriptionHistory",
741 reqwest::Method::GET,
742 query_params,
743 body_params,
744 if HAS_TIME_UNIT {
745 self.configuration.time_unit
746 } else {
747 None
748 },
749 true,
750 )
751 .await
752 }
753
754 async fn redeem_bfusd(
755 &self,
756 params: RedeemBfusdParams,
757 ) -> anyhow::Result<RestApiResponse<models::RedeemBfusdResponse>> {
758 let RedeemBfusdParams {
759 amount,
760 r#type,
761 recv_window,
762 } = params;
763
764 let mut query_params = BTreeMap::new();
765 let body_params = BTreeMap::new();
766
767 query_params.insert("amount".to_string(), json!(amount));
768
769 query_params.insert("type".to_string(), json!(r#type));
770
771 if let Some(rw) = recv_window {
772 query_params.insert("recvWindow".to_string(), json!(rw));
773 }
774
775 send_request::<models::RedeemBfusdResponse>(
776 &self.configuration,
777 "/sapi/v1/bfusd/redeem",
778 reqwest::Method::POST,
779 query_params,
780 body_params,
781 if HAS_TIME_UNIT {
782 self.configuration.time_unit
783 } else {
784 None
785 },
786 true,
787 )
788 .await
789 }
790
791 async fn subscribe_bfusd(
792 &self,
793 params: SubscribeBfusdParams,
794 ) -> anyhow::Result<RestApiResponse<models::SubscribeBfusdResponse>> {
795 let SubscribeBfusdParams {
796 asset,
797 amount,
798 recv_window,
799 } = params;
800
801 let mut query_params = BTreeMap::new();
802 let body_params = BTreeMap::new();
803
804 query_params.insert("asset".to_string(), json!(asset));
805
806 query_params.insert("amount".to_string(), json!(amount));
807
808 if let Some(rw) = recv_window {
809 query_params.insert("recvWindow".to_string(), json!(rw));
810 }
811
812 send_request::<models::SubscribeBfusdResponse>(
813 &self.configuration,
814 "/sapi/v1/bfusd/subscribe",
815 reqwest::Method::POST,
816 query_params,
817 body_params,
818 if HAS_TIME_UNIT {
819 self.configuration.time_unit
820 } else {
821 None
822 },
823 true,
824 )
825 .await
826 }
827}
828
829#[cfg(all(test, feature = "simple_earn"))]
830mod tests {
831 use super::*;
832 use crate::TOKIO_SHARED_RT;
833 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
834 use async_trait::async_trait;
835 use std::collections::HashMap;
836
837 struct DummyRestApiResponse<T> {
838 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
839 status: u16,
840 headers: HashMap<String, String>,
841 rate_limits: Option<Vec<RestApiRateLimit>>,
842 }
843
844 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
845 fn from(dummy: DummyRestApiResponse<T>) -> Self {
846 Self {
847 data_fn: dummy.inner,
848 status: dummy.status,
849 headers: dummy.headers,
850 rate_limits: dummy.rate_limits,
851 }
852 }
853 }
854
855 struct MockBfusdApiClient {
856 force_error: bool,
857 }
858
859 #[async_trait]
860 impl BfusdApi for MockBfusdApiClient {
861 async fn get_bfusd_account(
862 &self,
863 _params: GetBfusdAccountParams,
864 ) -> anyhow::Result<RestApiResponse<models::GetBfusdAccountResponse>> {
865 if self.force_error {
866 return Err(ConnectorError::ConnectorClientError {
867 msg: "ResponseError".to_string(),
868 code: None,
869 }
870 .into());
871 }
872
873 let resp_json: Value = serde_json::from_str(
874 r#"{"bfusdAmount":"100","usdtProfit":"11.00","bfusdProfit":"1.81"}"#,
875 )
876 .unwrap_or_else(|_| serde_json::json!({}));
877 let dummy_response: models::GetBfusdAccountResponse =
878 serde_json::from_value(resp_json.clone())
879 .expect("should parse into models::GetBfusdAccountResponse");
880
881 let dummy = DummyRestApiResponse {
882 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
883 status: 200,
884 headers: HashMap::new(),
885 rate_limits: None,
886 };
887
888 Ok(dummy.into())
889 }
890
891 async fn get_bfusd_quota_details(
892 &self,
893 _params: GetBfusdQuotaDetailsParams,
894 ) -> anyhow::Result<RestApiResponse<models::GetBfusdQuotaDetailsResponse>> {
895 if self.force_error {
896 return Err(ConnectorError::ConnectorClientError {
897 msg: "ResponseError".to_string(),
898 code: None,
899 }
900 .into());
901 }
902
903 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"leftQuota":"1000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","redeemPeriod":3}}"#).unwrap_or_else(|_| serde_json::json!({}));
904 let dummy_response: models::GetBfusdQuotaDetailsResponse =
905 serde_json::from_value(resp_json.clone())
906 .expect("should parse into models::GetBfusdQuotaDetailsResponse");
907
908 let dummy = DummyRestApiResponse {
909 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
910 status: 200,
911 headers: HashMap::new(),
912 rate_limits: None,
913 };
914
915 Ok(dummy.into())
916 }
917
918 async fn get_bfusd_rate_history(
919 &self,
920 _params: GetBfusdRateHistoryParams,
921 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRateHistoryResponse>> {
922 if self.force_error {
923 return Err(ConnectorError::ConnectorClientError {
924 msg: "ResponseError".to_string(),
925 code: None,
926 }
927 .into());
928 }
929
930 let resp_json: Value = serde_json::from_str(
931 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
932 )
933 .unwrap_or_else(|_| serde_json::json!({}));
934 let dummy_response: models::GetBfusdRateHistoryResponse =
935 serde_json::from_value(resp_json.clone())
936 .expect("should parse into models::GetBfusdRateHistoryResponse");
937
938 let dummy = DummyRestApiResponse {
939 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
940 status: 200,
941 headers: HashMap::new(),
942 rate_limits: None,
943 };
944
945 Ok(dummy.into())
946 }
947
948 async fn get_bfusd_redemption_history(
949 &self,
950 _params: GetBfusdRedemptionHistoryParams,
951 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRedemptionHistoryResponse>> {
952 if self.force_error {
953 return Err(ConnectorError::ConnectorClientError {
954 msg: "ResponseError".to_string(),
955 code: None,
956 }
957 .into());
958 }
959
960 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"BFUSD","amount":"51","receiveAsset":"USDT","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
961 let dummy_response: models::GetBfusdRedemptionHistoryResponse =
962 serde_json::from_value(resp_json.clone())
963 .expect("should parse into models::GetBfusdRedemptionHistoryResponse");
964
965 let dummy = DummyRestApiResponse {
966 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
967 status: 200,
968 headers: HashMap::new(),
969 rate_limits: None,
970 };
971
972 Ok(dummy.into())
973 }
974
975 async fn get_bfusd_rewards_history(
976 &self,
977 _params: GetBfusdRewardsHistoryParams,
978 ) -> anyhow::Result<RestApiResponse<models::GetBfusdRewardsHistoryResponse>> {
979 if self.force_error {
980 return Err(ConnectorError::ConnectorClientError {
981 msg: "ResponseError".to_string(),
982 code: None,
983 }
984 .into());
985 }
986
987 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardAsset":"BFUSD","rewardsAmount":"1","BFUSDPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
988 let dummy_response: models::GetBfusdRewardsHistoryResponse =
989 serde_json::from_value(resp_json.clone())
990 .expect("should parse into models::GetBfusdRewardsHistoryResponse");
991
992 let dummy = DummyRestApiResponse {
993 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
994 status: 200,
995 headers: HashMap::new(),
996 rate_limits: None,
997 };
998
999 Ok(dummy.into())
1000 }
1001
1002 async fn get_bfusd_subscription_history(
1003 &self,
1004 _params: GetBfusdSubscriptionHistoryParams,
1005 ) -> anyhow::Result<RestApiResponse<models::GetBfusdSubscriptionHistoryResponse>> {
1006 if self.force_error {
1007 return Err(ConnectorError::ConnectorClientError {
1008 msg: "ResponseError".to_string(),
1009 code: None,
1010 }
1011 .into());
1012 }
1013
1014 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDT","amount":"100","receiveAsset":"BFUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1015 let dummy_response: models::GetBfusdSubscriptionHistoryResponse =
1016 serde_json::from_value(resp_json.clone())
1017 .expect("should parse into models::GetBfusdSubscriptionHistoryResponse");
1018
1019 let dummy = DummyRestApiResponse {
1020 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1021 status: 200,
1022 headers: HashMap::new(),
1023 rate_limits: None,
1024 };
1025
1026 Ok(dummy.into())
1027 }
1028
1029 async fn redeem_bfusd(
1030 &self,
1031 _params: RedeemBfusdParams,
1032 ) -> anyhow::Result<RestApiResponse<models::RedeemBfusdResponse>> {
1033 if self.force_error {
1034 return Err(ConnectorError::ConnectorClientError {
1035 msg: "ResponseError".to_string(),
1036 code: None,
1037 }
1038 .into());
1039 }
1040
1041 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap_or_else(|_| serde_json::json!({}));
1042 let dummy_response: models::RedeemBfusdResponse =
1043 serde_json::from_value(resp_json.clone())
1044 .expect("should parse into models::RedeemBfusdResponse");
1045
1046 let dummy = DummyRestApiResponse {
1047 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1048 status: 200,
1049 headers: HashMap::new(),
1050 rate_limits: None,
1051 };
1052
1053 Ok(dummy.into())
1054 }
1055
1056 async fn subscribe_bfusd(
1057 &self,
1058 _params: SubscribeBfusdParams,
1059 ) -> anyhow::Result<RestApiResponse<models::SubscribeBfusdResponse>> {
1060 if self.force_error {
1061 return Err(ConnectorError::ConnectorClientError {
1062 msg: "ResponseError".to_string(),
1063 code: None,
1064 }
1065 .into());
1066 }
1067
1068 let resp_json: Value =
1069 serde_json::from_str(r#"{"success":true,"bfusdAmount":"0.22091092"}"#)
1070 .unwrap_or_else(|_| serde_json::json!({}));
1071 let dummy_response: models::SubscribeBfusdResponse =
1072 serde_json::from_value(resp_json.clone())
1073 .expect("should parse into models::SubscribeBfusdResponse");
1074
1075 let dummy = DummyRestApiResponse {
1076 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1077 status: 200,
1078 headers: HashMap::new(),
1079 rate_limits: None,
1080 };
1081
1082 Ok(dummy.into())
1083 }
1084 }
1085
1086 #[test]
1087 fn get_bfusd_account_required_params_success() {
1088 TOKIO_SHARED_RT.block_on(async {
1089 let client = MockBfusdApiClient { force_error: false };
1090
1091 let params = GetBfusdAccountParams::builder().build().unwrap();
1092
1093 let resp_json: Value = serde_json::from_str(
1094 r#"{"bfusdAmount":"100","usdtProfit":"11.00","bfusdProfit":"1.81"}"#,
1095 )
1096 .unwrap_or_else(|_| serde_json::json!({}));
1097 let expected_response: models::GetBfusdAccountResponse =
1098 serde_json::from_value(resp_json.clone())
1099 .expect("should parse into models::GetBfusdAccountResponse");
1100
1101 let resp = client
1102 .get_bfusd_account(params)
1103 .await
1104 .expect("Expected a response");
1105 let data_future = resp.data();
1106 let actual_response = data_future.await.unwrap();
1107 assert_eq!(actual_response, expected_response);
1108 });
1109 }
1110
1111 #[test]
1112 fn get_bfusd_account_optional_params_success() {
1113 TOKIO_SHARED_RT.block_on(async {
1114 let client = MockBfusdApiClient { force_error: false };
1115
1116 let params = GetBfusdAccountParams::builder()
1117 .recv_window(5000)
1118 .build()
1119 .unwrap();
1120
1121 let resp_json: Value = serde_json::from_str(
1122 r#"{"bfusdAmount":"100","usdtProfit":"11.00","bfusdProfit":"1.81"}"#,
1123 )
1124 .unwrap_or_else(|_| serde_json::json!({}));
1125 let expected_response: models::GetBfusdAccountResponse =
1126 serde_json::from_value(resp_json.clone())
1127 .expect("should parse into models::GetBfusdAccountResponse");
1128
1129 let resp = client
1130 .get_bfusd_account(params)
1131 .await
1132 .expect("Expected a response");
1133 let data_future = resp.data();
1134 let actual_response = data_future.await.unwrap();
1135 assert_eq!(actual_response, expected_response);
1136 });
1137 }
1138
1139 #[test]
1140 fn get_bfusd_account_response_error() {
1141 TOKIO_SHARED_RT.block_on(async {
1142 let client = MockBfusdApiClient { force_error: true };
1143
1144 let params = GetBfusdAccountParams::builder().build().unwrap();
1145
1146 match client.get_bfusd_account(params).await {
1147 Ok(_) => panic!("Expected an error"),
1148 Err(err) => {
1149 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1150 }
1151 }
1152 });
1153 }
1154
1155 #[test]
1156 fn get_bfusd_quota_details_required_params_success() {
1157 TOKIO_SHARED_RT.block_on(async {
1158 let client = MockBfusdApiClient { force_error: false };
1159
1160 let params = GetBfusdQuotaDetailsParams::builder().build().unwrap();
1161
1162 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"leftQuota":"1000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","redeemPeriod":3}}"#).unwrap_or_else(|_| serde_json::json!({}));
1163 let expected_response : models::GetBfusdQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdQuotaDetailsResponse");
1164
1165 let resp = client.get_bfusd_quota_details(params).await.expect("Expected a response");
1166 let data_future = resp.data();
1167 let actual_response = data_future.await.unwrap();
1168 assert_eq!(actual_response, expected_response);
1169 });
1170 }
1171
1172 #[test]
1173 fn get_bfusd_quota_details_optional_params_success() {
1174 TOKIO_SHARED_RT.block_on(async {
1175 let client = MockBfusdApiClient { force_error: false };
1176
1177 let params = GetBfusdQuotaDetailsParams::builder().recv_window(5000).build().unwrap();
1178
1179 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"leftQuota":"1000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","redeemPeriod":3}}"#).unwrap_or_else(|_| serde_json::json!({}));
1180 let expected_response : models::GetBfusdQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdQuotaDetailsResponse");
1181
1182 let resp = client.get_bfusd_quota_details(params).await.expect("Expected a response");
1183 let data_future = resp.data();
1184 let actual_response = data_future.await.unwrap();
1185 assert_eq!(actual_response, expected_response);
1186 });
1187 }
1188
1189 #[test]
1190 fn get_bfusd_quota_details_response_error() {
1191 TOKIO_SHARED_RT.block_on(async {
1192 let client = MockBfusdApiClient { force_error: true };
1193
1194 let params = GetBfusdQuotaDetailsParams::builder().build().unwrap();
1195
1196 match client.get_bfusd_quota_details(params).await {
1197 Ok(_) => panic!("Expected an error"),
1198 Err(err) => {
1199 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1200 }
1201 }
1202 });
1203 }
1204
1205 #[test]
1206 fn get_bfusd_rate_history_required_params_success() {
1207 TOKIO_SHARED_RT.block_on(async {
1208 let client = MockBfusdApiClient { force_error: false };
1209
1210 let params = GetBfusdRateHistoryParams::builder().build().unwrap();
1211
1212 let resp_json: Value = serde_json::from_str(
1213 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
1214 )
1215 .unwrap_or_else(|_| serde_json::json!({}));
1216 let expected_response: models::GetBfusdRateHistoryResponse =
1217 serde_json::from_value(resp_json.clone())
1218 .expect("should parse into models::GetBfusdRateHistoryResponse");
1219
1220 let resp = client
1221 .get_bfusd_rate_history(params)
1222 .await
1223 .expect("Expected a response");
1224 let data_future = resp.data();
1225 let actual_response = data_future.await.unwrap();
1226 assert_eq!(actual_response, expected_response);
1227 });
1228 }
1229
1230 #[test]
1231 fn get_bfusd_rate_history_optional_params_success() {
1232 TOKIO_SHARED_RT.block_on(async {
1233 let client = MockBfusdApiClient { force_error: false };
1234
1235 let params = GetBfusdRateHistoryParams::builder()
1236 .start_time(1623319461670)
1237 .end_time(1641782889000)
1238 .current(1)
1239 .size(10)
1240 .recv_window(5000)
1241 .build()
1242 .unwrap();
1243
1244 let resp_json: Value = serde_json::from_str(
1245 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
1246 )
1247 .unwrap_or_else(|_| serde_json::json!({}));
1248 let expected_response: models::GetBfusdRateHistoryResponse =
1249 serde_json::from_value(resp_json.clone())
1250 .expect("should parse into models::GetBfusdRateHistoryResponse");
1251
1252 let resp = client
1253 .get_bfusd_rate_history(params)
1254 .await
1255 .expect("Expected a response");
1256 let data_future = resp.data();
1257 let actual_response = data_future.await.unwrap();
1258 assert_eq!(actual_response, expected_response);
1259 });
1260 }
1261
1262 #[test]
1263 fn get_bfusd_rate_history_response_error() {
1264 TOKIO_SHARED_RT.block_on(async {
1265 let client = MockBfusdApiClient { force_error: true };
1266
1267 let params = GetBfusdRateHistoryParams::builder().build().unwrap();
1268
1269 match client.get_bfusd_rate_history(params).await {
1270 Ok(_) => panic!("Expected an error"),
1271 Err(err) => {
1272 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1273 }
1274 }
1275 });
1276 }
1277
1278 #[test]
1279 fn get_bfusd_redemption_history_required_params_success() {
1280 TOKIO_SHARED_RT.block_on(async {
1281 let client = MockBfusdApiClient { force_error: false };
1282
1283 let params = GetBfusdRedemptionHistoryParams::builder().build().unwrap();
1284
1285 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"BFUSD","amount":"51","receiveAsset":"USDT","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1286 let expected_response : models::GetBfusdRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdRedemptionHistoryResponse");
1287
1288 let resp = client.get_bfusd_redemption_history(params).await.expect("Expected a response");
1289 let data_future = resp.data();
1290 let actual_response = data_future.await.unwrap();
1291 assert_eq!(actual_response, expected_response);
1292 });
1293 }
1294
1295 #[test]
1296 fn get_bfusd_redemption_history_optional_params_success() {
1297 TOKIO_SHARED_RT.block_on(async {
1298 let client = MockBfusdApiClient { force_error: false };
1299
1300 let params = GetBfusdRedemptionHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1301
1302 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"BFUSD","amount":"51","receiveAsset":"USDT","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1303 let expected_response : models::GetBfusdRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdRedemptionHistoryResponse");
1304
1305 let resp = client.get_bfusd_redemption_history(params).await.expect("Expected a response");
1306 let data_future = resp.data();
1307 let actual_response = data_future.await.unwrap();
1308 assert_eq!(actual_response, expected_response);
1309 });
1310 }
1311
1312 #[test]
1313 fn get_bfusd_redemption_history_response_error() {
1314 TOKIO_SHARED_RT.block_on(async {
1315 let client = MockBfusdApiClient { force_error: true };
1316
1317 let params = GetBfusdRedemptionHistoryParams::builder().build().unwrap();
1318
1319 match client.get_bfusd_redemption_history(params).await {
1320 Ok(_) => panic!("Expected an error"),
1321 Err(err) => {
1322 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1323 }
1324 }
1325 });
1326 }
1327
1328 #[test]
1329 fn get_bfusd_rewards_history_required_params_success() {
1330 TOKIO_SHARED_RT.block_on(async {
1331 let client = MockBfusdApiClient { force_error: false };
1332
1333 let params = GetBfusdRewardsHistoryParams::builder().build().unwrap();
1334
1335 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardAsset":"BFUSD","rewardsAmount":"1","BFUSDPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1336 let expected_response : models::GetBfusdRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdRewardsHistoryResponse");
1337
1338 let resp = client.get_bfusd_rewards_history(params).await.expect("Expected a response");
1339 let data_future = resp.data();
1340 let actual_response = data_future.await.unwrap();
1341 assert_eq!(actual_response, expected_response);
1342 });
1343 }
1344
1345 #[test]
1346 fn get_bfusd_rewards_history_optional_params_success() {
1347 TOKIO_SHARED_RT.block_on(async {
1348 let client = MockBfusdApiClient { force_error: false };
1349
1350 let params = GetBfusdRewardsHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1351
1352 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardAsset":"BFUSD","rewardsAmount":"1","BFUSDPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1353 let expected_response : models::GetBfusdRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdRewardsHistoryResponse");
1354
1355 let resp = client.get_bfusd_rewards_history(params).await.expect("Expected a response");
1356 let data_future = resp.data();
1357 let actual_response = data_future.await.unwrap();
1358 assert_eq!(actual_response, expected_response);
1359 });
1360 }
1361
1362 #[test]
1363 fn get_bfusd_rewards_history_response_error() {
1364 TOKIO_SHARED_RT.block_on(async {
1365 let client = MockBfusdApiClient { force_error: true };
1366
1367 let params = GetBfusdRewardsHistoryParams::builder().build().unwrap();
1368
1369 match client.get_bfusd_rewards_history(params).await {
1370 Ok(_) => panic!("Expected an error"),
1371 Err(err) => {
1372 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1373 }
1374 }
1375 });
1376 }
1377
1378 #[test]
1379 fn get_bfusd_subscription_history_required_params_success() {
1380 TOKIO_SHARED_RT.block_on(async {
1381 let client = MockBfusdApiClient { force_error: false };
1382
1383 let params = GetBfusdSubscriptionHistoryParams::builder().build().unwrap();
1384
1385 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDT","amount":"100","receiveAsset":"BFUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1386 let expected_response : models::GetBfusdSubscriptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdSubscriptionHistoryResponse");
1387
1388 let resp = client.get_bfusd_subscription_history(params).await.expect("Expected a response");
1389 let data_future = resp.data();
1390 let actual_response = data_future.await.unwrap();
1391 assert_eq!(actual_response, expected_response);
1392 });
1393 }
1394
1395 #[test]
1396 fn get_bfusd_subscription_history_optional_params_success() {
1397 TOKIO_SHARED_RT.block_on(async {
1398 let client = MockBfusdApiClient { force_error: false };
1399
1400 let params = GetBfusdSubscriptionHistoryParams::builder().asset(GetBfusdSubscriptionHistoryAssetEnum::Usdc).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1401
1402 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDT","amount":"100","receiveAsset":"BFUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1403 let expected_response : models::GetBfusdSubscriptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBfusdSubscriptionHistoryResponse");
1404
1405 let resp = client.get_bfusd_subscription_history(params).await.expect("Expected a response");
1406 let data_future = resp.data();
1407 let actual_response = data_future.await.unwrap();
1408 assert_eq!(actual_response, expected_response);
1409 });
1410 }
1411
1412 #[test]
1413 fn get_bfusd_subscription_history_response_error() {
1414 TOKIO_SHARED_RT.block_on(async {
1415 let client = MockBfusdApiClient { force_error: true };
1416
1417 let params = GetBfusdSubscriptionHistoryParams::builder()
1418 .build()
1419 .unwrap();
1420
1421 match client.get_bfusd_subscription_history(params).await {
1422 Ok(_) => panic!("Expected an error"),
1423 Err(err) => {
1424 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1425 }
1426 }
1427 });
1428 }
1429
1430 #[test]
1431 fn redeem_bfusd_required_params_success() {
1432 TOKIO_SHARED_RT.block_on(async {
1433 let client = MockBfusdApiClient { force_error: false };
1434
1435 let params = RedeemBfusdParams::builder(dec!(1.0),RedeemBfusdTypeEnum::Fast,).build().unwrap();
1436
1437 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap_or_else(|_| serde_json::json!({}));
1438 let expected_response : models::RedeemBfusdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemBfusdResponse");
1439
1440 let resp = client.redeem_bfusd(params).await.expect("Expected a response");
1441 let data_future = resp.data();
1442 let actual_response = data_future.await.unwrap();
1443 assert_eq!(actual_response, expected_response);
1444 });
1445 }
1446
1447 #[test]
1448 fn redeem_bfusd_optional_params_success() {
1449 TOKIO_SHARED_RT.block_on(async {
1450 let client = MockBfusdApiClient { force_error: false };
1451
1452 let params = RedeemBfusdParams::builder(dec!(1.0),RedeemBfusdTypeEnum::Fast,).recv_window(5000).build().unwrap();
1453
1454 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap_or_else(|_| serde_json::json!({}));
1455 let expected_response : models::RedeemBfusdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemBfusdResponse");
1456
1457 let resp = client.redeem_bfusd(params).await.expect("Expected a response");
1458 let data_future = resp.data();
1459 let actual_response = data_future.await.unwrap();
1460 assert_eq!(actual_response, expected_response);
1461 });
1462 }
1463
1464 #[test]
1465 fn redeem_bfusd_response_error() {
1466 TOKIO_SHARED_RT.block_on(async {
1467 let client = MockBfusdApiClient { force_error: true };
1468
1469 let params = RedeemBfusdParams::builder(dec!(1.0), RedeemBfusdTypeEnum::Fast)
1470 .build()
1471 .unwrap();
1472
1473 match client.redeem_bfusd(params).await {
1474 Ok(_) => panic!("Expected an error"),
1475 Err(err) => {
1476 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1477 }
1478 }
1479 });
1480 }
1481
1482 #[test]
1483 fn subscribe_bfusd_required_params_success() {
1484 TOKIO_SHARED_RT.block_on(async {
1485 let client = MockBfusdApiClient { force_error: false };
1486
1487 let params = SubscribeBfusdParams::builder("USDT".to_string(), dec!(1.0))
1488 .build()
1489 .unwrap();
1490
1491 let resp_json: Value =
1492 serde_json::from_str(r#"{"success":true,"bfusdAmount":"0.22091092"}"#)
1493 .unwrap_or_else(|_| serde_json::json!({}));
1494 let expected_response: models::SubscribeBfusdResponse =
1495 serde_json::from_value(resp_json.clone())
1496 .expect("should parse into models::SubscribeBfusdResponse");
1497
1498 let resp = client
1499 .subscribe_bfusd(params)
1500 .await
1501 .expect("Expected a response");
1502 let data_future = resp.data();
1503 let actual_response = data_future.await.unwrap();
1504 assert_eq!(actual_response, expected_response);
1505 });
1506 }
1507
1508 #[test]
1509 fn subscribe_bfusd_optional_params_success() {
1510 TOKIO_SHARED_RT.block_on(async {
1511 let client = MockBfusdApiClient { force_error: false };
1512
1513 let params = SubscribeBfusdParams::builder("USDT".to_string(), dec!(1.0))
1514 .recv_window(5000)
1515 .build()
1516 .unwrap();
1517
1518 let resp_json: Value =
1519 serde_json::from_str(r#"{"success":true,"bfusdAmount":"0.22091092"}"#)
1520 .unwrap_or_else(|_| serde_json::json!({}));
1521 let expected_response: models::SubscribeBfusdResponse =
1522 serde_json::from_value(resp_json.clone())
1523 .expect("should parse into models::SubscribeBfusdResponse");
1524
1525 let resp = client
1526 .subscribe_bfusd(params)
1527 .await
1528 .expect("Expected a response");
1529 let data_future = resp.data();
1530 let actual_response = data_future.await.unwrap();
1531 assert_eq!(actual_response, expected_response);
1532 });
1533 }
1534
1535 #[test]
1536 fn subscribe_bfusd_response_error() {
1537 TOKIO_SHARED_RT.block_on(async {
1538 let client = MockBfusdApiClient { force_error: true };
1539
1540 let params = SubscribeBfusdParams::builder("USDT".to_string(), dec!(1.0))
1541 .build()
1542 .unwrap();
1543
1544 match client.subscribe_bfusd(params).await {
1545 Ok(_) => panic!("Expected an error"),
1546 Err(err) => {
1547 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1548 }
1549 }
1550 });
1551 }
1552}