Skip to main content

binance_sdk/vip_loan/rest_api/apis/
user_information_api.rs

1/*
2 * VIP Loan REST API
3 *
4 * Access over-collateralized loan services, manage positions, and monitor collateral via the VIP Loan API.
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![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::vip_loan::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait UserInformationApi: Send + Sync {
34    async fn check_vip_loan_collateral_account(
35        &self,
36        params: CheckVipLoanCollateralAccountParams,
37    ) -> anyhow::Result<RestApiResponse<models::CheckVipLoanCollateralAccountResponse>>;
38    async fn get_vip_loan_accrued_interest(
39        &self,
40        params: GetVipLoanAccruedInterestParams,
41    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanAccruedInterestResponse>>;
42    async fn get_vip_loan_ongoing_orders(
43        &self,
44        params: GetVipLoanOngoingOrdersParams,
45    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanOngoingOrdersResponse>>;
46    async fn get_vip_loan_repayment_history(
47        &self,
48        params: GetVipLoanRepaymentHistoryParams,
49    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanRepaymentHistoryResponse>>;
50    async fn query_application_status(
51        &self,
52        params: QueryApplicationStatusParams,
53    ) -> anyhow::Result<RestApiResponse<models::QueryApplicationStatusResponse>>;
54}
55
56#[derive(Debug, Clone)]
57pub struct UserInformationApiClient {
58    configuration: ConfigurationRestApi,
59}
60
61impl UserInformationApiClient {
62    pub fn new(configuration: ConfigurationRestApi) -> Self {
63        Self { configuration }
64    }
65}
66
67/// Request parameters for the [`check_vip_loan_collateral_account`] operation.
68///
69/// This struct holds all of the inputs you can pass when calling
70/// [`check_vip_loan_collateral_account`](#method.check_vip_loan_collateral_account).
71#[derive(Clone, Debug, Builder, Deserialize, Default)]
72#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
73pub struct CheckVipLoanCollateralAccountParams {
74    ///
75    /// The `order_id` parameter.
76    ///
77    /// This field is **optional.
78    #[builder(setter(into), default)]
79    #[serde(rename = "orderId", default)]
80    pub order_id: Option<i64>,
81    ///
82    /// The `collateral_account_id` parameter.
83    ///
84    /// This field is **optional.
85    #[builder(setter(into), default)]
86    #[serde(rename = "collateralAccountId", default)]
87    pub collateral_account_id: Option<i64>,
88    ///
89    /// The `recv_window` parameter.
90    ///
91    /// This field is **optional.
92    #[builder(setter(into), default)]
93    #[serde(rename = "recvWindow", default)]
94    pub recv_window: Option<i64>,
95}
96
97impl CheckVipLoanCollateralAccountParams {
98    /// Create a builder for [`check_vip_loan_collateral_account`].
99    ///
100    #[must_use]
101    pub fn builder() -> CheckVipLoanCollateralAccountParamsBuilder {
102        CheckVipLoanCollateralAccountParamsBuilder::default()
103    }
104}
105/// Request parameters for the [`get_vip_loan_accrued_interest`] operation.
106///
107/// This struct holds all of the inputs you can pass when calling
108/// [`get_vip_loan_accrued_interest`](#method.get_vip_loan_accrued_interest).
109#[derive(Clone, Debug, Builder, Deserialize, Default)]
110#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
111pub struct GetVipLoanAccruedInterestParams {
112    ///
113    /// The `order_id` parameter.
114    ///
115    /// This field is **optional.
116    #[builder(setter(into), default)]
117    #[serde(rename = "orderId", default)]
118    pub order_id: Option<i64>,
119    ///
120    /// The `loan_coin` parameter.
121    ///
122    /// This field is **optional.
123    #[builder(setter(into), default)]
124    #[serde(rename = "loanCoin", default)]
125    pub loan_coin: Option<String>,
126    /// If both startTime and endTime are omitted, the most recent 90 days are returned.
127    ///
128    /// This field is **optional.
129    #[builder(setter(into), default)]
130    #[serde(rename = "startTime", default)]
131    pub start_time: Option<i64>,
132    /// Maximum interval between startTime and endTime is 90 days.
133    ///
134    /// This field is **optional.
135    #[builder(setter(into), default)]
136    #[serde(rename = "endTime", default)]
137    pub end_time: Option<i64>,
138    /// Current page number, starting from 1.
139    ///
140    /// This field is **optional.
141    #[builder(setter(into), default)]
142    #[serde(rename = "current", default)]
143    pub current: Option<i64>,
144    /// Number of records per page.
145    ///
146    /// This field is **optional.
147    #[builder(setter(into), default)]
148    #[serde(rename = "limit", default)]
149    pub limit: Option<i64>,
150    ///
151    /// The `recv_window` parameter.
152    ///
153    /// This field is **optional.
154    #[builder(setter(into), default)]
155    #[serde(rename = "recvWindow", default)]
156    pub recv_window: Option<i64>,
157}
158
159impl GetVipLoanAccruedInterestParams {
160    /// Create a builder for [`get_vip_loan_accrued_interest`].
161    ///
162    #[must_use]
163    pub fn builder() -> GetVipLoanAccruedInterestParamsBuilder {
164        GetVipLoanAccruedInterestParamsBuilder::default()
165    }
166}
167/// Request parameters for the [`get_vip_loan_ongoing_orders`] operation.
168///
169/// This struct holds all of the inputs you can pass when calling
170/// [`get_vip_loan_ongoing_orders`](#method.get_vip_loan_ongoing_orders).
171#[derive(Clone, Debug, Builder, Deserialize, Default)]
172#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
173pub struct GetVipLoanOngoingOrdersParams {
174    ///
175    /// The `order_id` parameter.
176    ///
177    /// This field is **optional.
178    #[builder(setter(into), default)]
179    #[serde(rename = "orderId", default)]
180    pub order_id: Option<i64>,
181    ///
182    /// The `collateral_account_id` parameter.
183    ///
184    /// This field is **optional.
185    #[builder(setter(into), default)]
186    #[serde(rename = "collateralAccountId", default)]
187    pub collateral_account_id: Option<i64>,
188    ///
189    /// The `loan_coin` parameter.
190    ///
191    /// This field is **optional.
192    #[builder(setter(into), default)]
193    #[serde(rename = "loanCoin", default)]
194    pub loan_coin: Option<String>,
195    ///
196    /// The `collateral_coin` parameter.
197    ///
198    /// This field is **optional.
199    #[builder(setter(into), default)]
200    #[serde(rename = "collateralCoin", default)]
201    pub collateral_coin: Option<String>,
202    ///
203    /// The `current` parameter.
204    ///
205    /// This field is **optional.
206    #[builder(setter(into), default)]
207    #[serde(rename = "current", default)]
208    pub current: Option<i64>,
209    ///
210    /// The `limit` parameter.
211    ///
212    /// This field is **optional.
213    #[builder(setter(into), default)]
214    #[serde(rename = "limit", default)]
215    pub limit: Option<i64>,
216    ///
217    /// The `recv_window` parameter.
218    ///
219    /// This field is **optional.
220    #[builder(setter(into), default)]
221    #[serde(rename = "recvWindow", default)]
222    pub recv_window: Option<i64>,
223}
224
225impl GetVipLoanOngoingOrdersParams {
226    /// Create a builder for [`get_vip_loan_ongoing_orders`].
227    ///
228    #[must_use]
229    pub fn builder() -> GetVipLoanOngoingOrdersParamsBuilder {
230        GetVipLoanOngoingOrdersParamsBuilder::default()
231    }
232}
233/// Request parameters for the [`get_vip_loan_repayment_history`] operation.
234///
235/// This struct holds all of the inputs you can pass when calling
236/// [`get_vip_loan_repayment_history`](#method.get_vip_loan_repayment_history).
237#[derive(Clone, Debug, Builder, Deserialize, Default)]
238#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
239pub struct GetVipLoanRepaymentHistoryParams {
240    ///
241    /// The `order_id` parameter.
242    ///
243    /// This field is **optional.
244    #[builder(setter(into), default)]
245    #[serde(rename = "orderId", default)]
246    pub order_id: Option<i64>,
247    ///
248    /// The `loan_coin` parameter.
249    ///
250    /// This field is **optional.
251    #[builder(setter(into), default)]
252    #[serde(rename = "loanCoin", default)]
253    pub loan_coin: Option<String>,
254    /// If both startTime and endTime are omitted, the most recent 90 days are returned.
255    ///
256    /// This field is **optional.
257    #[builder(setter(into), default)]
258    #[serde(rename = "startTime", default)]
259    pub start_time: Option<i64>,
260    /// Maximum interval between startTime and endTime is 180 days.
261    ///
262    /// This field is **optional.
263    #[builder(setter(into), default)]
264    #[serde(rename = "endTime", default)]
265    pub end_time: Option<i64>,
266    /// Current page number, starting from 1.
267    ///
268    /// This field is **optional.
269    #[builder(setter(into), default)]
270    #[serde(rename = "current", default)]
271    pub current: Option<i64>,
272    /// Number of records per page.
273    ///
274    /// This field is **optional.
275    #[builder(setter(into), default)]
276    #[serde(rename = "limit", default)]
277    pub limit: Option<i64>,
278    ///
279    /// The `recv_window` parameter.
280    ///
281    /// This field is **optional.
282    #[builder(setter(into), default)]
283    #[serde(rename = "recvWindow", default)]
284    pub recv_window: Option<i64>,
285}
286
287impl GetVipLoanRepaymentHistoryParams {
288    /// Create a builder for [`get_vip_loan_repayment_history`].
289    ///
290    #[must_use]
291    pub fn builder() -> GetVipLoanRepaymentHistoryParamsBuilder {
292        GetVipLoanRepaymentHistoryParamsBuilder::default()
293    }
294}
295/// Request parameters for the [`query_application_status`] operation.
296///
297/// This struct holds all of the inputs you can pass when calling
298/// [`query_application_status`](#method.query_application_status).
299#[derive(Clone, Debug, Builder, Deserialize, Default)]
300#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
301pub struct QueryApplicationStatusParams {
302    /// Current page number, starting from 1.
303    ///
304    /// This field is **optional.
305    #[builder(setter(into), default)]
306    #[serde(rename = "current", default)]
307    pub current: Option<i64>,
308    ///
309    /// The `limit` parameter.
310    ///
311    /// This field is **optional.
312    #[builder(setter(into), default)]
313    #[serde(rename = "limit", default)]
314    pub limit: Option<i64>,
315    ///
316    /// The `recv_window` parameter.
317    ///
318    /// This field is **optional.
319    #[builder(setter(into), default)]
320    #[serde(rename = "recvWindow", default)]
321    pub recv_window: Option<i64>,
322}
323
324impl QueryApplicationStatusParams {
325    /// Create a builder for [`query_application_status`].
326    ///
327    #[must_use]
328    pub fn builder() -> QueryApplicationStatusParamsBuilder {
329        QueryApplicationStatusParamsBuilder::default()
330    }
331}
332
333#[async_trait]
334impl UserInformationApi for UserInformationApiClient {
335    async fn check_vip_loan_collateral_account(
336        &self,
337        params: CheckVipLoanCollateralAccountParams,
338    ) -> anyhow::Result<RestApiResponse<models::CheckVipLoanCollateralAccountResponse>> {
339        let CheckVipLoanCollateralAccountParams {
340            order_id,
341            collateral_account_id,
342            recv_window,
343        } = params;
344
345        let mut query_params = BTreeMap::new();
346        let body_params = BTreeMap::new();
347
348        if let Some(rw) = order_id {
349            query_params.insert("orderId".to_string(), json!(rw));
350        }
351
352        if let Some(rw) = collateral_account_id {
353            query_params.insert("collateralAccountId".to_string(), json!(rw));
354        }
355
356        if let Some(rw) = recv_window {
357            query_params.insert("recvWindow".to_string(), json!(rw));
358        }
359
360        send_request::<models::CheckVipLoanCollateralAccountResponse>(
361            &self.configuration,
362            "/sapi/v1/loan/vip/collateral/account",
363            reqwest::Method::GET,
364            query_params,
365            body_params,
366            if HAS_TIME_UNIT {
367                self.configuration.time_unit
368            } else {
369                None
370            },
371            true,
372        )
373        .await
374    }
375
376    async fn get_vip_loan_accrued_interest(
377        &self,
378        params: GetVipLoanAccruedInterestParams,
379    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanAccruedInterestResponse>> {
380        let GetVipLoanAccruedInterestParams {
381            order_id,
382            loan_coin,
383            start_time,
384            end_time,
385            current,
386            limit,
387            recv_window,
388        } = params;
389
390        let mut query_params = BTreeMap::new();
391        let body_params = BTreeMap::new();
392
393        if let Some(rw) = order_id {
394            query_params.insert("orderId".to_string(), json!(rw));
395        }
396
397        if let Some(rw) = loan_coin {
398            query_params.insert("loanCoin".to_string(), json!(rw));
399        }
400
401        if let Some(rw) = start_time {
402            query_params.insert("startTime".to_string(), json!(rw));
403        }
404
405        if let Some(rw) = end_time {
406            query_params.insert("endTime".to_string(), json!(rw));
407        }
408
409        if let Some(rw) = current {
410            query_params.insert("current".to_string(), json!(rw));
411        }
412
413        if let Some(rw) = limit {
414            query_params.insert("limit".to_string(), json!(rw));
415        }
416
417        if let Some(rw) = recv_window {
418            query_params.insert("recvWindow".to_string(), json!(rw));
419        }
420
421        send_request::<models::GetVipLoanAccruedInterestResponse>(
422            &self.configuration,
423            "/sapi/v1/loan/vip/accruedInterest",
424            reqwest::Method::GET,
425            query_params,
426            body_params,
427            if HAS_TIME_UNIT {
428                self.configuration.time_unit
429            } else {
430                None
431            },
432            true,
433        )
434        .await
435    }
436
437    async fn get_vip_loan_ongoing_orders(
438        &self,
439        params: GetVipLoanOngoingOrdersParams,
440    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanOngoingOrdersResponse>> {
441        let GetVipLoanOngoingOrdersParams {
442            order_id,
443            collateral_account_id,
444            loan_coin,
445            collateral_coin,
446            current,
447            limit,
448            recv_window,
449        } = params;
450
451        let mut query_params = BTreeMap::new();
452        let body_params = BTreeMap::new();
453
454        if let Some(rw) = order_id {
455            query_params.insert("orderId".to_string(), json!(rw));
456        }
457
458        if let Some(rw) = collateral_account_id {
459            query_params.insert("collateralAccountId".to_string(), json!(rw));
460        }
461
462        if let Some(rw) = loan_coin {
463            query_params.insert("loanCoin".to_string(), json!(rw));
464        }
465
466        if let Some(rw) = collateral_coin {
467            query_params.insert("collateralCoin".to_string(), json!(rw));
468        }
469
470        if let Some(rw) = current {
471            query_params.insert("current".to_string(), json!(rw));
472        }
473
474        if let Some(rw) = limit {
475            query_params.insert("limit".to_string(), json!(rw));
476        }
477
478        if let Some(rw) = recv_window {
479            query_params.insert("recvWindow".to_string(), json!(rw));
480        }
481
482        send_request::<models::GetVipLoanOngoingOrdersResponse>(
483            &self.configuration,
484            "/sapi/v1/loan/vip/ongoing/orders",
485            reqwest::Method::GET,
486            query_params,
487            body_params,
488            if HAS_TIME_UNIT {
489                self.configuration.time_unit
490            } else {
491                None
492            },
493            true,
494        )
495        .await
496    }
497
498    async fn get_vip_loan_repayment_history(
499        &self,
500        params: GetVipLoanRepaymentHistoryParams,
501    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanRepaymentHistoryResponse>> {
502        let GetVipLoanRepaymentHistoryParams {
503            order_id,
504            loan_coin,
505            start_time,
506            end_time,
507            current,
508            limit,
509            recv_window,
510        } = params;
511
512        let mut query_params = BTreeMap::new();
513        let body_params = BTreeMap::new();
514
515        if let Some(rw) = order_id {
516            query_params.insert("orderId".to_string(), json!(rw));
517        }
518
519        if let Some(rw) = loan_coin {
520            query_params.insert("loanCoin".to_string(), json!(rw));
521        }
522
523        if let Some(rw) = start_time {
524            query_params.insert("startTime".to_string(), json!(rw));
525        }
526
527        if let Some(rw) = end_time {
528            query_params.insert("endTime".to_string(), json!(rw));
529        }
530
531        if let Some(rw) = current {
532            query_params.insert("current".to_string(), json!(rw));
533        }
534
535        if let Some(rw) = limit {
536            query_params.insert("limit".to_string(), json!(rw));
537        }
538
539        if let Some(rw) = recv_window {
540            query_params.insert("recvWindow".to_string(), json!(rw));
541        }
542
543        send_request::<models::GetVipLoanRepaymentHistoryResponse>(
544            &self.configuration,
545            "/sapi/v1/loan/vip/repay/history",
546            reqwest::Method::GET,
547            query_params,
548            body_params,
549            if HAS_TIME_UNIT {
550                self.configuration.time_unit
551            } else {
552                None
553            },
554            true,
555        )
556        .await
557    }
558
559    async fn query_application_status(
560        &self,
561        params: QueryApplicationStatusParams,
562    ) -> anyhow::Result<RestApiResponse<models::QueryApplicationStatusResponse>> {
563        let QueryApplicationStatusParams {
564            current,
565            limit,
566            recv_window,
567        } = params;
568
569        let mut query_params = BTreeMap::new();
570        let body_params = BTreeMap::new();
571
572        if let Some(rw) = current {
573            query_params.insert("current".to_string(), json!(rw));
574        }
575
576        if let Some(rw) = limit {
577            query_params.insert("limit".to_string(), json!(rw));
578        }
579
580        if let Some(rw) = recv_window {
581            query_params.insert("recvWindow".to_string(), json!(rw));
582        }
583
584        send_request::<models::QueryApplicationStatusResponse>(
585            &self.configuration,
586            "/sapi/v1/loan/vip/request/data",
587            reqwest::Method::GET,
588            query_params,
589            body_params,
590            if HAS_TIME_UNIT {
591                self.configuration.time_unit
592            } else {
593                None
594            },
595            true,
596        )
597        .await
598    }
599}
600
601#[cfg(all(test, feature = "vip_loan"))]
602mod tests {
603    use super::*;
604    use crate::TOKIO_SHARED_RT;
605    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
606    use async_trait::async_trait;
607    use std::collections::HashMap;
608
609    struct DummyRestApiResponse<T> {
610        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
611        status: u16,
612        headers: HashMap<String, String>,
613        rate_limits: Option<Vec<RestApiRateLimit>>,
614    }
615
616    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
617        fn from(dummy: DummyRestApiResponse<T>) -> Self {
618            Self {
619                data_fn: dummy.inner,
620                status: dummy.status,
621                headers: dummy.headers,
622                rate_limits: dummy.rate_limits,
623            }
624        }
625    }
626
627    struct MockUserInformationApiClient {
628        force_error: bool,
629    }
630
631    #[async_trait]
632    impl UserInformationApi for MockUserInformationApiClient {
633        async fn check_vip_loan_collateral_account(
634            &self,
635            _params: CheckVipLoanCollateralAccountParams,
636        ) -> anyhow::Result<RestApiResponse<models::CheckVipLoanCollateralAccountResponse>>
637        {
638            if self.force_error {
639                return Err(ConnectorError::ConnectorClientError {
640                    msg: "ResponseError".to_string(),
641                    code: None,
642                }
643                .into());
644            }
645
646            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralAccountId":"12345678","collateralCoin":"BNB,BTC,ETH"}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
647            let dummy_response: models::CheckVipLoanCollateralAccountResponse =
648                serde_json::from_value(resp_json.clone())
649                    .expect("should parse into models::CheckVipLoanCollateralAccountResponse");
650
651            let dummy = DummyRestApiResponse {
652                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
653                status: 200,
654                headers: HashMap::new(),
655                rate_limits: None,
656            };
657
658            Ok(dummy.into())
659        }
660
661        async fn get_vip_loan_accrued_interest(
662            &self,
663            _params: GetVipLoanAccruedInterestParams,
664        ) -> anyhow::Result<RestApiResponse<models::GetVipLoanAccruedInterestResponse>> {
665            if self.force_error {
666                return Err(ConnectorError::ConnectorClientError {
667                    msg: "ResponseError".to_string(),
668                    code: None,
669                }
670                .into());
671            }
672
673            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"USDT","principalAmount":"10000","interestAmount":"1.2","annualInterestRate":"0.001273","accrualTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
674            let dummy_response: models::GetVipLoanAccruedInterestResponse =
675                serde_json::from_value(resp_json.clone())
676                    .expect("should parse into models::GetVipLoanAccruedInterestResponse");
677
678            let dummy = DummyRestApiResponse {
679                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
680                status: 200,
681                headers: HashMap::new(),
682                rate_limits: None,
683            };
684
685            Ok(dummy.into())
686        }
687
688        async fn get_vip_loan_ongoing_orders(
689            &self,
690            _params: GetVipLoanOngoingOrdersParams,
691        ) -> anyhow::Result<RestApiResponse<models::GetVipLoanOngoingOrdersResponse>> {
692            if self.force_error {
693                return Err(ConnectorError::ConnectorClientError {
694                    msg: "ResponseError".to_string(),
695                    code: None,
696                }
697                .into());
698            }
699
700            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","totalDebt":"10000","loanRate":"0.0123","residualInterest":"10.27687923","collateralAccountId":"12345678,23456789","collateralCoin":"BNB,BTC,ETH","totalCollateralValueAfterHaircut":"25000.27565492","lockedCollateralValue":"25000.27565492","currentLTV":"0.57","expirationTime":1575018510000,"loanDate":"1676851200000","loanTerm":"30days"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
701            let dummy_response: models::GetVipLoanOngoingOrdersResponse =
702                serde_json::from_value(resp_json.clone())
703                    .expect("should parse into models::GetVipLoanOngoingOrdersResponse");
704
705            let dummy = DummyRestApiResponse {
706                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
707                status: 200,
708                headers: HashMap::new(),
709                rate_limits: None,
710            };
711
712            Ok(dummy.into())
713        }
714
715        async fn get_vip_loan_repayment_history(
716            &self,
717            _params: GetVipLoanRepaymentHistoryParams,
718        ) -> anyhow::Result<RestApiResponse<models::GetVipLoanRepaymentHistoryResponse>> {
719            if self.force_error {
720                return Err(ConnectorError::ConnectorClientError {
721                    msg: "ResponseError".to_string(),
722                    code: None,
723                }
724                .into());
725            }
726
727            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB,BTC,ETH","repayStatus":"Repaid","loanDate":"1676851200000","repayTime":"1575018510000","orderId":"756783308056935434"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
728            let dummy_response: models::GetVipLoanRepaymentHistoryResponse =
729                serde_json::from_value(resp_json.clone())
730                    .expect("should parse into models::GetVipLoanRepaymentHistoryResponse");
731
732            let dummy = DummyRestApiResponse {
733                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
734                status: 200,
735                headers: HashMap::new(),
736                rate_limits: None,
737            };
738
739            Ok(dummy.into())
740        }
741
742        async fn query_application_status(
743            &self,
744            _params: QueryApplicationStatusParams,
745        ) -> anyhow::Result<RestApiResponse<models::QueryApplicationStatusResponse>> {
746            if self.force_error {
747                return Err(ConnectorError::ConnectorClientError {
748                    msg: "ResponseError".to_string(),
749                    code: None,
750                }
751                .into());
752            }
753
754            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanAccountId":"12345678","orderId":"12345678","requestId":"12345678","loanCoin":"BTC","loanAmount":"100.55","collateralAccountId":"12345678,12345678,12345678","collateralCoin":"BUSD,USDT,ETH","loanTerm":"30","status":"Repaid","loanDate":"1676851200000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
755            let dummy_response: models::QueryApplicationStatusResponse =
756                serde_json::from_value(resp_json.clone())
757                    .expect("should parse into models::QueryApplicationStatusResponse");
758
759            let dummy = DummyRestApiResponse {
760                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
761                status: 200,
762                headers: HashMap::new(),
763                rate_limits: None,
764            };
765
766            Ok(dummy.into())
767        }
768    }
769
770    #[test]
771    fn check_vip_loan_collateral_account_required_params_success() {
772        TOKIO_SHARED_RT.block_on(async {
773            let client = MockUserInformationApiClient { force_error: false };
774
775            let params = CheckVipLoanCollateralAccountParams::builder().build().unwrap();
776
777            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralAccountId":"12345678","collateralCoin":"BNB,BTC,ETH"}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
778            let expected_response : models::CheckVipLoanCollateralAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CheckVipLoanCollateralAccountResponse");
779
780            let resp = client.check_vip_loan_collateral_account(params).await.expect("Expected a response");
781            let data_future = resp.data();
782            let actual_response = data_future.await.unwrap();
783            assert_eq!(actual_response, expected_response);
784        });
785    }
786
787    #[test]
788    fn check_vip_loan_collateral_account_optional_params_success() {
789        TOKIO_SHARED_RT.block_on(async {
790            let client = MockUserInformationApiClient { force_error: false };
791
792            let params = CheckVipLoanCollateralAccountParams::builder().order_id(1).collateral_account_id(1).recv_window(5000).build().unwrap();
793
794            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralAccountId":"12345678","collateralCoin":"BNB,BTC,ETH"}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
795            let expected_response : models::CheckVipLoanCollateralAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CheckVipLoanCollateralAccountResponse");
796
797            let resp = client.check_vip_loan_collateral_account(params).await.expect("Expected a response");
798            let data_future = resp.data();
799            let actual_response = data_future.await.unwrap();
800            assert_eq!(actual_response, expected_response);
801        });
802    }
803
804    #[test]
805    fn check_vip_loan_collateral_account_response_error() {
806        TOKIO_SHARED_RT.block_on(async {
807            let client = MockUserInformationApiClient { force_error: true };
808
809            let params = CheckVipLoanCollateralAccountParams::builder()
810                .build()
811                .unwrap();
812
813            match client.check_vip_loan_collateral_account(params).await {
814                Ok(_) => panic!("Expected an error"),
815                Err(err) => {
816                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
817                }
818            }
819        });
820    }
821
822    #[test]
823    fn get_vip_loan_accrued_interest_required_params_success() {
824        TOKIO_SHARED_RT.block_on(async {
825            let client = MockUserInformationApiClient { force_error: false };
826
827            let params = GetVipLoanAccruedInterestParams::builder().build().unwrap();
828
829            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"USDT","principalAmount":"10000","interestAmount":"1.2","annualInterestRate":"0.001273","accrualTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
830            let expected_response : models::GetVipLoanAccruedInterestResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanAccruedInterestResponse");
831
832            let resp = client.get_vip_loan_accrued_interest(params).await.expect("Expected a response");
833            let data_future = resp.data();
834            let actual_response = data_future.await.unwrap();
835            assert_eq!(actual_response, expected_response);
836        });
837    }
838
839    #[test]
840    fn get_vip_loan_accrued_interest_optional_params_success() {
841        TOKIO_SHARED_RT.block_on(async {
842            let client = MockUserInformationApiClient { force_error: false };
843
844            let params = GetVipLoanAccruedInterestParams::builder().order_id(1).loan_coin("BTC".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
845
846            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"USDT","principalAmount":"10000","interestAmount":"1.2","annualInterestRate":"0.001273","accrualTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
847            let expected_response : models::GetVipLoanAccruedInterestResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanAccruedInterestResponse");
848
849            let resp = client.get_vip_loan_accrued_interest(params).await.expect("Expected a response");
850            let data_future = resp.data();
851            let actual_response = data_future.await.unwrap();
852            assert_eq!(actual_response, expected_response);
853        });
854    }
855
856    #[test]
857    fn get_vip_loan_accrued_interest_response_error() {
858        TOKIO_SHARED_RT.block_on(async {
859            let client = MockUserInformationApiClient { force_error: true };
860
861            let params = GetVipLoanAccruedInterestParams::builder().build().unwrap();
862
863            match client.get_vip_loan_accrued_interest(params).await {
864                Ok(_) => panic!("Expected an error"),
865                Err(err) => {
866                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
867                }
868            }
869        });
870    }
871
872    #[test]
873    fn get_vip_loan_ongoing_orders_required_params_success() {
874        TOKIO_SHARED_RT.block_on(async {
875            let client = MockUserInformationApiClient { force_error: false };
876
877            let params = GetVipLoanOngoingOrdersParams::builder().build().unwrap();
878
879            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","totalDebt":"10000","loanRate":"0.0123","residualInterest":"10.27687923","collateralAccountId":"12345678,23456789","collateralCoin":"BNB,BTC,ETH","totalCollateralValueAfterHaircut":"25000.27565492","lockedCollateralValue":"25000.27565492","currentLTV":"0.57","expirationTime":1575018510000,"loanDate":"1676851200000","loanTerm":"30days"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
880            let expected_response : models::GetVipLoanOngoingOrdersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanOngoingOrdersResponse");
881
882            let resp = client.get_vip_loan_ongoing_orders(params).await.expect("Expected a response");
883            let data_future = resp.data();
884            let actual_response = data_future.await.unwrap();
885            assert_eq!(actual_response, expected_response);
886        });
887    }
888
889    #[test]
890    fn get_vip_loan_ongoing_orders_optional_params_success() {
891        TOKIO_SHARED_RT.block_on(async {
892            let client = MockUserInformationApiClient { force_error: false };
893
894            let params = GetVipLoanOngoingOrdersParams::builder().order_id(1).collateral_account_id(1).loan_coin("BUSD".to_string()).collateral_coin("BNB,BTC,ETH".to_string()).current(1).limit(10).recv_window(5000).build().unwrap();
895
896            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","totalDebt":"10000","loanRate":"0.0123","residualInterest":"10.27687923","collateralAccountId":"12345678,23456789","collateralCoin":"BNB,BTC,ETH","totalCollateralValueAfterHaircut":"25000.27565492","lockedCollateralValue":"25000.27565492","currentLTV":"0.57","expirationTime":1575018510000,"loanDate":"1676851200000","loanTerm":"30days"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
897            let expected_response : models::GetVipLoanOngoingOrdersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanOngoingOrdersResponse");
898
899            let resp = client.get_vip_loan_ongoing_orders(params).await.expect("Expected a response");
900            let data_future = resp.data();
901            let actual_response = data_future.await.unwrap();
902            assert_eq!(actual_response, expected_response);
903        });
904    }
905
906    #[test]
907    fn get_vip_loan_ongoing_orders_response_error() {
908        TOKIO_SHARED_RT.block_on(async {
909            let client = MockUserInformationApiClient { force_error: true };
910
911            let params = GetVipLoanOngoingOrdersParams::builder().build().unwrap();
912
913            match client.get_vip_loan_ongoing_orders(params).await {
914                Ok(_) => panic!("Expected an error"),
915                Err(err) => {
916                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
917                }
918            }
919        });
920    }
921
922    #[test]
923    fn get_vip_loan_repayment_history_required_params_success() {
924        TOKIO_SHARED_RT.block_on(async {
925            let client = MockUserInformationApiClient { force_error: false };
926
927            let params = GetVipLoanRepaymentHistoryParams::builder().build().unwrap();
928
929            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB,BTC,ETH","repayStatus":"Repaid","loanDate":"1676851200000","repayTime":"1575018510000","orderId":"756783308056935434"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
930            let expected_response : models::GetVipLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanRepaymentHistoryResponse");
931
932            let resp = client.get_vip_loan_repayment_history(params).await.expect("Expected a response");
933            let data_future = resp.data();
934            let actual_response = data_future.await.unwrap();
935            assert_eq!(actual_response, expected_response);
936        });
937    }
938
939    #[test]
940    fn get_vip_loan_repayment_history_optional_params_success() {
941        TOKIO_SHARED_RT.block_on(async {
942            let client = MockUserInformationApiClient { force_error: false };
943
944            let params = GetVipLoanRepaymentHistoryParams::builder().order_id(1).loan_coin("BUSD".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
945
946            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB,BTC,ETH","repayStatus":"Repaid","loanDate":"1676851200000","repayTime":"1575018510000","orderId":"756783308056935434"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
947            let expected_response : models::GetVipLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetVipLoanRepaymentHistoryResponse");
948
949            let resp = client.get_vip_loan_repayment_history(params).await.expect("Expected a response");
950            let data_future = resp.data();
951            let actual_response = data_future.await.unwrap();
952            assert_eq!(actual_response, expected_response);
953        });
954    }
955
956    #[test]
957    fn get_vip_loan_repayment_history_response_error() {
958        TOKIO_SHARED_RT.block_on(async {
959            let client = MockUserInformationApiClient { force_error: true };
960
961            let params = GetVipLoanRepaymentHistoryParams::builder().build().unwrap();
962
963            match client.get_vip_loan_repayment_history(params).await {
964                Ok(_) => panic!("Expected an error"),
965                Err(err) => {
966                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
967                }
968            }
969        });
970    }
971
972    #[test]
973    fn query_application_status_required_params_success() {
974        TOKIO_SHARED_RT.block_on(async {
975            let client = MockUserInformationApiClient { force_error: false };
976
977            let params = QueryApplicationStatusParams::builder().build().unwrap();
978
979            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanAccountId":"12345678","orderId":"12345678","requestId":"12345678","loanCoin":"BTC","loanAmount":"100.55","collateralAccountId":"12345678,12345678,12345678","collateralCoin":"BUSD,USDT,ETH","loanTerm":"30","status":"Repaid","loanDate":"1676851200000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
980            let expected_response : models::QueryApplicationStatusResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryApplicationStatusResponse");
981
982            let resp = client.query_application_status(params).await.expect("Expected a response");
983            let data_future = resp.data();
984            let actual_response = data_future.await.unwrap();
985            assert_eq!(actual_response, expected_response);
986        });
987    }
988
989    #[test]
990    fn query_application_status_optional_params_success() {
991        TOKIO_SHARED_RT.block_on(async {
992            let client = MockUserInformationApiClient { force_error: false };
993
994            let params = QueryApplicationStatusParams::builder().current(1).limit(10).recv_window(5000).build().unwrap();
995
996            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanAccountId":"12345678","orderId":"12345678","requestId":"12345678","loanCoin":"BTC","loanAmount":"100.55","collateralAccountId":"12345678,12345678,12345678","collateralCoin":"BUSD,USDT,ETH","loanTerm":"30","status":"Repaid","loanDate":"1676851200000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
997            let expected_response : models::QueryApplicationStatusResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryApplicationStatusResponse");
998
999            let resp = client.query_application_status(params).await.expect("Expected a response");
1000            let data_future = resp.data();
1001            let actual_response = data_future.await.unwrap();
1002            assert_eq!(actual_response, expected_response);
1003        });
1004    }
1005
1006    #[test]
1007    fn query_application_status_response_error() {
1008        TOKIO_SHARED_RT.block_on(async {
1009            let client = MockUserInformationApiClient { force_error: true };
1010
1011            let params = QueryApplicationStatusParams::builder().build().unwrap();
1012
1013            match client.query_application_status(params).await {
1014                Ok(_) => panic!("Expected an error"),
1015                Err(err) => {
1016                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1017                }
1018            }
1019        });
1020    }
1021}