"""
Binance Mining REST API

OpenAPI Specification for the Binance Mining 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_mining.rest_api.api import MiningApi
from binance_sdk_mining.rest_api.models import AccountListResponse
from binance_sdk_mining.rest_api.models import AcquiringAlgorithmResponse
from binance_sdk_mining.rest_api.models import AcquiringCoinnameResponse
from binance_sdk_mining.rest_api.models import CancelHashrateResaleConfigurationResponse
from binance_sdk_mining.rest_api.models import EarningsListResponse
from binance_sdk_mining.rest_api.models import ExtraBonusListResponse
from binance_sdk_mining.rest_api.models import HashrateResaleDetailResponse
from binance_sdk_mining.rest_api.models import HashrateResaleListResponse
from binance_sdk_mining.rest_api.models import HashrateResaleRequestResponse
from binance_sdk_mining.rest_api.models import MiningAccountEarningResponse
from binance_sdk_mining.rest_api.models import RequestForDetailMinerListResponse
from binance_sdk_mining.rest_api.models import RequestForMinerListResponse
from binance_sdk_mining.rest_api.models import StatisticListResponse


class TestMiningApi:
    @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 = MiningApi(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_list_success(self, mock_get_signature):
        """Test account_list() successfully with required parameters only."""

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": [
                {
                    "type": "H_hashrate",
                    "userName": "test",
                    "list": [
                        {
                            "time": 1585267200000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                        {
                            "time": 1585353600000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                    ],
                },
                {
                    "type": "D_hashrate",
                    "userName": "test",
                    "list": [
                        {
                            "time": 1587906000000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                        {
                            "time": 1587909600000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                    ],
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/mining/statistics/user/list" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["algo"] == "algo_example"
        assert normalized["userName"] == "user_name_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(AccountListResponse)

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

        assert response.data() == expected

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
            "recv_window": 5000,
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": [
                {
                    "type": "H_hashrate",
                    "userName": "test",
                    "list": [
                        {
                            "time": 1585267200000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                        {
                            "time": 1585353600000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                    ],
                },
                {
                    "type": "D_hashrate",
                    "userName": "test",
                    "list": [
                        {
                            "time": 1587906000000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                        {
                            "time": 1587909600000,
                            "hashrate": "0.00000000",
                            "reject": "0.00000000",
                        },
                    ],
                },
            ],
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.account_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/mining/statistics/user/list" 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(AccountListResponse)

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

        assert response.data() == expected

    def test_account_list_missing_required_param_algo(self):
        """Test that account_list() raises RequiredError when 'algo' is missing."""
        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }
        params["algo"] = None

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

    def test_account_list_missing_required_param_user_name(self):
        """Test that account_list() raises RequiredError when 'user_name' is missing."""
        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }
        params["user_name"] = None

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

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }

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

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

    def test_acquiring_algorithm_success(self):
        """Test acquiring_algorithm() successfully with required parameters only."""

        expected_response = {
            "code": 0,
            "msg": "",
            "data": [
                {"algoName": "sha256", "algoId": 1, "poolIndex": 0, "unit": "h/s"}
            ],
        }

        self.set_mock_response(expected_response)

        response = self.client.acquiring_algorithm()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/mining/pub/algoList" 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(AcquiringAlgorithmResponse)

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

        assert response.data() == expected

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

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

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

    def test_acquiring_coinname_success(self):
        """Test acquiring_coinname() successfully with required parameters only."""

        expected_response = {
            "code": 0,
            "msg": "",
            "data": [
                {
                    "coinName": "BTC",
                    "coinId": 1,
                    "poolIndex": 0,
                    "algoId": 1,
                    "algoName": "sha256",
                }
            ],
        }

        self.set_mock_response(expected_response)

        response = self.client.acquiring_coinname()

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

        self.mock_session.request.assert_called_once()

        assert "url" in request_kwargs
        assert "/sapi/v1/mining/pub/coinList" 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(AcquiringCoinnameResponse)

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

        assert response.data() == expected

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

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

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

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

        params = {
            "config_id": 1,
            "user_name": "user_name_example",
        }

        expected_response = {"code": 0, "msg": "", "data": True}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_hashrate_resale_configuration(**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/mining/hash-transfer/config/cancel" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["configId"] == 1
        assert normalized["userName"] == "user_name_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(CancelHashrateResaleConfigurationResponse)

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

        assert response.data() == expected

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

        params = {"config_id": 1, "user_name": "user_name_example", "recv_window": 5000}

        expected_response = {"code": 0, "msg": "", "data": True}
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.cancel_hashrate_resale_configuration(**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/mining/hash-transfer/config/cancel" 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(CancelHashrateResaleConfigurationResponse)

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

        assert response.data() == expected

    def test_cancel_hashrate_resale_configuration_missing_required_param_config_id(
        self,
    ):
        """Test that cancel_hashrate_resale_configuration() raises RequiredError when 'config_id' is missing."""
        params = {
            "config_id": 1,
            "user_name": "user_name_example",
        }
        params["config_id"] = None

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

    def test_cancel_hashrate_resale_configuration_missing_required_param_user_name(
        self,
    ):
        """Test that cancel_hashrate_resale_configuration() raises RequiredError when 'user_name' is missing."""
        params = {
            "config_id": 1,
            "user_name": "user_name_example",
        }
        params["user_name"] = None

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

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

        params = {
            "config_id": 1,
            "user_name": "user_name_example",
        }

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

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

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": {
                "accountProfits": [
                    {
                        "time": 1586188800000,
                        "type": 31,
                        "hashTransfer": None,
                        "transferAmount": None,
                        "dayHashRate": 129129903378244,
                        "profitAmount": 8.6083060304,
                        "coinName": "BTC",
                        "status": 2,
                    },
                    {
                        "time": 1607529600000,
                        "coinName": "BTC",
                        "type": 0,
                        "dayHashRate": 9942053925926,
                        "profitAmount": 0.85426469,
                        "hashTransfer": 200000000000,
                        "transferAmount": 0.02180958,
                        "status": 2,
                    },
                    {
                        "time": 1607443200000,
                        "coinName": "BTC",
                        "type": 31,
                        "dayHashRate": 200000000000,
                        "profitAmount": 0.02905916,
                        "hashTransfer": None,
                        "transferAmount": None,
                        "status": 2,
                    },
                ],
                "totalNum": 3,
                "pageSize": 20,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/mining/payment/list" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["algo"] == "algo_example"
        assert normalized["userName"] == "user_name_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(EarningsListResponse)

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

        assert response.data() == expected

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
            "coin": "coin_example",
            "start_date": 56,
            "end_date": 56,
            "page_index": 1,
            "page_size": 56,
            "recv_window": 5000,
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": {
                "accountProfits": [
                    {
                        "time": 1586188800000,
                        "type": 31,
                        "hashTransfer": None,
                        "transferAmount": None,
                        "dayHashRate": 129129903378244,
                        "profitAmount": 8.6083060304,
                        "coinName": "BTC",
                        "status": 2,
                    },
                    {
                        "time": 1607529600000,
                        "coinName": "BTC",
                        "type": 0,
                        "dayHashRate": 9942053925926,
                        "profitAmount": 0.85426469,
                        "hashTransfer": 200000000000,
                        "transferAmount": 0.02180958,
                        "status": 2,
                    },
                    {
                        "time": 1607443200000,
                        "coinName": "BTC",
                        "type": 31,
                        "dayHashRate": 200000000000,
                        "profitAmount": 0.02905916,
                        "hashTransfer": None,
                        "transferAmount": None,
                        "status": 2,
                    },
                ],
                "totalNum": 3,
                "pageSize": 20,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.earnings_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/mining/payment/list" 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(EarningsListResponse)

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

        assert response.data() == expected

    def test_earnings_list_missing_required_param_algo(self):
        """Test that earnings_list() raises RequiredError when 'algo' is missing."""
        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }
        params["algo"] = None

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

    def test_earnings_list_missing_required_param_user_name(self):
        """Test that earnings_list() raises RequiredError when 'user_name' is missing."""
        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }
        params["user_name"] = None

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

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }

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

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

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": {
                "otherProfits": [
                    {
                        "time": 1607443200000,
                        "coinName": "BTC",
                        "type": 4,
                        "profitAmount": 0.0011859,
                        "status": 2,
                    }
                ],
                "totalNum": 3,
                "pageSize": 20,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

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

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

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

        assert "url" in request_kwargs
        assert "signature" in parse_qs(request_kwargs["params"])
        assert "/sapi/v1/mining/payment/other" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["algo"] == "algo_example"
        assert normalized["userName"] == "user_name_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(ExtraBonusListResponse)

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

        assert response.data() == expected

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

        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
            "coin": "coin_example",
            "start_date": 56,
            "end_date": 56,
            "page_index": 1,
            "page_size": 56,
            "recv_window": 5000,
        }

        expected_response = {
            "code": 0,
            "msg": "",
            "data": {
                "otherProfits": [
                    {
                        "time": 1607443200000,
                        "coinName": "BTC",
                        "type": 4,
                        "profitAmount": 0.0011859,
                        "status": 2,
                    }
                ],
                "totalNum": 3,
                "pageSize": 20,
            },
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.extra_bonus_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/mining/payment/other" 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(ExtraBonusListResponse)

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

        assert response.data() == expected

    def test_extra_bonus_list_missing_required_param_algo(self):
        """Test that extra_bonus_list() raises RequiredError when 'algo' is missing."""
        params = {
            "algo": "algo_example",
            "user_name": "user_name_example",
        }
        params["algo"] = None

