"""
Binance Margin Trading REST API

OpenAPI Specification for the Binance Margin Trading 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_margin_trading.rest_api.api import MarketDataApi
from binance_sdk_margin_trading.rest_api.models import (
    CrossMarginCollateralRatioResponse,
)
from binance_sdk_margin_trading.rest_api.models import GetAllCrossMarginPairsResponse
from binance_sdk_margin_trading.rest_api.models import (
    GetAllIsolatedMarginSymbolResponse,
)
from binance_sdk_margin_trading.rest_api.models import GetAllMarginAssetsResponse
from binance_sdk_margin_trading.rest_api.models import GetDelistScheduleResponse
from binance_sdk_margin_trading.rest_api.models import GetLimitPricePairsResponse
from binance_sdk_margin_trading.rest_api.models import GetListScheduleResponse
from binance_sdk_margin_trading.rest_api.models import (
    QueryIsolatedMarginTierDataResponse,
)
from binance_sdk_margin_trading.rest_api.models import (
    QueryLiabilityCoinLeverageBracketInCrossMarginProModeResponse,
)
from binance_sdk_margin_trading.rest_api.models import (
    QueryMarginAvailableInventoryResponse,
)
from binance_sdk_margin_trading.rest_api.models import QueryMarginPriceindexResponse


class TestMarketDataApi:
    @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 = MarketDataApi(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

    def test_cross_margin_collateral_ratio_success(self):
        """Test cross_margin_collateral_ratio() successfully with required parameters only."""

        expected_response = [
            {
                "collaterals": [
                    {
                        "minUsdValue": "0",
                        "maxUsdValue": "13000000",
                        "discountRate": "1",
                    },
                    {
                        "minUsdValue": "13000000",
                        "maxUsdValue": "20000000",
                        "discountRate": "0.975",
                    },
                    {"minUsdValue": "20000000", "discountRate": "0"},
                ],
                "assetNames": ["BNX"],
            },
            {
                "collaterals": [{"minUsdValue": "0", "discountRate": "1"}],
                "assetNames": ["BTC", "BUSD", "ETH", "USDT"],
            },
        ]

        self.set_mock_response(expected_response)

        response = self.client.cross_margin_collateral_ratio()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/crossMarginCollateralRatio" 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(CrossMarginCollateralRatioResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_all_cross_margin_pairs_success(self):
        """Test get_all_cross_margin_pairs() successfully with required parameters only."""

        expected_response = [
            {
                "base": "BNB",
                "id": 351637150141315840,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "BNBBTC",
            },
            {
                "base": "TRX",
                "id": 351637923235429100,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "TRXBTC",
                "delistTime": 1704973040,
            },
            {
                "base": "XRP",
                "id": 351638112213990140,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "XRPBTC",
            },
            {
                "base": "ETH",
                "id": 351638524530850560,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "ETHBTC",
            },
        ]

        self.set_mock_response(expected_response)

        response = self.client.get_all_cross_margin_pairs()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/allPairs" 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(GetAllCrossMarginPairsResponse)

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

        assert response.data() == expected

    def test_get_all_cross_margin_pairs_success_with_optional_params(self):
        """Test get_all_cross_margin_pairs() successfully with optional parameters."""

        params = {"symbol": "symbol_example"}

        expected_response = [
            {
                "base": "BNB",
                "id": 351637150141315840,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "BNBBTC",
            },
            {
                "base": "TRX",
                "id": 351637923235429100,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "TRXBTC",
                "delistTime": 1704973040,
            },
            {
                "base": "XRP",
                "id": 351638112213990140,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "XRPBTC",
            },
            {
                "base": "ETH",
                "id": 351638524530850560,
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "ETHBTC",
            },
        ]

        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/allPairs" 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(GetAllCrossMarginPairsResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_all_isolated_margin_symbol_success(self):
        """Test get_all_isolated_margin_symbol() successfully with required parameters only."""

        expected_response = [
            {
                "base": "BNB",
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "BNBBTC",
            },
            {
                "base": "TRX",
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "TRXBTC",
            },
        ]

        self.set_mock_response(expected_response)

        response = self.client.get_all_isolated_margin_symbol()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/isolated/allPairs" 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(GetAllIsolatedMarginSymbolResponse)

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

        assert response.data() == expected

    def test_get_all_isolated_margin_symbol_success_with_optional_params(self):
        """Test get_all_isolated_margin_symbol() successfully with optional parameters."""

        params = {"symbol": "symbol_example", "recv_window": 5000}

        expected_response = [
            {
                "base": "BNB",
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "BNBBTC",
            },
            {
                "base": "TRX",
                "isBuyAllowed": True,
                "isMarginTrade": True,
                "isSellAllowed": True,
                "quote": "BTC",
                "symbol": "TRXBTC",
            },
        ]

        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/isolated/allPairs" 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(GetAllIsolatedMarginSymbolResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_all_margin_assets_success(self):
        """Test get_all_margin_assets() successfully with required parameters only."""

        expected_response = [
            {
                "assetFullName": "USD coin",
                "assetName": "USDC",
                "isBorrowable": True,
                "isMortgageable": True,
                "userMinBorrow": "0.00000000",
                "userMinRepay": "0.00000000",
                "delistTime": 1704973040,
            }
        ]

        self.set_mock_response(expected_response)

        response = self.client.get_all_margin_assets()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/allAssets" 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(GetAllMarginAssetsResponse)

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

        assert response.data() == expected

    def test_get_all_margin_assets_success_with_optional_params(self):
        """Test get_all_margin_assets() successfully with optional parameters."""

        params = {"asset": "asset_example"}

        expected_response = [
            {
                "assetFullName": "USD coin",
                "assetName": "USDC",
                "isBorrowable": True,
                "isMortgageable": True,
                "userMinBorrow": "0.00000000",
                "userMinRepay": "0.00000000",
                "delistTime": 1704973040,
            }
        ]

        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/allAssets" 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(GetAllMarginAssetsResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_delist_schedule_success(self):
        """Test get_delist_schedule() successfully with required parameters only."""

        expected_response = [
            {
                "delistTime": 1686161202000,
                "crossMarginAssets": ["BTC", "USDT"],
                "isolatedMarginSymbols": ["ADAUSDT", "BNBUSDT"],
            },
            {
                "delistTime": 1686222232000,
                "crossMarginAssets": ["ADA"],
                "isolatedMarginSymbols": [],
            },
        ]

        self.set_mock_response(expected_response)

        response = self.client.get_delist_schedule()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/delist-schedule" 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(GetDelistScheduleResponse)

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

        assert response.data() == expected

    def test_get_delist_schedule_success_with_optional_params(self):
        """Test get_delist_schedule() successfully with optional parameters."""

        params = {"recv_window": 5000}

        expected_response = [
            {
                "delistTime": 1686161202000,
                "crossMarginAssets": ["BTC", "USDT"],
                "isolatedMarginSymbols": ["ADAUSDT", "BNBUSDT"],
            },
            {
                "delistTime": 1686222232000,
                "crossMarginAssets": ["ADA"],
                "isolatedMarginSymbols": [],
            },
        ]

        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/delist-schedule" 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(GetDelistScheduleResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_limit_price_pairs_success(self):
        """Test get_limit_price_pairs() successfully with required parameters only."""

        expected_response = {
            "crossMarginSymbols": [
                "BLURUSDC",
                "SANDBTC",
                "QKCBTC",
                "SEIFDUSD",
                "NEOUSDC",
                "ARBFDUSD",
                "ORDIUSDC",
            ]
        }

        self.set_mock_response(expected_response)

        response = self.client.get_limit_price_pairs()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/limit-price-pairs" 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(GetLimitPricePairsResponse)

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

        assert response.data() == expected

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

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

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

    def test_get_list_schedule_success(self):
        """Test get_list_schedule() successfully with required parameters only."""

        expected_response = [
            {
                "listTime": 1686161202000,
                "crossMarginAssets": ["BTC", "USDT"],
                "isolatedMarginSymbols": ["ADAUSDT", "BNBUSDT"],
            },
            {
                "listTime": 1686222232000,
                "crossMarginAssets": ["ADA"],
                "isolatedMarginSymbols": [],
            },
        ]

        self.set_mock_response(expected_response)

        response = self.client.get_list_schedule()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/list-schedule" 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(GetListScheduleResponse)

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

        assert response.data() == expected

    def test_get_list_schedule_success_with_optional_params(self):
        """Test get_list_schedule() successfully with optional parameters."""

        params = {"recv_window": 5000}

        expected_response = [
            {
                "listTime": 1686161202000,
                "crossMarginAssets": ["BTC", "USDT"],
                "isolatedMarginSymbols": ["ADAUSDT", "BNBUSDT"],
            },
            {
                "listTime": 1686222232000,
                "crossMarginAssets": ["ADA"],
                "isolatedMarginSymbols": [],
            },
        ]

        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "/sapi/v1/margin/list-schedule" 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(GetListScheduleResponse)

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

        assert response.data() == expected

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

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

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

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

        params = {
            "symbol": "symbol_example",
        }

        expected_response = [
            {
                "symbol": "BTCUSDT",
                "tier": 1,
                "effectiveMultiple": "10",
                "initialRiskRatio": "1.111",
                "liquidationRiskRatio": "1.05",
                "baseAssetMaxBorrowable": "9",
                "quoteAssetMaxBorrowable": "70000",
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_isolated_margin_tier_data(**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/margin/isolatedMarginTier" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["symbol"] == "symbol_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(QueryIsolatedMarginTierDataResponse)

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

        assert response.data() == expected

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

        params = {"symbol": "symbol_example", "tier": 56, "recv_window": 5000}

        expected_response = [
            {
                "symbol": "BTCUSDT",
                "tier": 1,
                "effectiveMultiple": "10",
                "initialRiskRatio": "1.111",
                "liquidationRiskRatio": "1.05",
                "baseAssetMaxBorrowable": "9",
                "quoteAssetMaxBorrowable": "70000",
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.query_isolated_margin_tier_data(**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/margin/isolatedMarginTier" 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(QueryIsolatedMarginTierDataResponse)

        if is_list and not is_flat_list:
            expected = expected_response
        elif (
            is_oneof
            or is_list
            or hasattr(QueryIsolatedMarginTierDataResponse, "from_dict")
        ):
            expected = QueryIsolatedMarginTierDataResponse.from_dict(expected_response)
