"""
Binance Sub Account REST API

OpenAPI Specification for the Binance Sub Account REST API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

import json
import pytest
import requests

from unittest.mock import MagicMock, patch
from urllib.parse import parse_qs

from binance_common.configuration import ConfigurationRestAPI
from binance_common.errors import RequiredError
from binance_common.utils import normalize_query_values, is_one_of_model, snake_to_camel

from binance_sdk_sub_account.rest_api.api import ManagedSubAccountApi
from binance_sdk_sub_account.rest_api.models import (
    DepositAssetsIntoTheManagedSubAccountResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    GetManagedSubAccountDepositAddressResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountAssetDetailsResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountFuturesAssetDetailsResponse,
)
from binance_sdk_sub_account.rest_api.models import QueryManagedSubAccountListResponse
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountMarginAssetDetailsResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountSnapshotResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountTransferLogMasterAccountInvestorResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountTransferLogMasterAccountTradingResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    QueryManagedSubAccountTransferLogSubAccountTradingResponse,
)
from binance_sdk_sub_account.rest_api.models import (
    WithdrawlAssetsFromTheManagedSubAccountResponse,
)


class TestManagedSubAccountApi:
    @pytest.fixture(autouse=True)
    def setup_client(self):
        """Setup a client instance with mocked session before each test method."""
        self.mock_session = MagicMock(spec=requests.Session)
        config = ConfigurationRestAPI(
            api_key="test-api-key",
            api_secret="test-api-secret",
        )
        self.client = ManagedSubAccountApi(
            configuration=config, session=self.mock_session
        )

    def set_mock_response(self, data: dict = {}, status_code=200, headers=None):
        """Helper method to setup mock response for the client's session request."""
        if headers is None:
            headers = {}

        mock_response = MagicMock()
        mock_response.status_code = status_code
        mock_response.json.return_value = data
        mock_response.text = json.dumps(data)
        mock_response.headers = headers

        self.mock_session.request.return_value = mock_response

    @patch("binance_common.utils.get_signature")
    def test_deposit_assets_into_the_managed_sub_account_success(
        self, mock_get_signature
    ):
        """Test deposit_assets_into_the_managed_sub_account() successfully with required parameters only."""

        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
        }

        expected_response = {"tranId": 66157362489}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_assets_into_the_managed_sub_account(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs
        parsed_params = parse_qs(request_kwargs["params"])
        camel_case_params = {snake_to_camel(k): v for k, v in params.items()}
        normalized = normalize_query_values(parsed_params, camel_case_params)

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/deposit" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["toEmail"] == "to_email_example"
        assert normalized["asset"] == "asset_example"
        assert normalized["amount"] == 1.0

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(DepositAssetsIntoTheManagedSubAccountResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(DepositAssetsIntoTheManagedSubAccountResponse, "from_dict")
        ):
            expected = DepositAssetsIntoTheManagedSubAccountResponse.from_dict(
                expected_response
            )
        else:
            expected = (
                DepositAssetsIntoTheManagedSubAccountResponse.model_validate_json(
                    json.dumps(expected_response)
                )
            )

        assert response.data() == expected

    @patch("binance_common.utils.get_signature")
    def test_deposit_assets_into_the_managed_sub_account_success_with_optional_params(
        self, mock_get_signature
    ):
        """Test deposit_assets_into_the_managed_sub_account() successfully with optional parameters."""

        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
            "recv_window": 5000,
        }

        expected_response = {"tranId": 66157362489}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_assets_into_the_managed_sub_account(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/deposit" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        self.mock_session.request.assert_called_once()
        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(DepositAssetsIntoTheManagedSubAccountResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(DepositAssetsIntoTheManagedSubAccountResponse, "from_dict")
        ):
            expected = DepositAssetsIntoTheManagedSubAccountResponse.from_dict(
                expected_response
            )
        else:
            expected = (
                DepositAssetsIntoTheManagedSubAccountResponse.model_validate_json(
                    json.dumps(expected_response)
                )
            )

        assert response.data() == expected

    def test_deposit_assets_into_the_managed_sub_account_missing_required_param_to_email(
        self,
    ):
        """Test that deposit_assets_into_the_managed_sub_account() raises RequiredError when 'to_email' is missing."""
        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
        }
        params["to_email"] = None

        with pytest.raises(
            RequiredError, match="Missing required parameter 'to_email'"
        ):
            self.client.deposit_assets_into_the_managed_sub_account(**params)

    def test_deposit_assets_into_the_managed_sub_account_missing_required_param_asset(
        self,
    ):
        """Test that deposit_assets_into_the_managed_sub_account() raises RequiredError when 'asset' is missing."""
        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
        }
        params["asset"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'asset'"):
            self.client.deposit_assets_into_the_managed_sub_account(**params)

    def test_deposit_assets_into_the_managed_sub_account_missing_required_param_amount(
        self,
    ):
        """Test that deposit_assets_into_the_managed_sub_account() raises RequiredError when 'amount' is missing."""
        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
        }
        params["amount"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'amount'"):
            self.client.deposit_assets_into_the_managed_sub_account(**params)

    def test_deposit_assets_into_the_managed_sub_account_server_error(self):
        """Test that deposit_assets_into_the_managed_sub_account() raises an error when the server returns an error."""

        params = {
            "to_email": "to_email_example",
            "asset": "asset_example",
            "amount": 1.0,
        }

        mock_error = Exception("ResponseError")
        self.client.deposit_assets_into_the_managed_sub_account = MagicMock(
            side_effect=mock_error
        )

        with pytest.raises(Exception, match="ResponseError"):
            self.client.deposit_assets_into_the_managed_sub_account(**params)

    @patch("binance_common.utils.get_signature")
    def test_get_managed_sub_account_deposit_address_success(self, mock_get_signature):
        """Test get_managed_sub_account_deposit_address() successfully with required parameters only."""

        params = {
            "email": "sub-account-email@email.com",
            "coin": "coin_example",
        }

        expected_response = {
            "coin": "USDT",
            "address": "0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d",
            "tag": "",
            "url": "https://etherscan.io/address/0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.get_managed_sub_account_deposit_address(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs
        parsed_params = parse_qs(request_kwargs["params"])
        camel_case_params = {snake_to_camel(k): v for k, v in params.items()}
        normalized = normalize_query_values(parsed_params, camel_case_params)

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/deposit/address" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["email"] == "sub-account-email@email.com"
        assert normalized["coin"] == "coin_example"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(GetManagedSubAccountDepositAddressResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(GetManagedSubAccountDepositAddressResponse, "from_dict")
        ):
            expected = GetManagedSubAccountDepositAddressResponse.from_dict(
                expected_response
            )
        else:
            expected = GetManagedSubAccountDepositAddressResponse.model_validate_json(
                json.dumps(expected_response)
            )

        assert response.data() == expected

    @patch("binance_common.utils.get_signature")
    def test_get_managed_sub_account_deposit_address_success_with_optional_params(
        self, mock_get_signature
    ):
        """Test get_managed_sub_account_deposit_address() successfully with optional parameters."""

        params = {
            "email": "sub-account-email@email.com",
            "coin": "coin_example",
            "network": "network_example",
            "amount": 1.0,
            "recv_window": 5000,
        }

        expected_response = {
            "coin": "USDT",
            "address": "0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d",
            "tag": "",
            "url": "https://etherscan.io/address/0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.get_managed_sub_account_deposit_address(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/deposit/address" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        self.mock_session.request.assert_called_once()
        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(GetManagedSubAccountDepositAddressResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(GetManagedSubAccountDepositAddressResponse, "from_dict")
        ):
            expected = GetManagedSubAccountDepositAddressResponse.from_dict(
                expected_response
            )
        else:
            expected = GetManagedSubAccountDepositAddressResponse.model_validate_json(
                json.dumps(expected_response)
            )

        assert response.data() == expected

    def test_get_managed_sub_account_deposit_address_missing_required_param_email(self):
        """Test that get_managed_sub_account_deposit_address() raises RequiredError when 'email' is missing."""
        params = {
            "email": "sub-account-email@email.com",
            "coin": "coin_example",
        }
        params["email"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'email'"):
            self.client.get_managed_sub_account_deposit_address(**params)

    def test_get_managed_sub_account_deposit_address_missing_required_param_coin(self):
        """Test that get_managed_sub_account_deposit_address() raises RequiredError when 'coin' is missing."""
        params = {
            "email": "sub-account-email@email.com",
            "coin": "coin_example",
        }
        params["coin"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'coin'"):
            self.client.get_managed_sub_account_deposit_address(**params)

    def test_get_managed_sub_account_deposit_address_server_error(self):
        """Test that get_managed_sub_account_deposit_address() raises an error when the server returns an error."""

        params = {
            "email": "sub-account-email@email.com",
            "coin": "coin_example",
        }

        mock_error = Exception("ResponseError")
        self.client.get_managed_sub_account_deposit_address = MagicMock(
            side_effect=mock_error
        )

        with pytest.raises(Exception, match="ResponseError"):
            self.client.get_managed_sub_account_deposit_address(**params)

    @patch("binance_common.utils.get_signature")
    def test_query_managed_sub_account_asset_details_success(self, mock_get_signature):
        """Test query_managed_sub_account_asset_details() successfully with required parameters only."""

        params = {
            "email": "sub-account-email@email.com",
        }

        expected_response = [
            {
                "coin": "INJ",
                "name": "Injective Protocol",
                "totalBalance": "0",
                "availableBalance": "0",
                "inOrder": "0",
                "btcValue": "0",
            },
            {
                "coin": "FILDOWN",
                "name": "FILDOWN",
                "totalBalance": "0",
                "availableBalance": "0",
                "inOrder": "0",
                "btcValue": "0",
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_managed_sub_account_asset_details(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs
        parsed_params = parse_qs(request_kwargs["params"])
        camel_case_params = {snake_to_camel(k): v for k, v in params.items()}
        normalized = normalize_query_values(parsed_params, camel_case_params)

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/asset" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["email"] == "sub-account-email@email.com"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(QueryManagedSubAccountAssetDetailsResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryManagedSubAccountAssetDetailsResponse, "from_dict")
        ):
            expected = QueryManagedSubAccountAssetDetailsResponse.from_dict(
                expected_response
            )
        else:
            expected = QueryManagedSubAccountAssetDetailsResponse.model_validate_json(
                json.dumps(expected_response)
            )

        assert response.data() == expected

    @patch("binance_common.utils.get_signature")
    def test_query_managed_sub_account_asset_details_success_with_optional_params(
        self, mock_get_signature
    ):
        """Test query_managed_sub_account_asset_details() successfully with optional parameters."""

        params = {"email": "sub-account-email@email.com", "recv_window": 5000}

        expected_response = [
            {
                "coin": "INJ",
                "name": "Injective Protocol",
                "totalBalance": "0",
                "availableBalance": "0",
                "inOrder": "0",
                "btcValue": "0",
            },
            {
                "coin": "FILDOWN",
                "name": "FILDOWN",
                "totalBalance": "0",
                "availableBalance": "0",
                "inOrder": "0",
                "btcValue": "0",
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_managed_sub_account_asset_details(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/asset" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        self.mock_session.request.assert_called_once()
        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(QueryManagedSubAccountAssetDetailsResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryManagedSubAccountAssetDetailsResponse, "from_dict")
        ):
            expected = QueryManagedSubAccountAssetDetailsResponse.from_dict(
                expected_response
            )
        else:
            expected = QueryManagedSubAccountAssetDetailsResponse.model_validate_json(
                json.dumps(expected_response)
            )

        assert response.data() == expected

    def test_query_managed_sub_account_asset_details_missing_required_param_email(self):
        """Test that query_managed_sub_account_asset_details() raises RequiredError when 'email' is missing."""
        params = {
            "email": "sub-account-email@email.com",
        }
        params["email"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'email'"):
            self.client.query_managed_sub_account_asset_details(**params)

    def test_query_managed_sub_account_asset_details_server_error(self):
        """Test that query_managed_sub_account_asset_details() raises an error when the server returns an error."""

        params = {
            "email": "sub-account-email@email.com",
        }

        mock_error = Exception("ResponseError")
        self.client.query_managed_sub_account_asset_details = MagicMock(
            side_effect=mock_error
        )

        with pytest.raises(Exception, match="ResponseError"):
            self.client.query_managed_sub_account_asset_details(**params)

    @patch("binance_common.utils.get_signature")
    def test_query_managed_sub_account_futures_asset_details_success(
        self, mock_get_signature
    ):
        """Test query_managed_sub_account_futures_asset_details() successfully with required parameters only."""

        params = {
            "email": "sub-account-email@email.com",
        }

        expected_response = {
            "code": "200",
            "message": "OK",
            "snapshotVos": [
                {
                    "type": "FUTURES",
                    "updateTime": 1672893855394,
                    "data": {
                        "assets": [
                            {
                                "asset": "USDT",
                                "marginBalance": 100,
                                "walletBalance": 120,
                            }
                        ],
                        "position": [
                            {
                                "symbol": "BTCUSDT",
                                "entryPrice": 17000,
                                "markPrice": 17000,
                                "positionAmt": 1.0e-4,
                            }
                        ],
                    },
                }
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_managed_sub_account_futures_asset_details(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs
        parsed_params = parse_qs(request_kwargs["params"])
        camel_case_params = {snake_to_camel(k): v for k, v in params.items()}
        normalized = normalize_query_values(parsed_params, camel_case_params)

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/fetch-future-asset" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["email"] == "sub-account-email@email.com"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(QueryManagedSubAccountFuturesAssetDetailsResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryManagedSubAccountFuturesAssetDetailsResponse, "from_dict")
        ):
            expected = QueryManagedSubAccountFuturesAssetDetailsResponse.from_dict(
                expected_response
            )
        else:
            expected = (
                QueryManagedSubAccountFuturesAssetDetailsResponse.model_validate_json(
                    json.dumps(expected_response)
                )
            )

        assert response.data() == expected

    @patch("binance_common.utils.get_signature")
    def test_query_managed_sub_account_futures_asset_details_success_with_optional_params(
        self, mock_get_signature
    ):
        """Test query_managed_sub_account_futures_asset_details() successfully with optional parameters."""

        params = {
            "email": "sub-account-email@email.com",
            "account_type": "account_type_example",
        }

        expected_response = {
            "code": "200",
            "message": "OK",
            "snapshotVos": [
                {
                    "type": "FUTURES",
                    "updateTime": 1672893855394,
                    "data": {
                        "assets": [
                            {
                                "asset": "USDT",
                                "marginBalance": 100,
                                "walletBalance": 120,
                            }
                        ],
                        "position": [
                            {
                                "symbol": "BTCUSDT",
                                "entryPrice": 17000,
                                "markPrice": 17000,
                                "positionAmt": 1.0e-4,
                            }
                        ],
                    },
                }
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_managed_sub_account_futures_asset_details(**params)

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/fetch-future-asset" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        self.mock_session.request.assert_called_once()
        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(QueryManagedSubAccountFuturesAssetDetailsResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryManagedSubAccountFuturesAssetDetailsResponse, "from_dict")
        ):
            expected = QueryManagedSubAccountFuturesAssetDetailsResponse.from_dict(
                expected_response
            )
        else:
            expected = (
                QueryManagedSubAccountFuturesAssetDetailsResponse.model_validate_json(
                    json.dumps(expected_response)
                )
            )

        assert response.data() == expected

    def test_query_managed_sub_account_futures_asset_details_missing_required_param_email(
        self,
    ):
        """Test that query_managed_sub_account_futures_asset_details() raises RequiredError when 'email' is missing."""
        params = {
            "email": "sub-account-email@email.com",
        }
        params["email"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'email'"):
            self.client.query_managed_sub_account_futures_asset_details(**params)

    def test_query_managed_sub_account_futures_asset_details_server_error(self):
        """Test that query_managed_sub_account_futures_asset_details() raises an error when the server returns an error."""

        params = {
            "email": "sub-account-email@email.com",
        }

        mock_error = Exception("ResponseError")
        self.client.query_managed_sub_account_futures_asset_details = MagicMock(
            side_effect=mock_error
        )

        with pytest.raises(Exception, match="ResponseError"):
            self.client.query_managed_sub_account_futures_asset_details(**params)

    @patch("binance_common.utils.get_signature")
    def test_query_managed_sub_account_list_success(self, mock_get_signature):
        """Test query_managed_sub_account_list() successfully with required parameters only."""

        expected_response = {
            "total": 3,
            "managerSubUserInfoVoList": [
                {
                    "rootUserId": 1000138475670,
                    "managersubUserId": 1000137842513,
                    "bindParentUserId": 1000138475669,
                    "email": "test_0_virtual@kq3kno9imanagedsub.com",
                    "insertTimeStamp": 1678435149000,
                    "bindParentEmail": "wdyw8xsh8pey@test.com",
                    "isSubUserEnabled": True,
                    "isUserActive": True,
                    "isMarginEnabled": False,
                    "isFutureEnabled": False,
                    "isSignedLVTRiskAgreement": False,
                },
                {
                    "rootUserId": 1000138475670,
                    "managersubUserId": 1000137842514,
                    "bindParentUserId": 1000138475669,
                    "email": "test_1_virtual@4qd2u7zxmanagedsub.com",
                    "insertTimeStamp": 1678435152000,
                    "bindParentEmail": "wdyw8xsh8pey@test.com",
                    "isSubUserEnabled": True,
                    "isUserActive": True,
                    "isMarginEnabled": False,
                    "isFutureEnabled": False,
                    "isSignedLVTRiskAgreement": False,
                },
                {
                    "rootUserId": 1000138475670,
                    "managersubUserId": 1000137842515,
                    "bindParentUserId": 1000138475669,
                    "email": "test_2_virtual@akc05o8hmanagedsub.com",
                    "insertTimeStamp": 1678435153000,
                    "bindParentEmail": "wdyw8xsh8pey@test.com",
                    "isSubUserEnabled": True,
                    "isUserActive": True,
                    "isMarginEnabled": False,
                    "isFutureEnabled": False,
                    "isSignedLVTRiskAgreement": False,
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_managed_sub_account_list()

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/managed-subaccount/info" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(QueryManagedSubAccountListResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryManagedSubAccountListResponse, "from_dict")
        ):
            expected = QueryManagedSubAccountListResponse.from_dict(expected_response)
        else:
            expected = QueryManagedSubAccountListResponse.model_validate_json(
                json.dumps(expected_response)
            )

        assert response.data() == expected

    @patch("binance_common.utils.get_signature")
