"""
Binance Crypto Loan REST API

OpenAPI Specification for the Binance Crypto Loan 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_crypto_loan.rest_api.api import FlexibleRateApi
from binance_sdk_crypto_loan.rest_api.models import CheckCollateralRepayRateResponse
from binance_sdk_crypto_loan.rest_api.models import FlexibleLoanAdjustLtvResponse
from binance_sdk_crypto_loan.rest_api.models import FlexibleLoanBorrowResponse
from binance_sdk_crypto_loan.rest_api.models import FlexibleLoanRepayResponse
from binance_sdk_crypto_loan.rest_api.models import GetFlexibleLoanAssetsDataResponse
from binance_sdk_crypto_loan.rest_api.models import GetFlexibleLoanBorrowHistoryResponse
from binance_sdk_crypto_loan.rest_api.models import (
    GetFlexibleLoanCollateralAssetsDataResponse,
)
from binance_sdk_crypto_loan.rest_api.models import (
    GetFlexibleLoanLiquidationHistoryResponse,
)
from binance_sdk_crypto_loan.rest_api.models import (
    GetFlexibleLoanLtvAdjustmentHistoryResponse,
)
from binance_sdk_crypto_loan.rest_api.models import GetFlexibleLoanOngoingOrdersResponse
from binance_sdk_crypto_loan.rest_api.models import (
    GetFlexibleLoanRepaymentHistoryResponse,
)


class TestFlexibleRateApi:
    @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 = FlexibleRateApi(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_check_collateral_repay_rate_success(self, mock_get_signature):
        """Test check_collateral_repay_rate() successfully with required parameters only."""

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "rate": "300.36781234",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.check_collateral_repay_rate(**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/v2/loan/flexible/repay/rate" in request_kwargs["url"]
        assert request_kwargs["method"] == "GET"
        assert normalized["loanCoin"] == "loan_coin_example"
        assert normalized["collateralCoin"] == "collateral_coin_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(CheckCollateralRepayRateResponse)

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

        assert response.data() == expected

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "recv_window": 5000,
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "rate": "300.36781234",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.check_collateral_repay_rate(**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/loan/flexible/repay/rate" 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(CheckCollateralRepayRateResponse)

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

        assert response.data() == expected

    def test_check_collateral_repay_rate_missing_required_param_loan_coin(self):
        """Test that check_collateral_repay_rate() raises RequiredError when 'loan_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }
        params["loan_coin"] = None

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

    def test_check_collateral_repay_rate_missing_required_param_collateral_coin(self):
        """Test that check_collateral_repay_rate() raises RequiredError when 'collateral_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }
        params["collateral_coin"] = None

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }

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

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "direction": "ADDITIONAL",
            "adjustmentAmount": "5.235",
            "currentLTV": "0.52",
            "status": "Succeeds",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_adjust_ltv(**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/v2/loan/flexible/adjust/ltv" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["loanCoin"] == "loan_coin_example"
        assert normalized["collateralCoin"] == "collateral_coin_example"
        assert normalized["adjustmentAmount"] == 1.0
        assert normalized["direction"] == "direction_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(FlexibleLoanAdjustLtvResponse)

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

        assert response.data() == expected

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
            "recv_window": 5000,
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "direction": "ADDITIONAL",
            "adjustmentAmount": "5.235",
            "currentLTV": "0.52",
            "status": "Succeeds",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_adjust_ltv(**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/loan/flexible/adjust/ltv" 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(FlexibleLoanAdjustLtvResponse)

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

        assert response.data() == expected

    def test_flexible_loan_adjust_ltv_missing_required_param_loan_coin(self):
        """Test that flexible_loan_adjust_ltv() raises RequiredError when 'loan_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }
        params["loan_coin"] = None

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

    def test_flexible_loan_adjust_ltv_missing_required_param_collateral_coin(self):
        """Test that flexible_loan_adjust_ltv() raises RequiredError when 'collateral_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }
        params["collateral_coin"] = None

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

    def test_flexible_loan_adjust_ltv_missing_required_param_adjustment_amount(self):
        """Test that flexible_loan_adjust_ltv() raises RequiredError when 'adjustment_amount' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }
        params["adjustment_amount"] = None

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

    def test_flexible_loan_adjust_ltv_missing_required_param_direction(self):
        """Test that flexible_loan_adjust_ltv() raises RequiredError when 'direction' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }
        params["direction"] = None

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "adjustment_amount": 1.0,
            "direction": "direction_example",
        }

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

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }

        expected_response = {
            "loanCoin": "BUSD",
            "loanAmount": "100.5",
            "collateralCoin": "BNB",
            "collateralAmount": "50.5",
            "status": "Succeeds",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_borrow(**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/v2/loan/flexible/borrow" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["loanCoin"] == "loan_coin_example"
        assert normalized["collateralCoin"] == "collateral_coin_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(FlexibleLoanBorrowResponse)

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

        assert response.data() == expected

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "loan_amount": 1.0,
            "collateral_amount": 1.0,
            "recv_window": 5000,
        }

        expected_response = {
            "loanCoin": "BUSD",
            "loanAmount": "100.5",
            "collateralCoin": "BNB",
            "collateralAmount": "50.5",
            "status": "Succeeds",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_borrow(**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/loan/flexible/borrow" 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(FlexibleLoanBorrowResponse)

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

        assert response.data() == expected

    def test_flexible_loan_borrow_missing_required_param_loan_coin(self):
        """Test that flexible_loan_borrow() raises RequiredError when 'loan_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }
        params["loan_coin"] = None

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

    def test_flexible_loan_borrow_missing_required_param_collateral_coin(self):
        """Test that flexible_loan_borrow() raises RequiredError when 'collateral_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }
        params["collateral_coin"] = None

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
        }

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

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "remainingDebt": "100.5",
            "remainingCollateral": "5.253",
            "fullRepayment": False,
            "currentLTV": "0.25",
            "repayStatus": "REPAID",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_repay(**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/v2/loan/flexible/repay" in request_kwargs["url"]
        assert request_kwargs["method"] == "POST"
        assert normalized["loanCoin"] == "loan_coin_example"
        assert normalized["collateralCoin"] == "collateral_coin_example"
        assert normalized["repayAmount"] == 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(FlexibleLoanRepayResponse)

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

        assert response.data() == expected

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
            "collateral_return": True,
            "full_repayment": False,
            "repayment_type": 1,
            "recv_window": 5000,
        }

        expected_response = {
            "loanCoin": "BUSD",
            "collateralCoin": "BNB",
            "remainingDebt": "100.5",
            "remainingCollateral": "5.253",
            "fullRepayment": False,
            "currentLTV": "0.25",
            "repayStatus": "REPAID",
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.flexible_loan_repay(**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/loan/flexible/repay" 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(FlexibleLoanRepayResponse)

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

        assert response.data() == expected

    def test_flexible_loan_repay_missing_required_param_loan_coin(self):
        """Test that flexible_loan_repay() raises RequiredError when 'loan_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
        }
        params["loan_coin"] = None

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

    def test_flexible_loan_repay_missing_required_param_collateral_coin(self):
        """Test that flexible_loan_repay() raises RequiredError when 'collateral_coin' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
        }
        params["collateral_coin"] = None

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

    def test_flexible_loan_repay_missing_required_param_repay_amount(self):
        """Test that flexible_loan_repay() raises RequiredError when 'repay_amount' is missing."""
        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
        }
        params["repay_amount"] = None

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

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

        params = {
            "loan_coin": "loan_coin_example",
            "collateral_coin": "collateral_coin_example",
            "repay_amount": 1.0,
        }

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

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

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

        expected_response = {
            "rows": [
                {
                    "loanCoin": "BUSD",
                    "flexibleInterestRate": "0.00000491",
                    "flexibleMinLimit": "100",
                    "flexibleMaxLimit": "1000000",
                }
            ],
            "total": 1,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.get_flexible_loan_assets_data()

        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/loan/flexible/loanable/data" 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(GetFlexibleLoanAssetsDataResponse)

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

        assert response.data() == expected

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

        params = {"loan_coin": "loan_coin_example", "recv_window": 5000}

        expected_response = {
            "rows": [
                {
                    "loanCoin": "BUSD",
                    "flexibleInterestRate": "0.00000491",
                    "flexibleMinLimit": "100",
                    "flexibleMaxLimit": "1000000",
                }
            ],
            "total": 1,
        }
        mock_get_signature.return_value = "mocked_signature"
        self.set_mock_response(expected_response)

        response = self.client.get_flexible_loan_assets_data(**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/loan/flexible/loanable/data" 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(GetFlexibleLoanAssetsDataResponse)

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

        assert response.data() == expected

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

