"""
Binance Gift Card REST API

OpenAPI Specification for the Binance Gift Card 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_gift_card.rest_api.api import MarketDataApi
from binance_sdk_gift_card.rest_api.models import CreateADualTokenGiftCardResponse
from binance_sdk_gift_card.rest_api.models import CreateASingleTokenGiftCardResponse
from binance_sdk_gift_card.rest_api.models import FetchRsaPublicKeyResponse
from binance_sdk_gift_card.rest_api.models import FetchTokenLimitResponse
from binance_sdk_gift_card.rest_api.models import RedeemABinanceGiftCardResponse
from binance_sdk_gift_card.rest_api.models import (
    VerifyBinanceGiftCardByGiftCardNumberResponse,
)


class TestMarketDataApi:
    @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 = MarketDataApi(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_create_a_dual_token_gift_card_success(self, mock_get_signature):
        """Test create_a_dual_token_gift_card() successfully with required parameters only."""

        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002144060553",
                "code": "6H9EKF5ECCWFBHGE",
                "expiredTime": 1727417154000,
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.create_a_dual_token_gift_card(**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/giftcard/buyCode" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["baseToken"] == "base_token_example"
        assert normalized["faceToken"] == "face_token_example"
        assert normalized["baseTokenAmount"] == 1.0

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

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

        assert response.data() == expected

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

        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
            "recv_window": 5000,
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002144060553",
                "code": "6H9EKF5ECCWFBHGE",
                "expiredTime": 1727417154000,
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.create_a_dual_token_gift_card(**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/giftcard/buyCode" 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(CreateADualTokenGiftCardResponse)

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

        assert response.data() == expected

    def test_create_a_dual_token_gift_card_missing_required_param_base_token(self):
        """Test that create_a_dual_token_gift_card() raises RequiredError when 'base_token' is missing."""
        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
        }
        params["base_token"] = None

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

    def test_create_a_dual_token_gift_card_missing_required_param_face_token(self):
        """Test that create_a_dual_token_gift_card() raises RequiredError when 'face_token' is missing."""
        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
        }
        params["face_token"] = None

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

    def test_create_a_dual_token_gift_card_missing_required_param_base_token_amount(
        self,
    ):
        """Test that create_a_dual_token_gift_card() raises RequiredError when 'base_token_amount' is missing."""
        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
        }
        params["base_token_amount"] = None

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

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

        params = {
            "base_token": "base_token_example",
            "face_token": "face_token_example",
            "base_token_amount": 1.0,
        }

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

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

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

        params = {
            "token": "token_example",
            "amount": 1.0,
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002144060553",
                "code": "6H9EKF5ECCWFBHGE",
                "expiredTime": 1727417154000,
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.create_a_single_token_gift_card(**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/giftcard/createCode" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["token"] == "token_example"
        assert normalized["amount"] == 1.0

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

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

        assert response.data() == expected

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

        params = {"token": "token_example", "amount": 1.0, "recv_window": 5000}

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002144060553",
                "code": "6H9EKF5ECCWFBHGE",
                "expiredTime": 1727417154000,
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.create_a_single_token_gift_card(**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/giftcard/createCode" 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(CreateASingleTokenGiftCardResponse)

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

        assert response.data() == expected

    def test_create_a_single_token_gift_card_missing_required_param_token(self):
        """Test that create_a_single_token_gift_card() raises RequiredError when 'token' is missing."""
        params = {
            "token": "token_example",
            "amount": 1.0,
        }
        params["token"] = None

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

    def test_create_a_single_token_gift_card_missing_required_param_amount(self):
        """Test that create_a_single_token_gift_card() raises RequiredError when 'amount' is missing."""
        params = {
            "token": "token_example",
            "amount": 1.0,
        }
        params["amount"] = None

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

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

        params = {
            "token": "token_example",
            "amount": 1.0,
        }

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

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

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

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXBBVKLAc1GQ5FsIFFqOHrPTox5noBONIKr+IAedTR9FkVxq6e65updEbfdhRNkMOeYIO2i0UylrjGC0X8YSoIszmrVHeV0l06Zh1oJuZos1+7N+WLuz9JvlPaawof3GUakTxYWWCa9+8KIbLKsoKMdfS96VT+8iOXO3quMGKUmQIDAQAB",
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.fetch_rsa_public_key()

        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/giftcard/cryptography/rsa-public-key" 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(FetchRsaPublicKeyResponse)

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

        assert response.data() == expected

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

        params = {"recv_window": 5000}

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXBBVKLAc1GQ5FsIFFqOHrPTox5noBONIKr+IAedTR9FkVxq6e65updEbfdhRNkMOeYIO2i0UylrjGC0X8YSoIszmrVHeV0l06Zh1oJuZos1+7N+WLuz9JvlPaawof3GUakTxYWWCa9+8KIbLKsoKMdfS96VT+8iOXO3quMGKUmQIDAQAB",
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.fetch_rsa_public_key(**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/giftcard/cryptography/rsa-public-key" 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(FetchRsaPublicKeyResponse)

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

        assert response.data() == expected

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

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

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

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

        params = {
            "base_token": "base_token_example",
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": [{"coin": "BNB", "fromMin": "0.01", "fromMax": "1"}],
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.fetch_token_limit(**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/giftcard/buyCode/token-limit" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["baseToken"] == "base_token_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(FetchTokenLimitResponse)

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

        assert response.data() == expected

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

        params = {"base_token": "base_token_example", "recv_window": 5000}

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": [{"coin": "BNB", "fromMin": "0.01", "fromMax": "1"}],
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.fetch_token_limit(**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/giftcard/buyCode/token-limit" 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(FetchTokenLimitResponse)

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

        assert response.data() == expected

    def test_fetch_token_limit_missing_required_param_base_token(self):
        """Test that fetch_token_limit() raises RequiredError when 'base_token' is missing."""
        params = {
            "base_token": "base_token_example",
        }
        params["base_token"] = None

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

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

        params = {
            "base_token": "base_token_example",
        }

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

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

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

        params = {
            "code": "code_example",
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002328060227",
                "identityNo": "10317392647411060736",
                "token": "BNB",
                "amount": "0.00000001",
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.redeem_a_binance_gift_card(**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/giftcard/redeemCode" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["code"] == "code_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(RedeemABinanceGiftCardResponse)

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

        assert response.data() == expected

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

        params = {
            "code": "code_example",
            "external_uid": "external_uid_example",
            "recv_window": 5000,
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {
                "referenceNo": "0033002328060227",
                "identityNo": "10317392647411060736",
                "token": "BNB",
                "amount": "0.00000001",
            },
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.redeem_a_binance_gift_card(**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/giftcard/redeemCode" 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(RedeemABinanceGiftCardResponse)

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

        assert response.data() == expected

    def test_redeem_a_binance_gift_card_missing_required_param_code(self):
        """Test that redeem_a_binance_gift_card() raises RequiredError when 'code' is missing."""
        params = {
            "code": "code_example",
        }
        params["code"] = None

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

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

        params = {
            "code": "code_example",
        }

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

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

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

        params = {
            "reference_no": "reference_no_example",
        }

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {"valid": True, "token": "BNB", "amount": "0.00000001"},
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.verify_binance_gift_card_by_gift_card_number(**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/giftcard/verify" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["referenceNo"] == "reference_no_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(VerifyBinanceGiftCardByGiftCardNumberResponse)

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

        assert response.data() == expected

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

        params = {"reference_no": "reference_no_example", "recv_window": 5000}

        expected_response = {
            "code": "000000",
            "message": "success",
            "data": {"valid": True, "token": "BNB", "amount": "0.00000001"},
            "success": True,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.verify_binance_gift_card_by_gift_card_number(**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/giftcard/verify" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"

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