Skip to main content

binance_sdk/sub_account/rest_api/apis/
account_management_api.rs

1/*
2 * Sub Account REST API
3 *
4 * Create and manage sub-accounts, control permissions, and transfer assets via the Sub Account 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::sub_account::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait AccountManagementApi: Send + Sync {
34    async fn create_a_virtual_sub_account(
35        &self,
36        params: CreateAVirtualSubAccountParams,
37    ) -> anyhow::Result<RestApiResponse<models::CreateAVirtualSubAccountResponse>>;
38    async fn enable_futures_for_sub_account(
39        &self,
40        params: EnableFuturesForSubAccountParams,
41    ) -> anyhow::Result<RestApiResponse<models::EnableFuturesForSubAccountResponse>>;
42    async fn enable_options_for_sub_account(
43        &self,
44        params: EnableOptionsForSubAccountParams,
45    ) -> anyhow::Result<RestApiResponse<models::EnableOptionsForSubAccountResponse>>;
46    async fn get_futures_position_risk_of_sub_account(
47        &self,
48        params: GetFuturesPositionRiskOfSubAccountParams,
49    ) -> anyhow::Result<RestApiResponse<Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>>>;
50    async fn get_futures_position_risk_of_sub_account_v2(
51        &self,
52        params: GetFuturesPositionRiskOfSubAccountV2Params,
53    ) -> anyhow::Result<RestApiResponse<models::GetFuturesPositionRiskOfSubAccountV2Response>>;
54    async fn get_sub_accounts_status_on_margin_or_futures(
55        &self,
56        params: GetSubAccountsStatusOnMarginOrFuturesParams,
57    ) -> anyhow::Result<
58        RestApiResponse<Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>>,
59    >;
60    async fn query_sub_account_list(
61        &self,
62        params: QuerySubAccountListParams,
63    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountListResponse>>;
64    async fn query_sub_account_transaction_statistics(
65        &self,
66        params: QuerySubAccountTransactionStatisticsParams,
67    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountTransactionStatisticsResponse>>;
68}
69
70#[derive(Debug, Clone)]
71pub struct AccountManagementApiClient {
72    configuration: ConfigurationRestApi,
73}
74
75impl AccountManagementApiClient {
76    pub fn new(configuration: ConfigurationRestApi) -> Self {
77        Self { configuration }
78    }
79}
80
81/// Request parameters for the [`create_a_virtual_sub_account`] operation.
82///
83/// This struct holds all of the inputs you can pass when calling
84/// [`create_a_virtual_sub_account`](#method.create_a_virtual_sub_account).
85#[derive(Clone, Debug, Builder, Deserialize)]
86#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
87pub struct CreateAVirtualSubAccountParams {
88    /// Please input a string. We will create a virtual email using that string for you to register
89    ///
90    /// This field is **required.
91    #[builder(setter(into))]
92    #[serde(rename = "subAccountString")]
93    pub sub_account_string: String,
94    ///
95    /// The `recv_window` parameter.
96    ///
97    /// This field is **optional.
98    #[builder(setter(into), default)]
99    #[serde(rename = "recvWindow", default)]
100    pub recv_window: Option<i64>,
101}
102
103impl CreateAVirtualSubAccountParams {
104    /// Create a builder for [`create_a_virtual_sub_account`].
105    ///
106    /// Required parameters:
107    ///
108    /// * `sub_account_string` — Please input a string. We will create a virtual email using that string for you to register
109    ///
110    #[must_use]
111    pub fn builder(sub_account_string: String) -> CreateAVirtualSubAccountParamsBuilder {
112        CreateAVirtualSubAccountParamsBuilder::default().sub_account_string(sub_account_string)
113    }
114}
115/// Request parameters for the [`enable_futures_for_sub_account`] operation.
116///
117/// This struct holds all of the inputs you can pass when calling
118/// [`enable_futures_for_sub_account`](#method.enable_futures_for_sub_account).
119#[derive(Clone, Debug, Builder, Deserialize)]
120#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
121pub struct EnableFuturesForSubAccountParams {
122    ///
123    /// The `email` parameter.
124    ///
125    /// This field is **required.
126    #[builder(setter(into))]
127    #[serde(rename = "email")]
128    pub email: String,
129    ///
130    /// The `recv_window` parameter.
131    ///
132    /// This field is **optional.
133    #[builder(setter(into), default)]
134    #[serde(rename = "recvWindow", default)]
135    pub recv_window: Option<i64>,
136}
137
138impl EnableFuturesForSubAccountParams {
139    /// Create a builder for [`enable_futures_for_sub_account`].
140    ///
141    /// Required parameters:
142    ///
143    /// * `email` — String
144    ///
145    #[must_use]
146    pub fn builder(email: String) -> EnableFuturesForSubAccountParamsBuilder {
147        EnableFuturesForSubAccountParamsBuilder::default().email(email)
148    }
149}
150/// Request parameters for the [`enable_options_for_sub_account`] operation.
151///
152/// This struct holds all of the inputs you can pass when calling
153/// [`enable_options_for_sub_account`](#method.enable_options_for_sub_account).
154#[derive(Clone, Debug, Builder, Deserialize)]
155#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
156pub struct EnableOptionsForSubAccountParams {
157    ///
158    /// The `email` parameter.
159    ///
160    /// This field is **required.
161    #[builder(setter(into))]
162    #[serde(rename = "email")]
163    pub email: String,
164    ///
165    /// The `recv_window` parameter.
166    ///
167    /// This field is **optional.
168    #[builder(setter(into), default)]
169    #[serde(rename = "recvWindow", default)]
170    pub recv_window: Option<i64>,
171}
172
173impl EnableOptionsForSubAccountParams {
174    /// Create a builder for [`enable_options_for_sub_account`].
175    ///
176    /// Required parameters:
177    ///
178    /// * `email` — String
179    ///
180    #[must_use]
181    pub fn builder(email: String) -> EnableOptionsForSubAccountParamsBuilder {
182        EnableOptionsForSubAccountParamsBuilder::default().email(email)
183    }
184}
185/// Request parameters for the [`get_futures_position_risk_of_sub_account`] operation.
186///
187/// This struct holds all of the inputs you can pass when calling
188/// [`get_futures_position_risk_of_sub_account`](#method.get_futures_position_risk_of_sub_account).
189#[derive(Clone, Debug, Builder, Deserialize)]
190#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
191pub struct GetFuturesPositionRiskOfSubAccountParams {
192    ///
193    /// The `email` parameter.
194    ///
195    /// This field is **required.
196    #[builder(setter(into))]
197    #[serde(rename = "email")]
198    pub email: String,
199    ///
200    /// The `recv_window` parameter.
201    ///
202    /// This field is **optional.
203    #[builder(setter(into), default)]
204    #[serde(rename = "recvWindow", default)]
205    pub recv_window: Option<i64>,
206}
207
208impl GetFuturesPositionRiskOfSubAccountParams {
209    /// Create a builder for [`get_futures_position_risk_of_sub_account`].
210    ///
211    /// Required parameters:
212    ///
213    /// * `email` — String
214    ///
215    #[must_use]
216    pub fn builder(email: String) -> GetFuturesPositionRiskOfSubAccountParamsBuilder {
217        GetFuturesPositionRiskOfSubAccountParamsBuilder::default().email(email)
218    }
219}
220/// Request parameters for the [`get_futures_position_risk_of_sub_account_v2`] operation.
221///
222/// This struct holds all of the inputs you can pass when calling
223/// [`get_futures_position_risk_of_sub_account_v2`](#method.get_futures_position_risk_of_sub_account_v2).
224#[derive(Clone, Debug, Builder, Deserialize)]
225#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
226pub struct GetFuturesPositionRiskOfSubAccountV2Params {
227    ///
228    /// The `email` parameter.
229    ///
230    /// This field is **required.
231    #[builder(setter(into))]
232    #[serde(rename = "email")]
233    pub email: String,
234    /// 1:USDT-margined Futures,2: Coin-margined Futures
235    ///
236    /// This field is **required.
237    #[builder(setter(into))]
238    #[serde(rename = "futuresType")]
239    pub futures_type: i64,
240    ///
241    /// The `recv_window` parameter.
242    ///
243    /// This field is **optional.
244    #[builder(setter(into), default)]
245    #[serde(rename = "recvWindow", default)]
246    pub recv_window: Option<i64>,
247}
248
249impl GetFuturesPositionRiskOfSubAccountV2Params {
250    /// Create a builder for [`get_futures_position_risk_of_sub_account_v2`].
251    ///
252    /// Required parameters:
253    ///
254    /// * `email` — String
255    /// * `futures_type` — 1:USDT-margined Futures,2: Coin-margined Futures
256    ///
257    #[must_use]
258    pub fn builder(
259        email: String,
260        futures_type: i64,
261    ) -> GetFuturesPositionRiskOfSubAccountV2ParamsBuilder {
262        GetFuturesPositionRiskOfSubAccountV2ParamsBuilder::default()
263            .email(email)
264            .futures_type(futures_type)
265    }
266}
267/// Request parameters for the [`get_sub_accounts_status_on_margin_or_futures`] operation.
268///
269/// This struct holds all of the inputs you can pass when calling
270/// [`get_sub_accounts_status_on_margin_or_futures`](#method.get_sub_accounts_status_on_margin_or_futures).
271#[derive(Clone, Debug, Builder, Deserialize, Default)]
272#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
273pub struct GetSubAccountsStatusOnMarginOrFuturesParams {
274    ///
275    /// The `email` parameter.
276    ///
277    /// This field is **optional.
278    #[builder(setter(into), default)]
279    #[serde(rename = "email", default)]
280    pub email: Option<String>,
281    ///
282    /// The `recv_window` parameter.
283    ///
284    /// This field is **optional.
285    #[builder(setter(into), default)]
286    #[serde(rename = "recvWindow", default)]
287    pub recv_window: Option<i64>,
288}
289
290impl GetSubAccountsStatusOnMarginOrFuturesParams {
291    /// Create a builder for [`get_sub_accounts_status_on_margin_or_futures`].
292    ///
293    #[must_use]
294    pub fn builder() -> GetSubAccountsStatusOnMarginOrFuturesParamsBuilder {
295        GetSubAccountsStatusOnMarginOrFuturesParamsBuilder::default()
296    }
297}
298/// Request parameters for the [`query_sub_account_list`] operation.
299///
300/// This struct holds all of the inputs you can pass when calling
301/// [`query_sub_account_list`](#method.query_sub_account_list).
302#[derive(Clone, Debug, Builder, Deserialize, Default)]
303#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
304pub struct QuerySubAccountListParams {
305    ///
306    /// The `email` parameter.
307    ///
308    /// This field is **optional.
309    #[builder(setter(into), default)]
310    #[serde(rename = "email", default)]
311    pub email: Option<String>,
312    ///
313    /// The `is_freeze` parameter.
314    ///
315    /// This field is **optional.
316    #[builder(setter(into), default)]
317    #[serde(rename = "isFreeze", default)]
318    pub is_freeze: Option<String>,
319    ///
320    /// The `page` parameter.
321    ///
322    /// This field is **optional.
323    #[builder(setter(into), default)]
324    #[serde(rename = "page", default)]
325    pub page: Option<i64>,
326    ///
327    /// The `limit` parameter.
328    ///
329    /// This field is **optional.
330    #[builder(setter(into), default)]
331    #[serde(rename = "limit", default)]
332    pub limit: Option<i64>,
333    ///
334    /// The `recv_window` parameter.
335    ///
336    /// This field is **optional.
337    #[builder(setter(into), default)]
338    #[serde(rename = "recvWindow", default)]
339    pub recv_window: Option<i64>,
340}
341
342impl QuerySubAccountListParams {
343    /// Create a builder for [`query_sub_account_list`].
344    ///
345    #[must_use]
346    pub fn builder() -> QuerySubAccountListParamsBuilder {
347        QuerySubAccountListParamsBuilder::default()
348    }
349}
350/// Request parameters for the [`query_sub_account_transaction_statistics`] operation.
351///
352/// This struct holds all of the inputs you can pass when calling
353/// [`query_sub_account_transaction_statistics`](#method.query_sub_account_transaction_statistics).
354#[derive(Clone, Debug, Builder, Deserialize, Default)]
355#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
356pub struct QuerySubAccountTransactionStatisticsParams {
357    /// Managed sub-account email
358    ///
359    /// This field is **optional.
360    #[builder(setter(into), default)]
361    #[serde(rename = "email", default)]
362    pub email: Option<String>,
363    ///
364    /// The `recv_window` parameter.
365    ///
366    /// This field is **optional.
367    #[builder(setter(into), default)]
368    #[serde(rename = "recvWindow", default)]
369    pub recv_window: Option<i64>,
370}
371
372impl QuerySubAccountTransactionStatisticsParams {
373    /// Create a builder for [`query_sub_account_transaction_statistics`].
374    ///
375    #[must_use]
376    pub fn builder() -> QuerySubAccountTransactionStatisticsParamsBuilder {
377        QuerySubAccountTransactionStatisticsParamsBuilder::default()
378    }
379}
380
381#[async_trait]
382impl AccountManagementApi for AccountManagementApiClient {
383    async fn create_a_virtual_sub_account(
384        &self,
385        params: CreateAVirtualSubAccountParams,
386    ) -> anyhow::Result<RestApiResponse<models::CreateAVirtualSubAccountResponse>> {
387        let CreateAVirtualSubAccountParams {
388            sub_account_string,
389            recv_window,
390        } = params;
391
392        let mut query_params = BTreeMap::new();
393        let body_params = BTreeMap::new();
394
395        query_params.insert("subAccountString".to_string(), json!(sub_account_string));
396
397        if let Some(rw) = recv_window {
398            query_params.insert("recvWindow".to_string(), json!(rw));
399        }
400
401        send_request::<models::CreateAVirtualSubAccountResponse>(
402            &self.configuration,
403            "/sapi/v1/sub-account/virtualSubAccount",
404            reqwest::Method::POST,
405            query_params,
406            body_params,
407            if HAS_TIME_UNIT {
408                self.configuration.time_unit
409            } else {
410                None
411            },
412            true,
413        )
414        .await
415    }
416
417    async fn enable_futures_for_sub_account(
418        &self,
419        params: EnableFuturesForSubAccountParams,
420    ) -> anyhow::Result<RestApiResponse<models::EnableFuturesForSubAccountResponse>> {
421        let EnableFuturesForSubAccountParams { email, recv_window } = params;
422
423        let mut query_params = BTreeMap::new();
424        let body_params = BTreeMap::new();
425
426        query_params.insert("email".to_string(), json!(email));
427
428        if let Some(rw) = recv_window {
429            query_params.insert("recvWindow".to_string(), json!(rw));
430        }
431
432        send_request::<models::EnableFuturesForSubAccountResponse>(
433            &self.configuration,
434            "/sapi/v1/sub-account/futures/enable",
435            reqwest::Method::POST,
436            query_params,
437            body_params,
438            if HAS_TIME_UNIT {
439                self.configuration.time_unit
440            } else {
441                None
442            },
443            true,
444        )
445        .await
446    }
447
448    async fn enable_options_for_sub_account(
449        &self,
450        params: EnableOptionsForSubAccountParams,
451    ) -> anyhow::Result<RestApiResponse<models::EnableOptionsForSubAccountResponse>> {
452        let EnableOptionsForSubAccountParams { email, recv_window } = params;
453
454        let mut query_params = BTreeMap::new();
455        let body_params = BTreeMap::new();
456
457        query_params.insert("email".to_string(), json!(email));
458
459        if let Some(rw) = recv_window {
460            query_params.insert("recvWindow".to_string(), json!(rw));
461        }
462
463        send_request::<models::EnableOptionsForSubAccountResponse>(
464            &self.configuration,
465            "/sapi/v1/sub-account/eoptions/enable",
466            reqwest::Method::POST,
467            query_params,
468            body_params,
469            if HAS_TIME_UNIT {
470                self.configuration.time_unit
471            } else {
472                None
473            },
474            true,
475        )
476        .await
477    }
478
479    async fn get_futures_position_risk_of_sub_account(
480        &self,
481        params: GetFuturesPositionRiskOfSubAccountParams,
482    ) -> anyhow::Result<RestApiResponse<Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>>>
483    {
484        let GetFuturesPositionRiskOfSubAccountParams { email, recv_window } = params;
485
486        let mut query_params = BTreeMap::new();
487        let body_params = BTreeMap::new();
488
489        query_params.insert("email".to_string(), json!(email));
490
491        if let Some(rw) = recv_window {
492            query_params.insert("recvWindow".to_string(), json!(rw));
493        }
494
495        send_request::<Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>>(
496            &self.configuration,
497            "/sapi/v1/sub-account/futures/positionRisk",
498            reqwest::Method::GET,
499            query_params,
500            body_params,
501            if HAS_TIME_UNIT {
502                self.configuration.time_unit
503            } else {
504                None
505            },
506            true,
507        )
508        .await
509    }
510
511    async fn get_futures_position_risk_of_sub_account_v2(
512        &self,
513        params: GetFuturesPositionRiskOfSubAccountV2Params,
514    ) -> anyhow::Result<RestApiResponse<models::GetFuturesPositionRiskOfSubAccountV2Response>> {
515        let GetFuturesPositionRiskOfSubAccountV2Params {
516            email,
517            futures_type,
518            recv_window,
519        } = params;
520
521        let mut query_params = BTreeMap::new();
522        let body_params = BTreeMap::new();
523
524        query_params.insert("email".to_string(), json!(email));
525
526        query_params.insert("futuresType".to_string(), json!(futures_type));
527
528        if let Some(rw) = recv_window {
529            query_params.insert("recvWindow".to_string(), json!(rw));
530        }
531
532        send_request::<models::GetFuturesPositionRiskOfSubAccountV2Response>(
533            &self.configuration,
534            "/sapi/v2/sub-account/futures/positionRisk",
535            reqwest::Method::GET,
536            query_params,
537            body_params,
538            if HAS_TIME_UNIT {
539                self.configuration.time_unit
540            } else {
541                None
542            },
543            true,
544        )
545        .await
546    }
547
548    async fn get_sub_accounts_status_on_margin_or_futures(
549        &self,
550        params: GetSubAccountsStatusOnMarginOrFuturesParams,
551    ) -> anyhow::Result<
552        RestApiResponse<Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>>,
553    > {
554        let GetSubAccountsStatusOnMarginOrFuturesParams { email, recv_window } = params;
555
556        let mut query_params = BTreeMap::new();
557        let body_params = BTreeMap::new();
558
559        if let Some(rw) = email {
560            query_params.insert("email".to_string(), json!(rw));
561        }
562
563        if let Some(rw) = recv_window {
564            query_params.insert("recvWindow".to_string(), json!(rw));
565        }
566
567        send_request::<Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>>(
568            &self.configuration,
569            "/sapi/v1/sub-account/status",
570            reqwest::Method::GET,
571            query_params,
572            body_params,
573            if HAS_TIME_UNIT {
574                self.configuration.time_unit
575            } else {
576                None
577            },
578            true,
579        )
580        .await
581    }
582
583    async fn query_sub_account_list(
584        &self,
585        params: QuerySubAccountListParams,
586    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountListResponse>> {
587        let QuerySubAccountListParams {
588            email,
589            is_freeze,
590            page,
591            limit,
592            recv_window,
593        } = params;
594
595        let mut query_params = BTreeMap::new();
596        let body_params = BTreeMap::new();
597
598        if let Some(rw) = email {
599            query_params.insert("email".to_string(), json!(rw));
600        }
601
602        if let Some(rw) = is_freeze {
603            query_params.insert("isFreeze".to_string(), json!(rw));
604        }
605
606        if let Some(rw) = page {
607            query_params.insert("page".to_string(), json!(rw));
608        }
609
610        if let Some(rw) = limit {
611            query_params.insert("limit".to_string(), json!(rw));
612        }
613
614        if let Some(rw) = recv_window {
615            query_params.insert("recvWindow".to_string(), json!(rw));
616        }
617
618        send_request::<models::QuerySubAccountListResponse>(
619            &self.configuration,
620            "/sapi/v1/sub-account/list",
621            reqwest::Method::GET,
622            query_params,
623            body_params,
624            if HAS_TIME_UNIT {
625                self.configuration.time_unit
626            } else {
627                None
628            },
629            true,
630        )
631        .await
632    }
633
634    async fn query_sub_account_transaction_statistics(
635        &self,
636        params: QuerySubAccountTransactionStatisticsParams,
637    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountTransactionStatisticsResponse>> {
638        let QuerySubAccountTransactionStatisticsParams { email, recv_window } = params;
639
640        let mut query_params = BTreeMap::new();
641        let body_params = BTreeMap::new();
642
643        if let Some(rw) = email {
644            query_params.insert("email".to_string(), json!(rw));
645        }
646
647        if let Some(rw) = recv_window {
648            query_params.insert("recvWindow".to_string(), json!(rw));
649        }
650
651        send_request::<models::QuerySubAccountTransactionStatisticsResponse>(
652            &self.configuration,
653            "/sapi/v1/sub-account/transaction-statistics",
654            reqwest::Method::GET,
655            query_params,
656            body_params,
657            if HAS_TIME_UNIT {
658                self.configuration.time_unit
659            } else {
660                None
661            },
662            true,
663        )
664        .await
665    }
666}
667
668#[cfg(all(test, feature = "sub_account"))]
669mod tests {
670    use super::*;
671    use crate::TOKIO_SHARED_RT;
672    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
673    use async_trait::async_trait;
674    use std::collections::HashMap;
675
676    struct DummyRestApiResponse<T> {
677        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
678        status: u16,
679        headers: HashMap<String, String>,
680        rate_limits: Option<Vec<RestApiRateLimit>>,
681    }
682
683    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
684        fn from(dummy: DummyRestApiResponse<T>) -> Self {
685            Self {
686                data_fn: dummy.inner,
687                status: dummy.status,
688                headers: dummy.headers,
689                rate_limits: dummy.rate_limits,
690            }
691        }
692    }
693
694    struct MockAccountManagementApiClient {
695        force_error: bool,
696    }
697
698    #[async_trait]
699    impl AccountManagementApi for MockAccountManagementApiClient {
700        async fn create_a_virtual_sub_account(
701            &self,
702            _params: CreateAVirtualSubAccountParams,
703        ) -> anyhow::Result<RestApiResponse<models::CreateAVirtualSubAccountResponse>> {
704            if self.force_error {
705                return Err(ConnectorError::ConnectorClientError {
706                    msg: "ResponseError".to_string(),
707                    code: None,
708                }
709                .into());
710            }
711
712            let resp_json: Value =
713                serde_json::from_str(r#"{"email":"addsdd_virtual@aasaixwqnoemail.com"}"#)
714                    .unwrap_or_else(|_| serde_json::json!({}));
715            let dummy_response: models::CreateAVirtualSubAccountResponse =
716                serde_json::from_value(resp_json.clone())
717                    .expect("should parse into models::CreateAVirtualSubAccountResponse");
718
719            let dummy = DummyRestApiResponse {
720                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
721                status: 200,
722                headers: HashMap::new(),
723                rate_limits: None,
724            };
725
726            Ok(dummy.into())
727        }
728
729        async fn enable_futures_for_sub_account(
730            &self,
731            _params: EnableFuturesForSubAccountParams,
732        ) -> anyhow::Result<RestApiResponse<models::EnableFuturesForSubAccountResponse>> {
733            if self.force_error {
734                return Err(ConnectorError::ConnectorClientError {
735                    msg: "ResponseError".to_string(),
736                    code: None,
737                }
738                .into());
739            }
740
741            let resp_json: Value =
742                serde_json::from_str(r#"{"email":"123@test.com","isFuturesEnabled":true}"#)
743                    .unwrap_or_else(|_| serde_json::json!({}));
744            let dummy_response: models::EnableFuturesForSubAccountResponse =
745                serde_json::from_value(resp_json.clone())
746                    .expect("should parse into models::EnableFuturesForSubAccountResponse");
747
748            let dummy = DummyRestApiResponse {
749                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
750                status: 200,
751                headers: HashMap::new(),
752                rate_limits: None,
753            };
754
755            Ok(dummy.into())
756        }
757
758        async fn enable_options_for_sub_account(
759            &self,
760            _params: EnableOptionsForSubAccountParams,
761        ) -> anyhow::Result<RestApiResponse<models::EnableOptionsForSubAccountResponse>> {
762            if self.force_error {
763                return Err(ConnectorError::ConnectorClientError {
764                    msg: "ResponseError".to_string(),
765                    code: None,
766                }
767                .into());
768            }
769
770            let resp_json: Value =
771                serde_json::from_str(r#"{"email":"123@test.com","isEOptionsEnabled":true}"#)
772                    .unwrap_or_else(|_| serde_json::json!({}));
773            let dummy_response: models::EnableOptionsForSubAccountResponse =
774                serde_json::from_value(resp_json.clone())
775                    .expect("should parse into models::EnableOptionsForSubAccountResponse");
776
777            let dummy = DummyRestApiResponse {
778                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
779                status: 200,
780                headers: HashMap::new(),
781                rate_limits: None,
782            };
783
784            Ok(dummy.into())
785        }
786
787        async fn get_futures_position_risk_of_sub_account(
788            &self,
789            _params: GetFuturesPositionRiskOfSubAccountParams,
790        ) -> anyhow::Result<
791            RestApiResponse<Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>>,
792        > {
793            if self.force_error {
794                return Err(ConnectorError::ConnectorClientError {
795                    msg: "ResponseError".to_string(),
796                    code: None,
797                }
798                .into());
799            }
800
801            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}]"#).unwrap_or_else(|_| serde_json::json!({}));
802            let dummy_response : Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>");
803
804            let dummy = DummyRestApiResponse {
805                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
806                status: 200,
807                headers: HashMap::new(),
808                rate_limits: None,
809            };
810
811            Ok(dummy.into())
812        }
813
814        async fn get_futures_position_risk_of_sub_account_v2(
815            &self,
816            _params: GetFuturesPositionRiskOfSubAccountV2Params,
817        ) -> anyhow::Result<RestApiResponse<models::GetFuturesPositionRiskOfSubAccountV2Response>>
818        {
819            if self.force_error {
820                return Err(ConnectorError::ConnectorClientError {
821                    msg: "ResponseError".to_string(),
822                    code: None,
823                }
824                .into());
825            }
826
827            let resp_json: Value = serde_json::from_str(r#"{"futurePositionRiskVos":[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}],"deliveryPositionRiskVos":[{"entryPrice":"9975.12000","markPrice":"9973.50770517","leverage":"20","isolated":"false","isolatedWallet":"9973.50770517","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","positionAmount":"1.230","symbol":"BTCUSD_201225","unrealizedProfit":"-0.01612295"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
828            let dummy_response: models::GetFuturesPositionRiskOfSubAccountV2Response =
829                serde_json::from_value(resp_json.clone()).expect(
830                    "should parse into models::GetFuturesPositionRiskOfSubAccountV2Response",
831                );
832
833            let dummy = DummyRestApiResponse {
834                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
835                status: 200,
836                headers: HashMap::new(),
837                rate_limits: None,
838            };
839
840            Ok(dummy.into())
841        }
842
843        async fn get_sub_accounts_status_on_margin_or_futures(
844            &self,
845            _params: GetSubAccountsStatusOnMarginOrFuturesParams,
846        ) -> anyhow::Result<
847            RestApiResponse<Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>>,
848        > {
849            if self.force_error {
850                return Err(ConnectorError::ConnectorClientError {
851                    msg: "ResponseError".to_string(),
852                    code: None,
853                }
854                .into());
855            }
856
857            let resp_json: Value = serde_json::from_str(r#"[{"email":"123@test.com","isSubUserEnabled":true,"isUserActive":true,"insertTime":1570791523523,"isMarginEnabled":true,"isFutureEnabled":true,"mobile":1570791523523}]"#).unwrap_or_else(|_| serde_json::json!({}));
858            let dummy_response : Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>");
859
860            let dummy = DummyRestApiResponse {
861                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
862                status: 200,
863                headers: HashMap::new(),
864                rate_limits: None,
865            };
866
867            Ok(dummy.into())
868        }
869
870        async fn query_sub_account_list(
871            &self,
872            _params: QuerySubAccountListParams,
873        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountListResponse>> {
874            if self.force_error {
875                return Err(ConnectorError::ConnectorClientError {
876                    msg: "ResponseError".to_string(),
877                    code: None,
878                }
879                .into());
880            }
881
882            let resp_json: Value = serde_json::from_str(r#"{"subAccounts":[{"subUserId":123456,"email":"testsub@gmail.com","remark":"remark","isFreeze":false,"createTime":1544433328000,"isManagedSubAccount":false,"isAssetManagementSubAccount":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
883            let dummy_response: models::QuerySubAccountListResponse =
884                serde_json::from_value(resp_json.clone())
885                    .expect("should parse into models::QuerySubAccountListResponse");
886
887            let dummy = DummyRestApiResponse {
888                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
889                status: 200,
890                headers: HashMap::new(),
891                rate_limits: None,
892            };
893
894            Ok(dummy.into())
895        }
896
897        async fn query_sub_account_transaction_statistics(
898            &self,
899            _params: QuerySubAccountTransactionStatisticsParams,
900        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountTransactionStatisticsResponse>>
901        {
902            if self.force_error {
903                return Err(ConnectorError::ConnectorClientError {
904                    msg: "ResponseError".to_string(),
905                    code: None,
906                }
907                .into());
908            }
909
910            let resp_json: Value = serde_json::from_str(r#"{"recent30BtcTotal":"0","recent30BtcFuturesTotal":"0","recent30BtcMarginTotal":"0","recent30BusdTotal":"0","recent30BusdFuturesTotal":"0","recent30BusdMarginTotal":"0","tradeInfoVos":[{"userId":1000138138384,"btc":0,"btcFutures":0,"btcMargin":0,"busd":0,"busdFutures":0,"busdMargin":0,"date":1676851200000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
911            let dummy_response: models::QuerySubAccountTransactionStatisticsResponse =
912                serde_json::from_value(resp_json.clone()).expect(
913                    "should parse into models::QuerySubAccountTransactionStatisticsResponse",
914                );
915
916            let dummy = DummyRestApiResponse {
917                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
918                status: 200,
919                headers: HashMap::new(),
920                rate_limits: None,
921            };
922
923            Ok(dummy.into())
924        }
925    }
926
927    #[test]
928    fn create_a_virtual_sub_account_required_params_success() {
929        TOKIO_SHARED_RT.block_on(async {
930            let client = MockAccountManagementApiClient { force_error: false };
931
932            let params = CreateAVirtualSubAccountParams::builder("testSubAccount".to_string())
933                .build()
934                .unwrap();
935
936            let resp_json: Value =
937                serde_json::from_str(r#"{"email":"addsdd_virtual@aasaixwqnoemail.com"}"#)
938                    .unwrap_or_else(|_| serde_json::json!({}));
939            let expected_response: models::CreateAVirtualSubAccountResponse =
940                serde_json::from_value(resp_json.clone())
941                    .expect("should parse into models::CreateAVirtualSubAccountResponse");
942
943            let resp = client
944                .create_a_virtual_sub_account(params)
945                .await
946                .expect("Expected a response");
947            let data_future = resp.data();
948            let actual_response = data_future.await.unwrap();
949            assert_eq!(actual_response, expected_response);
950        });
951    }
952
953    #[test]
954    fn create_a_virtual_sub_account_optional_params_success() {
955        TOKIO_SHARED_RT.block_on(async {
956            let client = MockAccountManagementApiClient { force_error: false };
957
958            let params = CreateAVirtualSubAccountParams::builder("testSubAccount".to_string())
959                .recv_window(5000)
960                .build()
961                .unwrap();
962
963            let resp_json: Value =
964                serde_json::from_str(r#"{"email":"addsdd_virtual@aasaixwqnoemail.com"}"#)
965                    .unwrap_or_else(|_| serde_json::json!({}));
966            let expected_response: models::CreateAVirtualSubAccountResponse =
967                serde_json::from_value(resp_json.clone())
968                    .expect("should parse into models::CreateAVirtualSubAccountResponse");
969
970            let resp = client
971                .create_a_virtual_sub_account(params)
972                .await
973                .expect("Expected a response");
974            let data_future = resp.data();
975            let actual_response = data_future.await.unwrap();
976            assert_eq!(actual_response, expected_response);
977        });
978    }
979
980    #[test]
981    fn create_a_virtual_sub_account_response_error() {
982        TOKIO_SHARED_RT.block_on(async {
983            let client = MockAccountManagementApiClient { force_error: true };
984
985            let params = CreateAVirtualSubAccountParams::builder("testSubAccount".to_string())
986                .build()
987                .unwrap();
988
989            match client.create_a_virtual_sub_account(params).await {
990                Ok(_) => panic!("Expected an error"),
991                Err(err) => {
992                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
993                }
994            }
995        });
996    }
997
998    #[test]
999    fn enable_futures_for_sub_account_required_params_success() {
1000        TOKIO_SHARED_RT.block_on(async {
1001            let client = MockAccountManagementApiClient { force_error: false };
1002
1003            let params = EnableFuturesForSubAccountParams::builder("123@test.com".to_string())
1004                .build()
1005                .unwrap();
1006
1007            let resp_json: Value =
1008                serde_json::from_str(r#"{"email":"123@test.com","isFuturesEnabled":true}"#)
1009                    .unwrap_or_else(|_| serde_json::json!({}));
1010            let expected_response: models::EnableFuturesForSubAccountResponse =
1011                serde_json::from_value(resp_json.clone())
1012                    .expect("should parse into models::EnableFuturesForSubAccountResponse");
1013
1014            let resp = client
1015                .enable_futures_for_sub_account(params)
1016                .await
1017                .expect("Expected a response");
1018            let data_future = resp.data();
1019            let actual_response = data_future.await.unwrap();
1020            assert_eq!(actual_response, expected_response);
1021        });
1022    }
1023
1024    #[test]
1025    fn enable_futures_for_sub_account_optional_params_success() {
1026        TOKIO_SHARED_RT.block_on(async {
1027            let client = MockAccountManagementApiClient { force_error: false };
1028
1029            let params = EnableFuturesForSubAccountParams::builder("123@test.com".to_string())
1030                .recv_window(5000)
1031                .build()
1032                .unwrap();
1033
1034            let resp_json: Value =
1035                serde_json::from_str(r#"{"email":"123@test.com","isFuturesEnabled":true}"#)
1036                    .unwrap_or_else(|_| serde_json::json!({}));
1037            let expected_response: models::EnableFuturesForSubAccountResponse =
1038                serde_json::from_value(resp_json.clone())
1039                    .expect("should parse into models::EnableFuturesForSubAccountResponse");
1040
1041            let resp = client
1042                .enable_futures_for_sub_account(params)
1043                .await
1044                .expect("Expected a response");
1045            let data_future = resp.data();
1046            let actual_response = data_future.await.unwrap();
1047            assert_eq!(actual_response, expected_response);
1048        });
1049    }
1050
1051    #[test]
1052    fn enable_futures_for_sub_account_response_error() {
1053        TOKIO_SHARED_RT.block_on(async {
1054            let client = MockAccountManagementApiClient { force_error: true };
1055
1056            let params = EnableFuturesForSubAccountParams::builder("123@test.com".to_string())
1057                .build()
1058                .unwrap();
1059
1060            match client.enable_futures_for_sub_account(params).await {
1061                Ok(_) => panic!("Expected an error"),
1062                Err(err) => {
1063                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1064                }
1065            }
1066        });
1067    }
1068
1069    #[test]
1070    fn enable_options_for_sub_account_required_params_success() {
1071        TOKIO_SHARED_RT.block_on(async {
1072            let client = MockAccountManagementApiClient { force_error: false };
1073
1074            let params = EnableOptionsForSubAccountParams::builder("123@test.com".to_string())
1075                .build()
1076                .unwrap();
1077
1078            let resp_json: Value =
1079                serde_json::from_str(r#"{"email":"123@test.com","isEOptionsEnabled":true}"#)
1080                    .unwrap_or_else(|_| serde_json::json!({}));
1081            let expected_response: models::EnableOptionsForSubAccountResponse =
1082                serde_json::from_value(resp_json.clone())
1083                    .expect("should parse into models::EnableOptionsForSubAccountResponse");
1084
1085            let resp = client
1086                .enable_options_for_sub_account(params)
1087                .await
1088                .expect("Expected a response");
1089            let data_future = resp.data();
1090            let actual_response = data_future.await.unwrap();
1091            assert_eq!(actual_response, expected_response);
1092        });
1093    }
1094
1095    #[test]
1096    fn enable_options_for_sub_account_optional_params_success() {
1097        TOKIO_SHARED_RT.block_on(async {
1098            let client = MockAccountManagementApiClient { force_error: false };
1099
1100            let params = EnableOptionsForSubAccountParams::builder("123@test.com".to_string())
1101                .recv_window(5000)
1102                .build()
1103                .unwrap();
1104
1105            let resp_json: Value =
1106                serde_json::from_str(r#"{"email":"123@test.com","isEOptionsEnabled":true}"#)
1107                    .unwrap_or_else(|_| serde_json::json!({}));
1108            let expected_response: models::EnableOptionsForSubAccountResponse =
1109                serde_json::from_value(resp_json.clone())
1110                    .expect("should parse into models::EnableOptionsForSubAccountResponse");
1111
1112            let resp = client
1113                .enable_options_for_sub_account(params)
1114                .await
1115                .expect("Expected a response");
1116            let data_future = resp.data();
1117            let actual_response = data_future.await.unwrap();
1118            assert_eq!(actual_response, expected_response);
1119        });
1120    }
1121
1122    #[test]
1123    fn enable_options_for_sub_account_response_error() {
1124        TOKIO_SHARED_RT.block_on(async {
1125            let client = MockAccountManagementApiClient { force_error: true };
1126
1127            let params = EnableOptionsForSubAccountParams::builder("123@test.com".to_string())
1128                .build()
1129                .unwrap();
1130
1131            match client.enable_options_for_sub_account(params).await {
1132                Ok(_) => panic!("Expected an error"),
1133                Err(err) => {
1134                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1135                }
1136            }
1137        });
1138    }
1139
1140    #[test]
1141    fn get_futures_position_risk_of_sub_account_required_params_success() {
1142        TOKIO_SHARED_RT.block_on(async {
1143            let client = MockAccountManagementApiClient { force_error: false };
1144
1145            let params = GetFuturesPositionRiskOfSubAccountParams::builder("123@test.com".to_string(),).build().unwrap();
1146
1147            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}]"#).unwrap_or_else(|_| serde_json::json!({}));
1148            let expected_response : Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>");
1149
1150            let resp = client.get_futures_position_risk_of_sub_account(params).await.expect("Expected a response");
1151            let data_future = resp.data();
1152            let actual_response = data_future.await.unwrap();
1153            assert_eq!(actual_response, expected_response);
1154        });
1155    }
1156
1157    #[test]
1158    fn get_futures_position_risk_of_sub_account_optional_params_success() {
1159        TOKIO_SHARED_RT.block_on(async {
1160            let client = MockAccountManagementApiClient { force_error: false };
1161
1162            let params = GetFuturesPositionRiskOfSubAccountParams::builder("123@test.com".to_string(),).recv_window(5000).build().unwrap();
1163
1164            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}]"#).unwrap_or_else(|_| serde_json::json!({}));
1165            let expected_response : Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetFuturesPositionRiskOfSubAccountResponseInner>");
1166
1167            let resp = client.get_futures_position_risk_of_sub_account(params).await.expect("Expected a response");
1168            let data_future = resp.data();
1169            let actual_response = data_future.await.unwrap();
1170            assert_eq!(actual_response, expected_response);
1171        });
1172    }
1173
1174    #[test]
1175    fn get_futures_position_risk_of_sub_account_response_error() {
1176        TOKIO_SHARED_RT.block_on(async {
1177            let client = MockAccountManagementApiClient { force_error: true };
1178
1179            let params =
1180                GetFuturesPositionRiskOfSubAccountParams::builder("123@test.com".to_string())
1181                    .build()
1182                    .unwrap();
1183
1184            match client
1185                .get_futures_position_risk_of_sub_account(params)
1186                .await
1187            {
1188                Ok(_) => panic!("Expected an error"),
1189                Err(err) => {
1190                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1191                }
1192            }
1193        });
1194    }
1195
1196    #[test]
1197    fn get_futures_position_risk_of_sub_account_v2_required_params_success() {
1198        TOKIO_SHARED_RT.block_on(async {
1199            let client = MockAccountManagementApiClient { force_error: false };
1200
1201            let params = GetFuturesPositionRiskOfSubAccountV2Params::builder("123@test.com".to_string(),1,).build().unwrap();
1202
1203            let resp_json: Value = serde_json::from_str(r#"{"futurePositionRiskVos":[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}],"deliveryPositionRiskVos":[{"entryPrice":"9975.12000","markPrice":"9973.50770517","leverage":"20","isolated":"false","isolatedWallet":"9973.50770517","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","positionAmount":"1.230","symbol":"BTCUSD_201225","unrealizedProfit":"-0.01612295"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1204            let expected_response : models::GetFuturesPositionRiskOfSubAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFuturesPositionRiskOfSubAccountV2Response");
1205
1206            let resp = client.get_futures_position_risk_of_sub_account_v2(params).await.expect("Expected a response");
1207            let data_future = resp.data();
1208            let actual_response = data_future.await.unwrap();
1209            assert_eq!(actual_response, expected_response);
1210        });
1211    }
1212
1213    #[test]
1214    fn get_futures_position_risk_of_sub_account_v2_optional_params_success() {
1215        TOKIO_SHARED_RT.block_on(async {
1216            let client = MockAccountManagementApiClient { force_error: false };
1217
1218            let params = GetFuturesPositionRiskOfSubAccountV2Params::builder("123@test.com".to_string(),1,).recv_window(5000).build().unwrap();
1219
1220            let resp_json: Value = serde_json::from_str(r#"{"futurePositionRiskVos":[{"entryPrice":"9975.12000","leverage":"50","maxNotional":"1000000","liquidationPrice":"7963.54","markPrice":"9973.50770517","positionAmount":"0.010","symbol":"BTCUSDT","unrealizedProfit":"-0.01612295"}],"deliveryPositionRiskVos":[{"entryPrice":"9975.12000","markPrice":"9973.50770517","leverage":"20","isolated":"false","isolatedWallet":"9973.50770517","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","positionAmount":"1.230","symbol":"BTCUSD_201225","unrealizedProfit":"-0.01612295"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1221            let expected_response : models::GetFuturesPositionRiskOfSubAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFuturesPositionRiskOfSubAccountV2Response");
1222
1223            let resp = client.get_futures_position_risk_of_sub_account_v2(params).await.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_futures_position_risk_of_sub_account_v2_response_error() {
1232        TOKIO_SHARED_RT.block_on(async {
1233            let client = MockAccountManagementApiClient { force_error: true };
1234
1235            let params =
1236                GetFuturesPositionRiskOfSubAccountV2Params::builder("123@test.com".to_string(), 1)
1237                    .build()
1238                    .unwrap();
1239
1240            match client
1241                .get_futures_position_risk_of_sub_account_v2(params)
1242                .await
1243            {
1244                Ok(_) => panic!("Expected an error"),
1245                Err(err) => {
1246                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1247                }
1248            }
1249        });
1250    }
1251
1252    #[test]
1253    fn get_sub_accounts_status_on_margin_or_futures_required_params_success() {
1254        TOKIO_SHARED_RT.block_on(async {
1255            let client = MockAccountManagementApiClient { force_error: false };
1256
1257            let params = GetSubAccountsStatusOnMarginOrFuturesParams::builder().build().unwrap();
1258
1259            let resp_json: Value = serde_json::from_str(r#"[{"email":"123@test.com","isSubUserEnabled":true,"isUserActive":true,"insertTime":1570791523523,"isMarginEnabled":true,"isFutureEnabled":true,"mobile":1570791523523}]"#).unwrap_or_else(|_| serde_json::json!({}));
1260            let expected_response : Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>");
1261
1262            let resp = client.get_sub_accounts_status_on_margin_or_futures(params).await.expect("Expected a response");
1263            let data_future = resp.data();
1264            let actual_response = data_future.await.unwrap();
1265            assert_eq!(actual_response, expected_response);
1266        });
1267    }
1268
1269    #[test]
1270    fn get_sub_accounts_status_on_margin_or_futures_optional_params_success() {
1271        TOKIO_SHARED_RT.block_on(async {
1272            let client = MockAccountManagementApiClient { force_error: false };
1273
1274            let params = GetSubAccountsStatusOnMarginOrFuturesParams::builder().email("123@test.com".to_string()).recv_window(5000).build().unwrap();
1275
1276            let resp_json: Value = serde_json::from_str(r#"[{"email":"123@test.com","isSubUserEnabled":true,"isUserActive":true,"insertTime":1570791523523,"isMarginEnabled":true,"isFutureEnabled":true,"mobile":1570791523523}]"#).unwrap_or_else(|_| serde_json::json!({}));
1277            let expected_response : Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountsStatusOnMarginOrFuturesResponseInner>");
1278
1279            let resp = client.get_sub_accounts_status_on_margin_or_futures(params).await.expect("Expected a response");
1280            let data_future = resp.data();
1281            let actual_response = data_future.await.unwrap();
1282            assert_eq!(actual_response, expected_response);
1283        });
1284    }
1285
1286    #[test]
1287    fn get_sub_accounts_status_on_margin_or_futures_response_error() {
1288        TOKIO_SHARED_RT.block_on(async {
1289            let client = MockAccountManagementApiClient { force_error: true };
1290
1291            let params = GetSubAccountsStatusOnMarginOrFuturesParams::builder()
1292                .build()
1293                .unwrap();
1294
1295            match client
1296                .get_sub_accounts_status_on_margin_or_futures(params)
1297                .await
1298            {
1299                Ok(_) => panic!("Expected an error"),
1300                Err(err) => {
1301                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1302                }
1303            }
1304        });
1305    }
1306
1307    #[test]
1308    fn query_sub_account_list_required_params_success() {
1309        TOKIO_SHARED_RT.block_on(async {
1310            let client = MockAccountManagementApiClient { force_error: false };
1311
1312            let params = QuerySubAccountListParams::builder().build().unwrap();
1313
1314            let resp_json: Value = serde_json::from_str(r#"{"subAccounts":[{"subUserId":123456,"email":"testsub@gmail.com","remark":"remark","isFreeze":false,"createTime":1544433328000,"isManagedSubAccount":false,"isAssetManagementSubAccount":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1315            let expected_response : models::QuerySubAccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountListResponse");
1316
1317            let resp = client.query_sub_account_list(params).await.expect("Expected a response");
1318            let data_future = resp.data();
1319            let actual_response = data_future.await.unwrap();
1320            assert_eq!(actual_response, expected_response);
1321        });
1322    }
1323
1324    #[test]
1325    fn query_sub_account_list_optional_params_success() {
1326        TOKIO_SHARED_RT.block_on(async {
1327            let client = MockAccountManagementApiClient { force_error: false };
1328
1329            let params = QuerySubAccountListParams::builder().email("123@test.com".to_string()).is_freeze("true".to_string()).page(1).limit(10).recv_window(5000).build().unwrap();
1330
1331            let resp_json: Value = serde_json::from_str(r#"{"subAccounts":[{"subUserId":123456,"email":"testsub@gmail.com","remark":"remark","isFreeze":false,"createTime":1544433328000,"isManagedSubAccount":false,"isAssetManagementSubAccount":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1332            let expected_response : models::QuerySubAccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountListResponse");
1333
1334            let resp = client.query_sub_account_list(params).await.expect("Expected a response");
1335            let data_future = resp.data();
1336            let actual_response = data_future.await.unwrap();
1337            assert_eq!(actual_response, expected_response);
1338        });
1339    }
1340
1341    #[test]
1342    fn query_sub_account_list_response_error() {
1343        TOKIO_SHARED_RT.block_on(async {
1344            let client = MockAccountManagementApiClient { force_error: true };
1345
1346            let params = QuerySubAccountListParams::builder().build().unwrap();
1347
1348            match client.query_sub_account_list(params).await {
1349                Ok(_) => panic!("Expected an error"),
1350                Err(err) => {
1351                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1352                }
1353            }
1354        });
1355    }
1356
1357    #[test]
1358    fn query_sub_account_transaction_statistics_required_params_success() {
1359        TOKIO_SHARED_RT.block_on(async {
1360            let client = MockAccountManagementApiClient { force_error: false };
1361
1362            let params = QuerySubAccountTransactionStatisticsParams::builder().build().unwrap();
1363
1364            let resp_json: Value = serde_json::from_str(r#"{"recent30BtcTotal":"0","recent30BtcFuturesTotal":"0","recent30BtcMarginTotal":"0","recent30BusdTotal":"0","recent30BusdFuturesTotal":"0","recent30BusdMarginTotal":"0","tradeInfoVos":[{"userId":1000138138384,"btc":0,"btcFutures":0,"btcMargin":0,"busd":0,"busdFutures":0,"busdMargin":0,"date":1676851200000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1365            let expected_response : models::QuerySubAccountTransactionStatisticsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountTransactionStatisticsResponse");
1366
1367            let resp = client.query_sub_account_transaction_statistics(params).await.expect("Expected a response");
1368            let data_future = resp.data();
1369            let actual_response = data_future.await.unwrap();
1370            assert_eq!(actual_response, expected_response);
1371        });
1372    }
1373
1374    #[test]
1375    fn query_sub_account_transaction_statistics_optional_params_success() {
1376        TOKIO_SHARED_RT.block_on(async {
1377            let client = MockAccountManagementApiClient { force_error: false };
1378
1379            let params = QuerySubAccountTransactionStatisticsParams::builder().email("abc@test.com".to_string()).recv_window(5000).build().unwrap();
1380
1381            let resp_json: Value = serde_json::from_str(r#"{"recent30BtcTotal":"0","recent30BtcFuturesTotal":"0","recent30BtcMarginTotal":"0","recent30BusdTotal":"0","recent30BusdFuturesTotal":"0","recent30BusdMarginTotal":"0","tradeInfoVos":[{"userId":1000138138384,"btc":0,"btcFutures":0,"btcMargin":0,"busd":0,"busdFutures":0,"busdMargin":0,"date":1676851200000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1382            let expected_response : models::QuerySubAccountTransactionStatisticsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountTransactionStatisticsResponse");
1383
1384            let resp = client.query_sub_account_transaction_statistics(params).await.expect("Expected a response");
1385            let data_future = resp.data();
1386            let actual_response = data_future.await.unwrap();
1387            assert_eq!(actual_response, expected_response);
1388        });
1389    }
1390
1391    #[test]
1392    fn query_sub_account_transaction_statistics_response_error() {
1393        TOKIO_SHARED_RT.block_on(async {
1394            let client = MockAccountManagementApiClient { force_error: true };
1395
1396            let params = QuerySubAccountTransactionStatisticsParams::builder()
1397                .build()
1398                .unwrap();
1399
1400            match client
1401                .query_sub_account_transaction_statistics(params)
1402                .await
1403            {
1404                Ok(_) => panic!("Expected an error"),
1405                Err(err) => {
1406                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1407                }
1408            }
1409        });
1410    }
1411}