"""
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 TravelRuleApi
from binance_sdk_wallet.rest_api.models import BrokerWithdrawResponse
from binance_sdk_wallet.rest_api.models import CheckQuestionnaireRequirementsResponse
from binance_sdk_wallet.rest_api.models import DepositHistoryTravelRuleResponse
from binance_sdk_wallet.rest_api.models import DepositHistoryV2Response
from binance_sdk_wallet.rest_api.models import FetchAddressVerificationListResponse
from binance_sdk_wallet.rest_api.models import SubmitDepositQuestionnaireResponse
from binance_sdk_wallet.rest_api.models import (
    SubmitDepositQuestionnaireTravelRuleResponse,
)
from binance_sdk_wallet.rest_api.models import VaspListResponse
from binance_sdk_wallet.rest_api.models import WithdrawHistoryV1Response
from binance_sdk_wallet.rest_api.models import WithdrawHistoryV2Response
from binance_sdk_wallet.rest_api.models import WithdrawTravelRuleResponse


class TestTravelRuleApi:
    @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 = TravelRuleApi(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_broker_withdraw_success(self, mock_get_signature):
        """Test broker_withdraw() successfully with required parameters only."""

        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }

        expected_response = {
            "trId": 123456,
            "accpted": True,
            "info": "Withdraw request accepted",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.broker_withdraw(**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/localentity/broker/withdraw/apply" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["address"] == "address_example"
        assert normalized["coin"] == "coin_example"
        assert normalized["amount"] == 1.0
        assert normalized["withdrawOrderId"] == "1"
        assert normalized["questionnaire"] == "questionnaire_example"
        assert normalized["originatorPii"] == "originator_pii_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(BrokerWithdrawResponse)

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

        assert response.data() == expected

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

        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
            "address_tag": "address_tag_example",
            "network": "network_example",
            "address_name": "address_name_example",
            "transaction_fee_flag": False,
            "wallet_type": 0,
        }

        expected_response = {
            "trId": 123456,
            "accpted": True,
            "info": "Withdraw request accepted",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.broker_withdraw(**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/localentity/broker/withdraw/apply" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"

        self.mock_session.request.assert_called_once()
        assert response is not None
        is_list = isinstance(expected_response, list)
        is_flat_list = (
            is_list and not isinstance(expected_response[0], list) if is_list else False
        )
        is_oneof = is_one_of_model(BrokerWithdrawResponse)

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

        assert response.data() == expected

    def test_broker_withdraw_missing_required_param_address(self):
        """Test that broker_withdraw() raises RequiredError when 'address' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["address"] = None

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

    def test_broker_withdraw_missing_required_param_coin(self):
        """Test that broker_withdraw() raises RequiredError when 'coin' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["coin"] = None

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

    def test_broker_withdraw_missing_required_param_amount(self):
        """Test that broker_withdraw() raises RequiredError when 'amount' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["amount"] = None

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

    def test_broker_withdraw_missing_required_param_withdraw_order_id(self):
        """Test that broker_withdraw() raises RequiredError when 'withdraw_order_id' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["withdraw_order_id"] = None

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

    def test_broker_withdraw_missing_required_param_questionnaire(self):
        """Test that broker_withdraw() raises RequiredError when 'questionnaire' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["questionnaire"] = None

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

    def test_broker_withdraw_missing_required_param_originator_pii(self):
        """Test that broker_withdraw() raises RequiredError when 'originator_pii' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["originator_pii"] = None

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

    def test_broker_withdraw_missing_required_param_signature(self):
        """Test that broker_withdraw() raises RequiredError when 'signature' is missing."""
        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }
        params["signature"] = None

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

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

        params = {
            "address": "address_example",
            "coin": "coin_example",
            "amount": 1.0,
            "withdraw_order_id": "1",
            "questionnaire": "questionnaire_example",
            "originator_pii": "originator_pii_example",
            "signature": "signature_example",
        }

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

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

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

        expected_response = {"questionnaireCountryCode": "AE"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.check_questionnaire_requirements()

        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/localentity/questionnaire-requirements" 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(CheckQuestionnaireRequirementsResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {"questionnaireCountryCode": "AE"}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.check_questionnaire_requirements(**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/localentity/questionnaire-requirements" 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(CheckQuestionnaireRequirementsResponse)

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

        assert response.data() == expected

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

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

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

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

        expected_response = [
            {
                "trId": 123451123,
                "tranId": 17644346245865,
                "amount": "0.001",
                "coin": "BNB",
                "network": "BNB",
                "depositStatus": 0,
                "travelRuleStatus": 1,
                "address": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23",
                "addressTag": "101764890",
                "txId": "98A3EA560C6B3336D348B6C83F0F95ECE4F1F5919E94BD006E5BF3BF264FACFC",
                "insertTime": 1661493146000,
                "transferType": 0,
                "confirmTimes": "1/1",
                "unlockConfirm": 0,
                "walletType": 0,
                "requireQuestionnaire": False,
                "questionnaire": None,
            },
            {
                "trId": 2451123,
                "tranId": 4544346245865,
                "amount": "0.50000000",
                "coin": "IOTA",
                "network": "IOTA",
                "depositStatus": 0,
                "travelRuleStatus": 0,
                "address": "SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW",
                "addressTag": "",
                "txId": "ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999",
                "insertTime": 1599620082000,
                "transferType": 0,
                "confirmTimes": "1/1",
                "unlockConfirm": 0,
                "walletType": 0,
                "requireQuestionnaire": False,
                "questionnaire": '{"question1":"answer1","question2":"answer2"}',
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_history_travel_rule()

        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/localentity/deposit/history" 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(DepositHistoryTravelRuleResponse)

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

        assert response.data() == expected

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

        params = {
            "tr_id": "1",
            "tx_id": "1",
            "tran_id": "1",
            "network": "network_example",
            "coin": "coin_example",
            "travel_rule_status": 56,
            "pending_questionnaire": True,
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "offset": 0,
            "limit": 7,
        }

        expected_response = [
            {
                "trId": 123451123,
                "tranId": 17644346245865,
                "amount": "0.001",
                "coin": "BNB",
                "network": "BNB",
                "depositStatus": 0,
                "travelRuleStatus": 1,
                "address": "bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23",
                "addressTag": "101764890",
                "txId": "98A3EA560C6B3336D348B6C83F0F95ECE4F1F5919E94BD006E5BF3BF264FACFC",
                "insertTime": 1661493146000,
                "transferType": 0,
                "confirmTimes": "1/1",
                "unlockConfirm": 0,
                "walletType": 0,
                "requireQuestionnaire": False,
                "questionnaire": None,
            },
            {
                "trId": 2451123,
                "tranId": 4544346245865,
                "amount": "0.50000000",
                "coin": "IOTA",
                "network": "IOTA",
                "depositStatus": 0,
                "travelRuleStatus": 0,
                "address": "SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW",
                "addressTag": "",
                "txId": "ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999",
                "insertTime": 1599620082000,
                "transferType": 0,
                "confirmTimes": "1/1",
                "unlockConfirm": 0,
                "walletType": 0,
                "requireQuestionnaire": False,
                "questionnaire": '{"question1":"answer1","question2":"answer2"}',
            },
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_history_travel_rule(**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/localentity/deposit/history" 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(DepositHistoryTravelRuleResponse)

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

        assert response.data() == expected

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

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

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

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

        expected_response = [
            {
                "depositId": "4615328107052018945",
                "amount": "0.01",
                "network": "AVAXC",
                "coin": "AVAX",
                "depositStatus": 1,
                "travelRuleReqStatus": 0,
                "address": "0x0010627ab66d69232f4080d54e0f838b4dc3894a",
                "addressTag": "",
                "txId": "0xdde578983015741eed764e7ca10defb5a2caafdca3db5f92872d24a96beb1879",
                "transferType": 0,
                "confirmTimes": "12/12",
                "requireQuestionnaire": False,
                "questionnaire": {"vaspName": "BINANCE", "depositOriginator": 0},
                "insertTime": 1753053392000,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_history_v2()

        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/v2/localentity/deposit/history" 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(DepositHistoryV2Response)

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

        assert response.data() == expected

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

        params = {
            "deposit_id": "1",
            "tx_id": "1",
            "network": "network_example",
            "coin": "coin_example",
            "retrieve_questionnaire": True,
            "start_time": 1623319461670,
            "end_time": 1641782889000,
            "offset": 0,
            "limit": 7,
        }

        expected_response = [
            {
                "depositId": "4615328107052018945",
                "amount": "0.01",
                "network": "AVAXC",
                "coin": "AVAX",
                "depositStatus": 1,
                "travelRuleReqStatus": 0,
                "address": "0x0010627ab66d69232f4080d54e0f838b4dc3894a",
                "addressTag": "",
                "txId": "0xdde578983015741eed764e7ca10defb5a2caafdca3db5f92872d24a96beb1879",
                "transferType": 0,
                "confirmTimes": "12/12",
                "requireQuestionnaire": False,
                "questionnaire": {"vaspName": "BINANCE", "depositOriginator": 0},
                "insertTime": 1753053392000,
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.deposit_history_v2(**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/v2/localentity/deposit/history" 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(DepositHistoryV2Response)

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

        assert response.data() == expected

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

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

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

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

        expected_response = [
            {
                "status": "PENDING",
                "token": "AVAX",
                "network": "AVAXC",
                "walletAddress": "0xc03a6aa728a8dde7464c33828424ede7553a0021",
                "addressQuestionnaire": {
                    "sendTo": 1,
                    "satoshiToken": "AVAX",
                    "isAddressOwner": 1,
                    "verifyMethod": 1,
                },
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.fetch_address_verification_list()

        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/addressVerify/list" 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(FetchAddressVerificationListResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = [
            {
                "status": "PENDING",
                "token": "AVAX",
                "network": "AVAXC",
                "walletAddress": "0xc03a6aa728a8dde7464c33828424ede7553a0021",
                "addressQuestionnaire": {
                    "sendTo": 1,
                    "satoshiToken": "AVAX",
                    "isAddressOwner": 1,
                    "verifyMethod": 1,
                },
            }
        ]
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

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

