"""
Binance Spot REST API

OpenAPI Specifications for the Binance Spot REST API

API documents:
  - [Github rest-api documentation file](https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md)
  - [General API information for rest-api on website](https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-api-information)

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_spot.rest_api.api import TradeApi
from binance_sdk_spot.rest_api.models import DeleteOpenOrdersResponse
from binance_sdk_spot.rest_api.models import DeleteOrderResponse
from binance_sdk_spot.rest_api.models import DeleteOrderListResponse
from binance_sdk_spot.rest_api.models import NewOrderResponse
from binance_sdk_spot.rest_api.models import OrderAmendKeepPriorityResponse
from binance_sdk_spot.rest_api.models import OrderCancelReplaceResponse
from binance_sdk_spot.rest_api.models import OrderListOcoResponse
from binance_sdk_spot.rest_api.models import OrderListOpoResponse
from binance_sdk_spot.rest_api.models import OrderListOpocoResponse
from binance_sdk_spot.rest_api.models import OrderListOtoResponse
from binance_sdk_spot.rest_api.models import OrderListOtocoResponse
from binance_sdk_spot.rest_api.models import OrderOcoResponse
from binance_sdk_spot.rest_api.models import OrderTestResponse
from binance_sdk_spot.rest_api.models import SorOrderResponse
from binance_sdk_spot.rest_api.models import SorOrderTestResponse


from binance_sdk_spot.rest_api.models import DeleteOrderCancelRestrictionsEnum
from binance_sdk_spot.rest_api.models import NewOrderSideEnum
from binance_sdk_spot.rest_api.models import NewOrderTypeEnum
from binance_sdk_spot.rest_api.models import NewOrderTimeInForceEnum
from binance_sdk_spot.rest_api.models import NewOrderNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import NewOrderSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import NewOrderPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import NewOrderPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplaceSideEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplaceTypeEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplaceCancelReplaceModeEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplaceTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplaceNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import (
    OrderCancelReplaceSelfTradePreventionModeEnum,
)
from binance_sdk_spot.rest_api.models import OrderCancelReplaceCancelRestrictionsEnum
from binance_sdk_spot.rest_api.models import (
    OrderCancelReplaceOrderRateLimitExceededModeEnum,
)
from binance_sdk_spot.rest_api.models import OrderCancelReplacePegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderCancelReplacePegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoSideEnum
from binance_sdk_spot.rest_api.models import OrderListOcoAboveTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoBelowTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoAboveTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOcoAbovePegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoAbovePegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoBelowTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOcoBelowPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoBelowPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOcoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoWorkingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoWorkingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOpoPendingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoPendingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOpoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoWorkingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOpoWorkingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoWorkingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoPendingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOpoPendingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpoPendingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoWorkingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoWorkingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingAboveTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoWorkingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoWorkingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoWorkingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingAboveTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingAbovePegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingAbovePegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingBelowTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingBelowTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingBelowPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOpocoPendingBelowPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoWorkingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoWorkingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOtoPendingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoPendingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOtoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoWorkingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOtoWorkingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoWorkingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoPendingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOtoPendingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtoPendingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoWorkingTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoWorkingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingSideEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingAboveTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoWorkingTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoWorkingPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoWorkingPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingAboveTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingAbovePegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingAbovePegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingBelowTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingBelowTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingBelowPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderListOtocoPendingBelowPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import OrderOcoSideEnum
from binance_sdk_spot.rest_api.models import OrderOcoStopLimitTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderOcoNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderOcoSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderTestSideEnum
from binance_sdk_spot.rest_api.models import OrderTestTypeEnum
from binance_sdk_spot.rest_api.models import OrderTestTimeInForceEnum
from binance_sdk_spot.rest_api.models import OrderTestNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import OrderTestSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import OrderTestPegPriceTypeEnum
from binance_sdk_spot.rest_api.models import OrderTestPegOffsetTypeEnum
from binance_sdk_spot.rest_api.models import SorOrderSideEnum
from binance_sdk_spot.rest_api.models import SorOrderTypeEnum
from binance_sdk_spot.rest_api.models import SorOrderTimeInForceEnum
from binance_sdk_spot.rest_api.models import SorOrderNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import SorOrderSelfTradePreventionModeEnum
from binance_sdk_spot.rest_api.models import SorOrderTestSideEnum
from binance_sdk_spot.rest_api.models import SorOrderTestTypeEnum
from binance_sdk_spot.rest_api.models import SorOrderTestTimeInForceEnum
from binance_sdk_spot.rest_api.models import SorOrderTestNewOrderRespTypeEnum
from binance_sdk_spot.rest_api.models import SorOrderTestSelfTradePreventionModeEnum


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_delete_open_orders_success(self, mock_get_signature):
        """Test delete_open_orders() successfully with required parameters only."""

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

        expected_response = [
            {
                "symbol": "BTCUSDT",
                "origClientOrderId": "E6APeyTJvkMvLMYMqu1KQ4",
                "orderId": 11,
                "orderListId": -1,
                "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                "transactTime": 1684804350068,
                "price": "0.089853",
                "origQty": "0.178622",
                "executedQty": "0.000000",
                "origQuoteOrderQty": "0.000000",
                "cummulativeQuoteQty": "0.000000",
                "status": "CANCELED",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "side": "BUY",
                "selfTradePreventionMode": "NONE",
            },
            {
                "symbol": "BTCUSDT",
                "origClientOrderId": "A3EF2HCwxgZPFMrfwbgrhv",
                "orderId": 13,
                "orderListId": -1,
                "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                "transactTime": 1684804350069,
                "price": "0.090430",
                "origQty": "0.178622",
                "executedQty": "0.000000",
                "origQuoteOrderQty": "0.000000",
                "cummulativeQuoteQty": "0.000000",
                "status": "CANCELED",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "side": "BUY",
                "selfTradePreventionMode": "NONE",
            },
            {
                "orderListId": 1929,
                "contingencyType": "OCO",
                "listStatusType": "ALL_DONE",
                "listOrderStatus": "ALL_DONE",
                "listClientOrderId": "2inzWQdDvZLHbbAmAozX2N",
                "transactionTime": 1585230948299,
                "symbol": "BTCUSDT",
                "orders": [
                    {
                        "symbol": "BTCUSDT",
                        "orderId": 20,
                        "clientOrderId": "CwOOIPHSmYywx6jZX77TdL",
                    },
                    {
                        "symbol": "BTCUSDT",
                        "orderId": 21,
                        "clientOrderId": "461cPg51vQjV3zIMOXNz39",
                    },
                ],
                "orderReports": [
                    {
                        "symbol": "BTCUSDT",
                        "origClientOrderId": "CwOOIPHSmYywx6jZX77TdL",
                        "orderId": 20,
                        "orderListId": 1929,
                        "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                        "transactTime": 1688005070874,
                        "price": "0.668611",
                        "origQty": "0.690354",
                        "executedQty": "0.000000",
                        "origQuoteOrderQty": "0.000000",
                        "cummulativeQuoteQty": "0.000000",
                        "status": "CANCELED",
                        "timeInForce": "GTC",
                        "type": "STOP_LOSS_LIMIT",
                        "side": "BUY",
                        "stopPrice": "0.378131",
                        "icebergQty": "0.017083",
                        "selfTradePreventionMode": "NONE",
                    },
                    {
                        "symbol": "BTCUSDT",
                        "origClientOrderId": "461cPg51vQjV3zIMOXNz39",
                        "orderId": 21,
                        "orderListId": 1929,
                        "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                        "transactTime": 1688005070874,
                        "price": "0.008791",
                        "origQty": "0.690354",
                        "executedQty": "0.000000",
                        "origQuoteOrderQty": "0.000000",
                        "cummulativeQuoteQty": "0.000000",
                        "status": "CANCELED",
                        "timeInForce": "GTC",
                        "type": "LIMIT_MAKER",
                        "side": "BUY",
                        "icebergQty": "0.639962",
                        "selfTradePreventionMode": "NONE",
                    },
                ],
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.delete_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 "/api/v3/openOrders" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"
        assert normalized["symbol"] == "BNBUSDT"

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

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

        assert response.data() == expected

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

        params = {"symbol": "BNBUSDT", "recv_window": 5000.0}

        expected_response = [
            {
                "symbol": "BTCUSDT",
                "origClientOrderId": "E6APeyTJvkMvLMYMqu1KQ4",
                "orderId": 11,
                "orderListId": -1,
                "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                "transactTime": 1684804350068,
                "price": "0.089853",
                "origQty": "0.178622",
                "executedQty": "0.000000",
                "origQuoteOrderQty": "0.000000",
                "cummulativeQuoteQty": "0.000000",
                "status": "CANCELED",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "side": "BUY",
                "selfTradePreventionMode": "NONE",
            },
            {
                "symbol": "BTCUSDT",
                "origClientOrderId": "A3EF2HCwxgZPFMrfwbgrhv",
                "orderId": 13,
                "orderListId": -1,
                "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                "transactTime": 1684804350069,
                "price": "0.090430",
                "origQty": "0.178622",
                "executedQty": "0.000000",
                "origQuoteOrderQty": "0.000000",
                "cummulativeQuoteQty": "0.000000",
                "status": "CANCELED",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "side": "BUY",
                "selfTradePreventionMode": "NONE",
            },
            {
                "orderListId": 1929,
                "contingencyType": "OCO",
                "listStatusType": "ALL_DONE",
                "listOrderStatus": "ALL_DONE",
                "listClientOrderId": "2inzWQdDvZLHbbAmAozX2N",
                "transactionTime": 1585230948299,
                "symbol": "BTCUSDT",
                "orders": [
                    {
                        "symbol": "BTCUSDT",
                        "orderId": 20,
                        "clientOrderId": "CwOOIPHSmYywx6jZX77TdL",
                    },
                    {
                        "symbol": "BTCUSDT",
                        "orderId": 21,
                        "clientOrderId": "461cPg51vQjV3zIMOXNz39",
                    },
                ],
                "orderReports": [
                    {
                        "symbol": "BTCUSDT",
                        "origClientOrderId": "CwOOIPHSmYywx6jZX77TdL",
                        "orderId": 20,
                        "orderListId": 1929,
                        "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                        "transactTime": 1688005070874,
                        "price": "0.668611",
                        "origQty": "0.690354",
                        "executedQty": "0.000000",
                        "origQuoteOrderQty": "0.000000",
                        "cummulativeQuoteQty": "0.000000",
                        "status": "CANCELED",
                        "timeInForce": "GTC",
                        "type": "STOP_LOSS_LIMIT",
                        "side": "BUY",
                        "stopPrice": "0.378131",
                        "icebergQty": "0.017083",
                        "selfTradePreventionMode": "NONE",
                    },
                    {
                        "symbol": "BTCUSDT",
                        "origClientOrderId": "461cPg51vQjV3zIMOXNz39",
                        "orderId": 21,
                        "orderListId": 1929,
                        "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx",
                        "transactTime": 1688005070874,
                        "price": "0.008791",
                        "origQty": "0.690354",
                        "executedQty": "0.000000",
                        "origQuoteOrderQty": "0.000000",
                        "cummulativeQuoteQty": "0.000000",
                        "status": "CANCELED",
                        "timeInForce": "GTC",
                        "type": "LIMIT_MAKER",
                        "side": "BUY",
                        "icebergQty": "0.639962",
                        "selfTradePreventionMode": "NONE",
                    },
                ],
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.delete_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 "/api/v3/openOrders" 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(DeleteOpenOrdersResponse)

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

        assert response.data() == expected

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

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

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

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

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

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

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

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

        expected_response = {
            "symbol": "LTCBTC",
            "origClientOrderId": "myOrder1",
            "orderId": 4,
            "orderListId": -1,
            "clientOrderId": "cancelMyOrder1",
            "transactTime": 1684804350068,
            "price": "2.00000000",
            "origQty": "1.00000000",
            "executedQty": "0.00000000",
            "origQuoteOrderQty": "0.000000",
            "cummulativeQuoteQty": "0.00000000",
            "status": "CANCELED",
            "timeInForce": "GTC",
            "type": "LIMIT",
            "side": "BUY",
            "selfTradePreventionMode": "NONE",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.delete_order(**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 "/api/v3/order" in request_kwargs["url"]
        assert request_kwargs["method"] == "DELETE"
        assert normalized["symbol"] == "BNBUSDT"

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

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

        assert response.data() == expected

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

        params = {
            "symbol": "BNBUSDT",
            "order_id": 1,
            "orig_client_order_id": "orig_client_order_id_example",
            "new_client_order_id": "new_client_order_id_example",
            "cancel_restrictions": DeleteOrderCancelRestrictionsEnum["ONLY_NEW"].value,
            "recv_window": 5000.0,
        }

        expected_response = {
            "symbol": "LTCBTC",
            "origClientOrderId": "myOrder1",
            "orderId": 4,
            "orderListId": -1,
            "clientOrderId": "cancelMyOrder1",
            "transactTime": 1684804350068,
            "price": "2.00000000",
            "origQty": "1.00000000",
            "executedQty": "0.00000000",
            "origQuoteOrderQty": "0.000000",
            "cummulativeQuoteQty": "0.00000000",
            "status": "CANCELED",
            "timeInForce": "GTC",
            "type": "LIMIT",
            "side": "BUY",
            "selfTradePreventionMode": "NONE",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.delete_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 "/api/v3/order" 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(DeleteOrderResponse)

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

        assert response.data() == expected

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

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

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

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

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

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

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

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

        expected_response = {
            "orderListId": 0,
            "contingencyType": "OCO",
            "listStatusType": "ALL_DONE",
            "listOrderStatus": "ALL_DONE",
            "listClientOrderId": "C3wyj4WVEktd7u9aVBRXcN",
            "transactionTime": 1574040868128,
            "symbol": "LTCBTC",
            "orders": [
                {
                    "symbol": "LTCBTC",
                    "orderId": 3,
                    "clientOrderId": "TXOvglzXuaubXAaENpaRCB",
                },
                {
                    "symbol": "LTCBTC",
                    "orderId": 2,
                    "clientOrderId": "pO9ufTiFGg3nw2fOdgeOXa",
                },
            ],
            "orderReports": [
                {
                    "symbol": "LTCBTC",
                    "origClientOrderId": "TXOvglzXuaubXAaENpaRCB",
                    "orderId": 3,
                    "orderListId": 0,
                    "clientOrderId": "unfWT8ig8i0uj6lPuYLez6",
                    "transactTime": 1688005070874,
                    "price": "3.00000000",
                    "origQty": "10.00000000",
                    "executedQty": "0.00000000",
                    "origQuoteOrderQty": "0.000000",
                    "cummulativeQuoteQty": "0.00000000",
                    "status": "CANCELED",
                    "timeInForce": "GTC",
                    "type": "LIMIT_MAKER",
                    "side": "SELL",
                    "selfTradePreventionMode": "NONE",
                },
                {
                    "symbol": "LTCBTC",
                    "origClientOrderId": "pO9ufTiFGg3nw2fOdgeOXa",
                    "orderId": 2,
                    "orderListId": 0,
                    "clientOrderId": "unfWT8ig8i0uj6lPuYLez6",
                    "transactTime": 1688005070874,
                    "price": "1.00000000",
                    "origQty": "10.00000000",
                    "executedQty": "0.00000000",
                    "origQuoteOrderQty": "0.000000",
                    "cummulativeQuoteQty": "0.00000000",
                    "status": "CANCELED",
                    "timeInForce": "GTC",
                    "type": "STOP_LOSS_LIMIT",
                    "side": "SELL",
                    "stopPrice": "1.00000000",
                    "selfTradePreventionMode": "NONE",
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.delete_order_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
