"""
Binance Wallet REST API

OpenAPI Specification for the Binance Wallet REST API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

import json
import pytest
import requests

from unittest.mock import MagicMock, patch
from urllib.parse import parse_qs

from binance_common.configuration import ConfigurationRestAPI
from binance_common.errors import RequiredError
from binance_common.utils import normalize_query_values, is_one_of_model, snake_to_camel

from binance_sdk_wallet.rest_api.api import AccountApi
from binance_sdk_wallet.rest_api.models import AccountApiTradingStatusResponse
from binance_sdk_wallet.rest_api.models import AccountInfoResponse
from binance_sdk_wallet.rest_api.models import AccountStatusResponse
from binance_sdk_wallet.rest_api.models import DailyAccountSnapshotResponse


from binance_sdk_wallet.rest_api.models import GetApiKeyPermissionResponse


class TestAccountApi:
    @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 = AccountApi(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_api_trading_status_success(self, mock_get_signature):
        """Test account_api_trading_status() successfully with required parameters only."""

        expected_response = {
            "data": {
                "isLocked": False,
                "plannedRecoverTime": 0,
                "triggerCondition": {"GCR": 150, "IFER": 150, "UFR": 300},
                "updateTime": 1547630471725,
            }
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_api_trading_status()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/apiTradingStatus" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(AccountApiTradingStatusResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {
            "data": {
                "isLocked": False,
                "plannedRecoverTime": 0,
                "triggerCondition": {"GCR": 150, "IFER": 150, "UFR": 300},
                "updateTime": 1547630471725,
            }
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/apiTradingStatus" 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(AccountApiTradingStatusResponse)

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

        assert response.data() == expected

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

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

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

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

        expected_response = {
            "vipLevel": 0,
            "isMarginEnabled": True,
            "isFutureEnabled": True,
            "isOptionsEnabled": True,
            "isPortfolioMarginRetailEnabled": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_info()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/info" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(AccountInfoResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {
            "vipLevel": 0,
            "isMarginEnabled": True,
            "isFutureEnabled": True,
            "isOptionsEnabled": True,
            "isPortfolioMarginRetailEnabled": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/info" 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(AccountInfoResponse)

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

        assert response.data() == expected

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

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

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

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

        expected_response = {"data": "Normal"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_status()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/status" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(AccountStatusResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {"data": "Normal"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/status" 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(AccountStatusResponse)

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

        assert response.data() == expected

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

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

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

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

        params = {
            "type": "type_example",
        }

        expected_response = {
            "code": 200,
            "msg": "",
            "snapshotVos": [
                {
                    "data": {
                        "balances": [
                            {
                                "asset": "BTC",
                                "free": "0.09905021",
                                "locked": "0.00000000",
                            },
                            {
                                "asset": "USDT",
                                "free": "1.89109409",
                                "locked": "0.00000000",
                            },
                        ],
                        "totalAssetOfBtc": "0.09942700",
                    },
                    "type": "spot",
                    "updateTime": 1576281599000,
                },
                {
                    "data": {
                        "marginLevel": "2748.02909813",
                        "totalAssetOfBtc": "0.00274803",
                        "totalLiabilityOfBtc": "0.00000100",
                        "totalNetAssetOfBtc": "0.00274750",
                        "userAssets": [
                            {
                                "asset": "XRP",
                                "borrowed": "0.00000000",
                                "free": "1.00000000",
                                "interest": "0.00000000",
                                "locked": "0.00000000",
                                "netAsset": "1.00000000",
                            }
                        ],
                    },
                    "type": "margin",
                    "updateTime": 1576281599000,
                },
                {
                    "data": {
                        "assets": [
                            {
                                "asset": "USDT",
                                "marginBalance": "118.99782335",
                                "walletBalance": "120.23811389",
                            }
                        ],
                        "position": [
                            {
                                "entryPrice": "7130.41000000",
                                "markPrice": "7257.66239673",
                                "positionAmt": "0.01000000",
                                "symbol": "BTCUSDT",
                                "unRealizedProfit": "1.24029054",
                            }
                        ],
                    },
                    "type": "futures",
                    "updateTime": 1576281599000,
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

        actual_call_args = self.mock_session.request.call_args
        request_kwargs = actual_call_args.kwargs
        parsed_params = parse_qs(request_kwargs["params"])
        camel_case_params = {snake_to_camel(k): v for k, v in params.items()}
        normalized = normalize_query_values(parsed_params, camel_case_params)

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/accountSnapshot" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["type"] == "type_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(DailyAccountSnapshotResponse)

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

        assert response.data() == expected

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

        params = {
            "type": "type_example",
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "limit": 7,
            "recv_window": 5000,
        }

        expected_response = {
            "code": 200,
            "msg": "",
            "snapshotVos": [
                {
                    "data": {
                        "balances": [
                            {
                                "asset": "BTC",
                                "free": "0.09905021",
                                "locked": "0.00000000",
                            },
                            {
                                "asset": "USDT",
                                "free": "1.89109409",
                                "locked": "0.00000000",
                            },
                        ],
                        "totalAssetOfBtc": "0.09942700",
                    },
                    "type": "spot",
                    "updateTime": 1576281599000,
                },
                {
                    "data": {
                        "marginLevel": "2748.02909813",
                        "totalAssetOfBtc": "0.00274803",
                        "totalLiabilityOfBtc": "0.00000100",
                        "totalNetAssetOfBtc": "0.00274750",
                        "userAssets": [
                            {
                                "asset": "XRP",
                                "borrowed": "0.00000000",
                                "free": "1.00000000",
                                "interest": "0.00000000",
                                "locked": "0.00000000",
                                "netAsset": "1.00000000",
                            }
                        ],
                    },
                    "type": "margin",
                    "updateTime": 1576281599000,
                },
                {
                    "data": {
                        "assets": [
                            {
                                "asset": "USDT",
                                "marginBalance": "118.99782335",
                                "walletBalance": "120.23811389",
                            }
                        ],
                        "position": [
                            {
                                "entryPrice": "7130.41000000",
                                "markPrice": "7257.66239673",
                                "positionAmt": "0.01000000",
                                "symbol": "BTCUSDT",
                                "unRealizedProfit": "1.24029054",
                            }
                        ],
                    },
                    "type": "futures",
                    "updateTime": 1576281599000,
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/accountSnapshot" 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(DailyAccountSnapshotResponse)

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

        assert response.data() == expected

    def test_daily_account_snapshot_missing_required_param_type(self):
        """Test that daily_account_snapshot() raises RequiredError when 'type' is missing."""
        params = {
            "type": "type_example",
        }
        params["type"] = None

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

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

        params = {
            "type": "type_example",
        }

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

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

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

        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response({})

        response = self.client.disable_fast_withdraw_switch()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/disableFastWithdrawSwitch" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        assert response is not None

        assert response.data() == {}

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

        params = {"recv_window": 5000}

        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response({})

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/disableFastWithdrawSwitch" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        self.mock_session.request.assert_called_once()
        assert response is not None

        assert response.data() == {}

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

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

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

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

        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response({})

        response = self.client.enable_fast_withdraw_switch()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/enableFastWithdrawSwitch" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        assert response is not None

        assert response.data() == {}

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

        params = {"recv_window": 5000}

        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response({})

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/enableFastWithdrawSwitch" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        self.mock_session.request.assert_called_once()
        assert response is not None

        assert response.data() == {}

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

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

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

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

        expected_response = {
            "ipRestrict": False,
            "createTime": 1698645219000,
            "enableReading": True,
            "enableWithdrawals": False,
            "enableInternalTransfer": False,
            "enableMargin": False,
            "enableFutures": False,
            "permitsUniversalTransfer": False,
            "enableVanillaOptions": False,
            "enableFixApiTrade": False,
            "enableFixReadOnly": True,
            "enableSpotAndMarginTrading": False,
            "enablePortfolioMarginTrading": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.get_api_key_permission()

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

        self.mock_session.request.assert_called_once()
        mock_get_signature.assert_called_once()

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/apiRestrictions" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(GetApiKeyPermissionResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {
            "ipRestrict": False,
            "createTime": 1698645219000,
            "enableReading": True,
            "enableWithdrawals": False,
            "enableInternalTransfer": False,
            "enableMargin": False,
            "enableFutures": False,
            "permitsUniversalTransfer": False,
            "enableVanillaOptions": False,
            "enableFixApiTrade": False,
            "enableFixReadOnly": True,
            "enableSpotAndMarginTrading": False,
            "enablePortfolioMarginTrading": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/account/apiRestrictions" 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(GetApiKeyPermissionResponse)

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

        assert response.data() == expected

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

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

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