"""
Binance Wallet REST API

OpenAPI Specification for the Binance Wallet 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_wallet.rest_api.api import AssetApi
from binance_sdk_wallet.rest_api.models import AssetDetailResponse
from binance_sdk_wallet.rest_api.models import AssetDividendRecordResponse
from binance_sdk_wallet.rest_api.models import DustConvertResponse
from binance_sdk_wallet.rest_api.models import DustConvertibleAssetsResponse
from binance_sdk_wallet.rest_api.models import DustTransferResponse
from binance_sdk_wallet.rest_api.models import DustlogResponse
from binance_sdk_wallet.rest_api.models import FundingWalletResponse
from binance_sdk_wallet.rest_api.models import (
    GetAssetsThatCanBeConvertedIntoBnbResponse,
)
from binance_sdk_wallet.rest_api.models import (
    GetCloudMiningPaymentAndRefundHistoryResponse,
)
from binance_sdk_wallet.rest_api.models import GetOpenSymbolListResponse
from binance_sdk_wallet.rest_api.models import QueryUserDelegationHistoryResponse
from binance_sdk_wallet.rest_api.models import QueryUserUniversalTransferHistoryResponse
from binance_sdk_wallet.rest_api.models import QueryUserWalletBalanceResponse
from binance_sdk_wallet.rest_api.models import (
    ToggleBnbBurnOnSpotTradeAndMarginInterestResponse,
)
from binance_sdk_wallet.rest_api.models import TradeFeeResponse
from binance_sdk_wallet.rest_api.models import UserAssetResponse
from binance_sdk_wallet.rest_api.models import UserUniversalTransferResponse


class TestAssetApi:
    @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 = AssetApi(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_asset_detail_success(self, mock_get_signature):
        """Test asset_detail() successfully with required parameters only."""

        expected_response = {
            "CTR": {
                "minWithdrawAmount": "70.00000000",
                "depositStatus": False,
                "withdrawFee": 35,
                "withdrawStatus": True,
                "depositTip": "Delisted, Deposit Suspended",
            },
            "SKY": {
                "minWithdrawAmount": "0.02000000",
                "depositStatus": True,
                "withdrawFee": 0.01,
                "withdrawStatus": True,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.asset_detail()

        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/asset/assetDetail" 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(AssetDetailResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {
            "CTR": {
                "minWithdrawAmount": "70.00000000",
                "depositStatus": False,
                "withdrawFee": 35,
                "withdrawStatus": True,
                "depositTip": "Delisted, Deposit Suspended",
            },
            "SKY": {
                "minWithdrawAmount": "0.02000000",
                "depositStatus": True,
                "withdrawFee": 0.01,
                "withdrawStatus": True,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.asset_detail(**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/asset/assetDetail" 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(AssetDetailResponse)

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

        assert response.data() == expected

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

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

        with pytest.raises(Exception, match="ResponseError"):
            self.client.asset_detail()

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

        expected_response = {
            "rows": [
                {
                    "id": 1637366104,
                    "amount": "10.00000000",
                    "asset": "BHFT",
                    "divTime": 1563189166000,
                    "enInfo": "BHFT distribution",
                    "tranId": 2968885920,
                },
                {
                    "id": 1631750237,
                    "amount": "10.00000000",
                    "asset": "BHFT",
                    "divTime": 1563189165000,
                    "enInfo": "BHFT distribution",
                    "tranId": 2968885920,
                },
            ],
            "total": 2,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.asset_dividend_record()

        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/asset/assetDividend" 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(AssetDividendRecordResponse)

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

        assert response.data() == expected

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

        params = {
            "asset": "asset_example",
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "limit": 7,
            "recv_window": 5000,
        }

        expected_response = {
            "rows": [
                {
                    "id": 1637366104,
                    "amount": "10.00000000",
                    "asset": "BHFT",
                    "divTime": 1563189166000,
                    "enInfo": "BHFT distribution",
                    "tranId": 2968885920,
                },
                {
                    "id": 1631750237,
                    "amount": "10.00000000",
                    "asset": "BHFT",
                    "divTime": 1563189165000,
                    "enInfo": "BHFT distribution",
                    "tranId": 2968885920,
                },
            ],
            "total": 2,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.asset_dividend_record(**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/asset/assetDividend" 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(AssetDividendRecordResponse)

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

        assert response.data() == expected

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

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

        with pytest.raises(Exception, match="ResponseError"):
            self.client.asset_dividend_record()

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

        params = {
            "asset": "asset_example",
        }

        expected_response = {
            "totalTransfered": "3.5971223",
            "totalServiceCharge": "0.0794964",
            "transferResult": [
                {
                    "tranId": 2987331510,
                    "fromAsset": "USDT",
                    "amount": "1",
                    "transferedAmount": "3.5971223",
                    "serviceChargeAmount": "0.0794964",
                    "operateTime": 1765212029749,
                }
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_convert(**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/asset/dust-convert/convert" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["asset"] == "asset_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(DustConvertResponse)

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

        assert response.data() == expected

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

        params = {
            "asset": "asset_example",
            "client_id": "1",
            "target_asset": "target_asset_example",
            "third_party_client_id": "1",
            "dust_quota_asset_to_target_asset_price": 1.0,
        }

        expected_response = {
            "totalTransfered": "3.5971223",
            "totalServiceCharge": "0.0794964",
            "transferResult": [
                {
                    "tranId": 2987331510,
                    "fromAsset": "USDT",
                    "amount": "1",
                    "transferedAmount": "3.5971223",
                    "serviceChargeAmount": "0.0794964",
                    "operateTime": 1765212029749,
                }
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_convert(**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/asset/dust-convert/convert" 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(DustConvertResponse)

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

        assert response.data() == expected

    def test_dust_convert_missing_required_param_asset(self):
        """Test that dust_convert() raises RequiredError when 'asset' is missing."""
        params = {
            "asset": "asset_example",
        }
        params["asset"] = None

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

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

        params = {
            "asset": "asset_example",
        }

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

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

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

        params = {
            "target_asset": "target_asset_example",
        }

        expected_response = {
            "dribbletPercentage": "0.02",
            "totalTransferQuotaAssetAmount": "0.7899968",
            "totalTransferTargetAssetAmount": "0.7899968",
            "dribbletBase": "10",
            "details": [
                {
                    "asset": "AR",
                    "assetFullName": "AR",
                    "amountFree": "0.00856",
                    "exchange": "0.00073616",
                    "toQuotaAssetAmount": "0.036808",
                    "toTargetAssetAmount": "0.036808",
                    "toTargetAssetOffExchange": "0.03607184",
                },
                {
                    "asset": "BNB",
                    "assetFullName": "BNB",
                    "amountFree": "0.00082768",
                    "exchange": "0.01506378",
                    "toQuotaAssetAmount": "0.7531888",
                    "toTargetAssetAmount": "0.7531888",
                    "toTargetAssetOffExchange": "0.73812502",
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_convertible_assets(**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/asset/dust-convert/query-convertible-assets"
            in request_kwargs["url"]
        )
        assert request_kwargs["method"] == "POST"
        assert normalized["targetAsset"] == "target_asset_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(DustConvertibleAssetsResponse)

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

        assert response.data() == expected

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

        params = {
            "target_asset": "target_asset_example",
            "dust_quota_asset_to_target_asset_price": 1.0,
        }

        expected_response = {
            "dribbletPercentage": "0.02",
            "totalTransferQuotaAssetAmount": "0.7899968",
            "totalTransferTargetAssetAmount": "0.7899968",
            "dribbletBase": "10",
            "details": [
                {
                    "asset": "AR",
                    "assetFullName": "AR",
                    "amountFree": "0.00856",
                    "exchange": "0.00073616",
                    "toQuotaAssetAmount": "0.036808",
                    "toTargetAssetAmount": "0.036808",
                    "toTargetAssetOffExchange": "0.03607184",
                },
                {
                    "asset": "BNB",
                    "assetFullName": "BNB",
                    "amountFree": "0.00082768",
                    "exchange": "0.01506378",
                    "toQuotaAssetAmount": "0.7531888",
                    "toTargetAssetAmount": "0.7531888",
                    "toTargetAssetOffExchange": "0.73812502",
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_convertible_assets(**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/asset/dust-convert/query-convertible-assets"
            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(DustConvertibleAssetsResponse)

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

        assert response.data() == expected

    def test_dust_convertible_assets_missing_required_param_target_asset(self):
        """Test that dust_convertible_assets() raises RequiredError when 'target_asset' is missing."""
        params = {
            "target_asset": "target_asset_example",
        }
        params["target_asset"] = None

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

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

        params = {
            "target_asset": "target_asset_example",
        }

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

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

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

        params = {
            "asset": "asset_example",
        }

        expected_response = {
            "totalServiceCharge": "0.02102542",
            "totalTransfered": "1.05127099",
            "transferResult": [
                {
                    "amount": "0.03000000",
                    "fromAsset": "ETH",
                    "operateTime": 1563368549307,
                    "serviceChargeAmount": "0.00500000",
                    "tranId": 2970932918,
                    "transferedAmount": "0.25000000",
                },
                {
                    "amount": "0.09000000",
                    "fromAsset": "LTC",
                    "operateTime": 1563368549404,
                    "serviceChargeAmount": "0.01548000",
                    "tranId": 2970932918,
                    "transferedAmount": "0.77400000",
                },
                {
                    "amount": "248.61878453",
                    "fromAsset": "TRX",
                    "operateTime": 1563368549489,
                    "serviceChargeAmount": "0.00054542",
                    "tranId": 2970932918,
                    "transferedAmount": "0.02727099",
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_transfer(**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/asset/dust" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["asset"] == "asset_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(DustTransferResponse)

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

        assert response.data() == expected

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

        params = {"asset": "asset_example", "account_type": "SPOT", "recv_window": 5000}

        expected_response = {
            "totalServiceCharge": "0.02102542",
            "totalTransfered": "1.05127099",
            "transferResult": [
                {
                    "amount": "0.03000000",
                    "fromAsset": "ETH",
                    "operateTime": 1563368549307,
                    "serviceChargeAmount": "0.00500000",
                    "tranId": 2970932918,
                    "transferedAmount": "0.25000000",
                },
                {
                    "amount": "0.09000000",
                    "fromAsset": "LTC",
                    "operateTime": 1563368549404,
                    "serviceChargeAmount": "0.01548000",
                    "tranId": 2970932918,
                    "transferedAmount": "0.77400000",
                },
                {
                    "amount": "248.61878453",
                    "fromAsset": "TRX",
                    "operateTime": 1563368549489,
                    "serviceChargeAmount": "0.00054542",
                    "tranId": 2970932918,
                    "transferedAmount": "0.02727099",
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.dust_transfer(**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/asset/dust" 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(DustTransferResponse)

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

        assert response.data() == expected

    def test_dust_transfer_missing_required_param_asset(self):
        """Test that dust_transfer() raises RequiredError when 'asset' is missing."""
        params = {
            "asset": "asset_example",
        }
        params["asset"] = None

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

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

        params = {
            "asset": "asset_example",
        }

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

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

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

        expected_response = {
            "total": 8,
            "userAssetDribblets": [
                {
                    "operateTime": 1615985535000,
                    "totalTransferedAmount": "0.00132256",
                    "totalServiceChargeAmount": "0.00002699",
                    "transId": 45178372831,
                    "userAssetDribbletDetails": [
                        {
                            "transId": 4359321,
                            "serviceChargeAmount": "0.000009",
                            "amount": "0.0009",
                            "operateTime": 1615985535000,
                            "transferedAmount": "0.000441",
                            "fromAsset": "USDT",
                        },
                        {
                            "transId": 4359321,
                            "serviceChargeAmount": "0.00001799",
                            "amount": "0.0009",
                            "operateTime": 1615985535000,
                            "transferedAmount": "0.00088156",
                            "fromAsset": "ETH",
                        },
                    ],
                },
                {
                    "operateTime": 1616203180000,
                    "totalTransferedAmount": "0.00058795",
                    "totalServiceChargeAmount": "0.000012",
                    "transId": 4357015,
                    "userAssetDribbletDetails": [
                        {
                            "transId": 4357015,
                            "serviceChargeAmount": "0.00001",
                            "amount": "0.001",
                            "operateTime": 1616203180000,
                            "transferedAmount": "0.00049",
