"""
Binance Derivatives Trading COIN Futures WebSocket API

OpenAPI Specification for the Binance Derivatives Trading COIN Futures WebSocket 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 pytest

from unittest.mock import AsyncMock, MagicMock

from binance_common.models import WebsocketApiResponse
from binance_common.utils import parse_ws_rate_limit_headers
from binance_common.errors import RequiredError
from binance_sdk_derivatives_trading_coin_futures.websocket_api.api import TradeApi


from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    ModifyOrderSideEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    ModifyOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderSideEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderTypeEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderPositionSideEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderTimeInForceEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderWorkingTypeEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderNewOrderRespTypeEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderPriceMatchEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderSelfTradePreventionModeEnum,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    CancelOrderResponse,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    ModifyOrderResponse,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    NewOrderResponse,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    PositionInformationResponse,
)
from binance_sdk_derivatives_trading_coin_futures.websocket_api.models import (
    QueryOrderResponse,
)


class TestWebSocketTradeApi:
    @pytest.fixture(autouse=True)
    def setup_method(self):
        self.mock_websocket_api = MagicMock()
        self.websocket_api = TradeApi(websocket_api=self.mock_websocket_api)

    @pytest.mark.asyncio
    async def test_cancel_order_success(self):
        """Test cancel_order() successfully with required parameters only."""

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

        expected_response = {
            "id": "a8627ea5-8b9f-452f-90ae-4136f2b442e2",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "CANCELED",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "51000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728416138285,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                }
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )
        result = await self.websocket_api.cancel_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.cancel".replace(
            "/", "", 1
        )

        assert "params" in request_kwargs["payload"]
        params = request_kwargs["payload"]["params"]
        assert params["symbol"] == "symbol_example"

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.cancel".replace("/", "", 1), "params": params},
            response_model=CancelOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_cancel_order_success_with_optional_params(self):
        """Test cancel_order() successfully with optional parameters."""

        params = {
            "symbol": "symbol_example",
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "recv_window": 5000,
        }

        expected_response = {
            "id": "a8627ea5-8b9f-452f-90ae-4136f2b442e2",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "CANCELED",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "51000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728416138285,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                }
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )

        result = await self.websocket_api.cancel_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.cancel".replace(
            "/", "", 1
        )
        assert params["symbol"] == "symbol_example"
        assert params["id"] == "e9d6b4349871b40611412680b3445fac"
        assert params["order_id"] == 1
        assert params["orig_client_order_id"] == "1"
        assert params["recv_window"] == 5000

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.cancel".replace("/", "", 1), "params": params},
            response_model=CancelOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_cancel_order_missing_required_param_symbol(self):
        """Test that cancel_order() raises RequiredError when 'symbol' is missing."""

        params = {
            "symbol": "symbol_example",
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "recv_window": 5000,
        }
        params["symbol"] = None

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

    @pytest.mark.asyncio
    async def test_cancel_order_server_error(self):
        """Test that cancel_order() raises an error when the server returns an error."""

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

        mock_error = Exception("ResponseError")
        self.mock_websocket_api.send_signed_message.side_effect = mock_error

        with pytest.raises(Exception, match="ResponseError"):
            await self.websocket_api.cancel_order(**params)

    @pytest.mark.asyncio
    async def test_modify_order_success(self):
        """Test modify_order() successfully with required parameters only."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
        }

        expected_response = {
            "id": "88601d02-bd0d-430d-8733-2708a569ebda",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "NEW",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "51000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728415765493,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                },
                {
                    "rateLimitType": "ORDERS",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 1200,
                    "count": 1,
                },
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )
        result = await self.websocket_api.modify_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.modify".replace(
            "/", "", 1
        )

        assert params["symbol"] == "symbol_example"

        assert params["side"] == ModifyOrderSideEnum["BUY"].value

        assert params["quantity"] == 1.0

        assert params["price"] == 1.0

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.modify".replace("/", "", 1), "params": params},
            response_model=ModifyOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_modify_order_success_with_optional_params(self):
        """Test modify_order() successfully with optional parameters."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "price_match": ModifyOrderPriceMatchEnum["NONE"].value,
            "recv_window": 5000,
        }

        expected_response = {
            "id": "88601d02-bd0d-430d-8733-2708a569ebda",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "NEW",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "51000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728415765493,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                },
                {
                    "rateLimitType": "ORDERS",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 1200,
                    "count": 1,
                },
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )

        result = await self.websocket_api.modify_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.modify".replace(
            "/", "", 1
        )
        assert params["symbol"] == "symbol_example"
        assert params["side"] == ModifyOrderSideEnum["BUY"].value
        assert params["quantity"] == 1.0
        assert params["price"] == 1.0
        assert params["id"] == "e9d6b4349871b40611412680b3445fac"
        assert params["order_id"] == 1
        assert params["orig_client_order_id"] == "1"
        assert params["price_match"] == ModifyOrderPriceMatchEnum["NONE"].value
        assert params["recv_window"] == 5000

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.modify".replace("/", "", 1), "params": params},
            response_model=ModifyOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_modify_order_missing_required_param_symbol(self):
        """Test that modify_order() raises RequiredError when 'symbol' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "price_match": ModifyOrderPriceMatchEnum["NONE"].value,
            "recv_window": 5000,
        }
        params["symbol"] = None

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

    @pytest.mark.asyncio
    async def test_modify_order_missing_required_param_side(self):
        """Test that modify_order() raises RequiredError when 'side' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "price_match": ModifyOrderPriceMatchEnum["NONE"].value,
            "recv_window": 5000,
        }
        params["side"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'side'"):
            await self.websocket_api.modify_order(**params)

    @pytest.mark.asyncio
    async def test_modify_order_missing_required_param_quantity(self):
        """Test that modify_order() raises RequiredError when 'quantity' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "price_match": ModifyOrderPriceMatchEnum["NONE"].value,
            "recv_window": 5000,
        }
        params["quantity"] = None

        with pytest.raises(
            RequiredError, match="Missing required parameter 'quantity'"
        ):
            await self.websocket_api.modify_order(**params)

    @pytest.mark.asyncio
    async def test_modify_order_missing_required_param_price(self):
        """Test that modify_order() raises RequiredError when 'price' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
            "id": "e9d6b4349871b40611412680b3445fac",
            "order_id": 1,
            "orig_client_order_id": "1",
            "price_match": ModifyOrderPriceMatchEnum["NONE"].value,
            "recv_window": 5000,
        }
        params["price"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'price'"):
            await self.websocket_api.modify_order(**params)

    @pytest.mark.asyncio
    async def test_modify_order_server_error(self):
        """Test that modify_order() raises an error when the server returns an error."""

        params = {
            "symbol": "symbol_example",
            "side": ModifyOrderSideEnum["BUY"].value,
            "quantity": 1.0,
            "price": 1.0,
        }

        mock_error = Exception("ResponseError")
        self.mock_websocket_api.send_signed_message.side_effect = mock_error

        with pytest.raises(Exception, match="ResponseError"):
            await self.websocket_api.modify_order(**params)

    @pytest.mark.asyncio
    async def test_new_order_success(self):
        """Test new_order() successfully with required parameters only."""

        params = {
            "symbol": "symbol_example",
            "side": NewOrderSideEnum["BUY"].value,
            "type": NewOrderTypeEnum["LIMIT"].value,
        }

        expected_response = {
            "id": "60fa4366-f96e-42fe-a82b-f819952c6db4",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "NEW",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "50000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728413795125,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                },
                {
                    "rateLimitType": "ORDERS",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 1200,
                    "count": 1,
                },
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )
        result = await self.websocket_api.new_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.place".replace("/", "", 1)

        assert params["symbol"] == "symbol_example"

        assert params["side"] == NewOrderSideEnum["BUY"].value

        assert params["type"] == NewOrderTypeEnum["LIMIT"].value

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.place".replace("/", "", 1), "params": params},
            response_model=NewOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_new_order_success_with_optional_params(self):
        """Test new_order() successfully with optional parameters."""

        params = {
            "symbol": "symbol_example",
            "side": NewOrderSideEnum["BUY"].value,
            "type": NewOrderTypeEnum["LIMIT"].value,
            "id": "e9d6b4349871b40611412680b3445fac",
            "position_side": NewOrderPositionSideEnum["BOTH"].value,
            "time_in_force": NewOrderTimeInForceEnum["GTC"].value,
            "quantity": 1.0,
            "reduce_only": "False",
            "price": 1.0,
            "new_client_order_id": "1",
            "stop_price": 1.0,
            "close_position": "close_position_example",
            "activation_price": 1.0,
            "callback_rate": 1.0,
            "working_type": NewOrderWorkingTypeEnum["MARK_PRICE"].value,
            "price_protect": "False",
            "new_order_resp_type": NewOrderNewOrderRespTypeEnum["ACK"].value,
            "price_match": NewOrderPriceMatchEnum["NONE"].value,
            "self_trade_prevention_mode": NewOrderSelfTradePreventionModeEnum[
                "NONE"
            ].value,
            "recv_window": 5000,
        }

        expected_response = {
            "id": "60fa4366-f96e-42fe-a82b-f819952c6db4",
            "status": 200,
            "result": {
                "orderId": 333245211,
                "symbol": "BTCUSD_PERP",
                "pair": "BTCUSD",
                "status": "NEW",
                "clientOrderId": "5SztZiGFAxgAqw4J9EN9fA",
                "price": "50000",
                "avgPrice": "0.00",
                "origQty": "1",
                "executedQty": "0",
                "cumQty": "0",
                "cumBase": "0",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "reduceOnly": False,
                "closePosition": False,
                "side": "BUY",
                "positionSide": "BOTH",
                "stopPrice": "0",
                "workingType": "CONTRACT_PRICE",
                "priceProtect": False,
                "origType": "LIMIT",
                "updateTime": 1728413795125,
            },
            "rateLimits": [
                {
                    "rateLimitType": "REQUEST_WEIGHT",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 2400,
                    "count": 6,
                },
                {
                    "rateLimitType": "ORDERS",
                    "interval": "MINUTE",
                    "intervalNum": 1,
                    "limit": 1200,
                    "count": 1,
                },
            ],
        }

        self.mock_websocket_api.send_signed_message = AsyncMock(
            return_value=WebsocketApiResponse(
                data_function=lambda: expected_response,
                rate_limits=(
                    parse_ws_rate_limit_headers(expected_response["rateLimits"])
                    if "rateLimits" in expected_response
                    else None
                ),
            )
        )

        result = await self.websocket_api.new_order(**params)

        actual_call_args = self.mock_websocket_api.send_signed_message.call_args
        request_kwargs = actual_call_args.kwargs

        assert "payload" in request_kwargs
        assert "method" in request_kwargs["payload"]
        assert request_kwargs["payload"]["method"] == "/order.place".replace("/", "", 1)
        assert params["symbol"] == "symbol_example"
        assert params["side"] == NewOrderSideEnum["BUY"].value
        assert params["type"] == NewOrderTypeEnum["LIMIT"].value
        assert params["id"] == "e9d6b4349871b40611412680b3445fac"
        assert params["position_side"] == NewOrderPositionSideEnum["BOTH"].value
        assert params["time_in_force"] == NewOrderTimeInForceEnum["GTC"].value
        assert params["quantity"] == 1.0
        assert params["reduce_only"] == "False"
        assert params["price"] == 1.0
        assert params["new_client_order_id"] == "1"
        assert params["stop_price"] == 1.0
        assert params["close_position"] == "close_position_example"
        assert params["activation_price"] == 1.0
        assert params["callback_rate"] == 1.0
        assert params["working_type"] == NewOrderWorkingTypeEnum["MARK_PRICE"].value
        assert params["price_protect"] == "False"
        assert (
            params["new_order_resp_type"] == NewOrderNewOrderRespTypeEnum["ACK"].value
        )
        assert params["price_match"] == NewOrderPriceMatchEnum["NONE"].value
        assert (
            params["self_trade_prevention_mode"]
            == NewOrderSelfTradePreventionModeEnum["NONE"].value
        )
        assert params["recv_window"] == 5000

        assert result is not None
        assert result.data() == expected_response
        self.mock_websocket_api.send_signed_message.assert_called_once_with(
            payload={"method": "/order.place".replace("/", "", 1), "params": params},
            response_model=NewOrderResponse,
            signer=None,
        )

    @pytest.mark.asyncio
    async def test_new_order_missing_required_param_symbol(self):
        """Test that new_order() raises RequiredError when 'symbol' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": NewOrderSideEnum["BUY"].value,
            "type": NewOrderTypeEnum["LIMIT"].value,
            "id": "e9d6b4349871b40611412680b3445fac",
            "position_side": NewOrderPositionSideEnum["BOTH"].value,
            "time_in_force": NewOrderTimeInForceEnum["GTC"].value,
            "quantity": 1.0,
            "reduce_only": "False",
            "price": 1.0,
            "new_client_order_id": "1",
            "stop_price": 1.0,
            "close_position": "close_position_example",
            "activation_price": 1.0,
            "callback_rate": 1.0,
            "working_type": NewOrderWorkingTypeEnum["MARK_PRICE"].value,
            "price_protect": "False",
            "new_order_resp_type": NewOrderNewOrderRespTypeEnum["ACK"].value,
            "price_match": NewOrderPriceMatchEnum["NONE"].value,
            "self_trade_prevention_mode": NewOrderSelfTradePreventionModeEnum[
                "NONE"
            ].value,
            "recv_window": 5000,
        }
        params["symbol"] = None

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

    @pytest.mark.asyncio
    async def test_new_order_missing_required_param_side(self):
        """Test that new_order() raises RequiredError when 'side' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": NewOrderSideEnum["BUY"].value,
            "type": NewOrderTypeEnum["LIMIT"].value,
            "id": "e9d6b4349871b40611412680b3445fac",
            "position_side": NewOrderPositionSideEnum["BOTH"].value,
            "time_in_force": NewOrderTimeInForceEnum["GTC"].value,
            "quantity": 1.0,
            "reduce_only": "False",
            "price": 1.0,
            "new_client_order_id": "1",
            "stop_price": 1.0,
            "close_position": "close_position_example",
            "activation_price": 1.0,
            "callback_rate": 1.0,
            "working_type": NewOrderWorkingTypeEnum["MARK_PRICE"].value,
            "price_protect": "False",
            "new_order_resp_type": NewOrderNewOrderRespTypeEnum["ACK"].value,
            "price_match": NewOrderPriceMatchEnum["NONE"].value,
            "self_trade_prevention_mode": NewOrderSelfTradePreventionModeEnum[
                "NONE"
            ].value,
            "recv_window": 5000,
        }
        params["side"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'side'"):
            await self.websocket_api.new_order(**params)

    @pytest.mark.asyncio
    async def test_new_order_missing_required_param_type(self):
        """Test that new_order() raises RequiredError when 'type' is missing."""

        params = {
            "symbol": "symbol_example",
            "side": NewOrderSideEnum["BUY"].value,
            "type": NewOrderTypeEnum["LIMIT"].value,
            "id": "e9d6b4349871b40611412680b3445fac",
            "position_side": NewOrderPositionSideEnum["BOTH"].value,
            "time_in_force": NewOrderTimeInForceEnum["GTC"].value,
            "quantity": 1.0,
            "reduce_only": "False",
            "price": 1.0,
            "new_client_order_id": "1",
            "stop_price": 1.0,
            "close_position": "close_position_example",
            "activation_price": 1.0,
            "callback_rate": 1.0,
            "working_type": NewOrderWorkingTypeEnum["MARK_PRICE"].value,
            "price_protect": "False",
            "new_order_resp_type": NewOrderNewOrderRespTypeEnum["ACK"].value,
            "price_match": NewOrderPriceMatchEnum["NONE"].value,
            "self_trade_prevention_mode": NewOrderSelfTradePreventionModeEnum[
                "NONE"
            ].value,
            "recv_window": 5000,
        }
        params["type"] = None

        with pytest.raises(RequiredError, match="Missing required parameter 'type'"):
            await self.websocket_api.new_order(**params)

    @pytest.mark.asyncio
    async def test_new_order_server_error(self):
        """Test that new_order() raises an error when the server returns an error."""

        params = {
            "symbol": "symbol_example",
