"""
Binance Derivatives Trading USDS Futures REST API

OpenAPI Specification for the Binance Derivatives Trading USDS Futures 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_derivatives_trading_usds_futures.rest_api.api import TradeApi
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    AccountTradeListResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    AllOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    AutoCancelAllOpenOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CancelAlgoOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CancelAllAlgoOpenOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CancelAllOpenOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CancelMultipleOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CancelOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ChangeInitialLeverageResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ChangeMarginTypeResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ChangeMultiAssetsModeResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ChangePositionModeResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CurrentAllAlgoOpenOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    CurrentAllOpenOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    FuturesTradfiPerpsContractResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    GetOrderModifyHistoryResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    GetPositionMarginChangeHistoryResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyIsolatedPositionMarginResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyMultipleOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    PlaceMultipleOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    PositionAdlQuantileEstimationResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    PositionInformationV2Response,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    PositionInformationV3Response,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    QueryAlgoOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    QueryAllAlgoOrdersResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    QueryCurrentOpenOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    QueryOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderResponse,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    UsersForceOrdersResponse,
)


from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ChangeMarginTypeMarginTypeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyIsolatedPositionMarginPositionSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyOrderSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderPositionSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderTimeInForceEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderWorkingTypeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewAlgoOrderSelfTradePreventionModeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderPositionSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderTimeInForceEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderNewOrderRespTypeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    NewOrderSelfTradePreventionModeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderPositionSideEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderTimeInForceEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderWorkingTypeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderNewOrderRespTypeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    TestOrderSelfTradePreventionModeEnum,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    UsersForceOrdersAutoCloseTypeEnum,
)

from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    ModifyMultipleOrdersBatchOrdersParameterInner,
)
from binance_sdk_derivatives_trading_usds_futures.rest_api.models import (
    PlaceMultipleOrdersBatchOrdersParameterInner,
)


class TestTradeApi:
    @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 = TradeApi(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_account_trade_list_success(self, mock_get_signature):
        """Test account_trade_list() successfully with required parameters only."""

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

        expected_response = [
            {
                "buyer": False,
                "commission": "-0.07819010",
                "commissionAsset": "USDT",
                "id": 698759,
                "maker": False,
                "orderId": 25851813,
                "price": "7819.01",
                "qty": "0.002",
                "quoteQty": "15.63802",
                "realizedPnl": "-0.91539999",
                "side": "SELL",
                "positionSide": "SHORT",
                "symbol": "BTCUSDT",
                "time": 1569514978020,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_trade_list(**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 "/fapi/v1/userTrades" 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(AccountTradeListResponse)

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

        assert response.data() == expected

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

        params = {
            "symbol": "symbol_example",
            "order_id": 1,
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "from_id": 1,
            "limit": 100,
            "recv_window": 5000,
        }

        expected_response = [
            {
                "buyer": False,
                "commission": "-0.07819010",
                "commissionAsset": "USDT",
                "id": 698759,
                "maker": False,
                "orderId": 25851813,
                "price": "7819.01",
                "qty": "0.002",
                "quoteQty": "15.63802",
                "realizedPnl": "-0.91539999",
                "side": "SELL",
                "positionSide": "SHORT",
                "symbol": "BTCUSDT",
                "time": 1569514978020,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_trade_list(**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 "/fapi/v1/userTrades" 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(AccountTradeListResponse)

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

        assert response.data() == expected

    def test_account_trade_list_missing_required_param_symbol(self):
        """Test that account_trade_list() raises RequiredError when 'symbol' is missing."""
        params = {
            "symbol": "symbol_example",
        }
        params["symbol"] = None

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

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

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

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

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

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

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

        expected_response = [
            {
                "avgPrice": "0.00000",
                "clientOrderId": "abc",
                "cumQuote": "0",
                "executedQty": "0",
                "orderId": 1917641,
                "origQty": "0.40",
                "origType": "TRAILING_STOP_MARKET",
                "price": "0",
                "reduceOnly": False,
                "side": "BUY",
                "positionSide": "SHORT",
                "status": "NEW",
                "stopPrice": "9300",
                "closePosition": False,
                "symbol": "BTCUSDT",
                "time": 1579276756075,
                "timeInForce": "GTC",
                "type": "TRAILING_STOP_MARKET",
                "activatePrice": "9020",
                "priceRate": "0.3",
                "updateTime": 1579276756075,
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "priceMatch": "NONE",
                "selfTradePreventionMode": "NONE",
                "goodTillDate": 0,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.all_orders(**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 "/fapi/v1/allOrders" 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(AllOrdersResponse)

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

        assert response.data() == expected

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

        params = {
            "symbol": "symbol_example",
            "order_id": 1,
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "limit": 100,
            "recv_window": 5000,
        }

        expected_response = [
            {
                "avgPrice": "0.00000",
                "clientOrderId": "abc",
                "cumQuote": "0",
                "executedQty": "0",
                "orderId": 1917641,
                "origQty": "0.40",
                "origType": "TRAILING_STOP_MARKET",
                "price": "0",
                "reduceOnly": False,
                "side": "BUY",
                "positionSide": "SHORT",
                "status": "NEW",
                "stopPrice": "9300",
                "closePosition": False,
                "symbol": "BTCUSDT",
                "time": 1579276756075,
                "timeInForce": "GTC",
                "type": "TRAILING_STOP_MARKET",
                "activatePrice": "9020",
                "priceRate": "0.3",
                "updateTime": 1579276756075,
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "priceMatch": "NONE",
                "selfTradePreventionMode": "NONE",
                "goodTillDate": 0,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.all_orders(**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 "/fapi/v1/allOrders" 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(AllOrdersResponse)

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

        assert response.data() == expected

    def test_all_orders_missing_required_param_symbol(self):
        """Test that all_orders() raises RequiredError when 'symbol' is missing."""
        params = {
            "symbol": "symbol_example",
        }
        params["symbol"] = None

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

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

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

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

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

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

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

        expected_response = {"symbol": "BTCUSDT", "countdownTime": "100000"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.auto_cancel_all_open_orders(**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 "/fapi/v1/countdownCancelAll" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["symbol"] == "symbol_example"
        assert normalized["countdownTime"] == 56

        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(AutoCancelAllOpenOrdersResponse)

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

        assert response.data() == expected

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

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

        expected_response = {"symbol": "BTCUSDT", "countdownTime": "100000"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.auto_cancel_all_open_orders(**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 "/fapi/v1/countdownCancelAll" 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(AutoCancelAllOpenOrdersResponse)

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

        assert response.data() == expected

    def test_auto_cancel_all_open_orders_missing_required_param_symbol(self):
        """Test that auto_cancel_all_open_orders() raises RequiredError when 'symbol' is missing."""
        params = {
            "symbol": "symbol_example",
            "countdown_time": 56,
        }
        params["symbol"] = None

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

    def test_auto_cancel_all_open_orders_missing_required_param_countdown_time(self):
        """Test that auto_cancel_all_open_orders() raises RequiredError when 'countdown_time' is missing."""
        params = {
            "symbol": "symbol_example",
            "countdown_time": 56,
        }
        params["countdown_time"] = None

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

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

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

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

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

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

        expected_response = {
            "algoId": 2146760,
            "clientAlgoId": "6B2I9XVcJpCjqPAJ4YoFX7",
            "code": "200",
            "msg": "success",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_algo_order()

        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 "/fapi/v1/algoOrder" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"

        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(CancelAlgoOrderResponse)

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

        assert response.data() == expected

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

        params = {
            "algoid": 56,
            "clientalgoid": "clientalgoid_example",
            "recv_window": 5000,
        }

        expected_response = {
            "algoId": 2146760,
            "clientAlgoId": "6B2I9XVcJpCjqPAJ4YoFX7",
            "code": "200",
            "msg": "success",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_algo_order(**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 "/fapi/v1/algoOrder" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"

        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(CancelAlgoOrderResponse)

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

        assert response.data() == expected

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

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

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

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

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

        expected_response = {
            "code": 200,
            "msg": "The operation of cancel all open order is done.",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_all_algo_open_orders(**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 "/fapi/v1/algoOpenOrders" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"
        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(CancelAllAlgoOpenOrdersResponse)

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

        assert response.data() == expected

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

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

        expected_response = {
            "code": 200,
            "msg": "The operation of cancel all open order is done.",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_all_algo_open_orders(**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 "/fapi/v1/algoOpenOrders" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"

        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(CancelAllAlgoOpenOrdersResponse)

        if is_list and not is_flat_list:
