From 429505b134c1f9687bea8a72478901cbf70b2128 Mon Sep 17 00:00:00 2001 From: Axel-CH Date: Wed, 12 Mar 2025 10:37:39 -0400 Subject: [PATCH] test: add test_api_custom_data_multiple_open_trades to validate api route behaviour --- tests/rpc/test_rpc_apiserver.py | 141 ++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 55a1b5a76..4cb7424bf 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -882,6 +882,147 @@ def test_api_custom_data_single_trade(botclient, fee): assert rc.json()["detail"] == "No trade found for trade_id: 13" +@pytest.mark.usefixtures("init_persistence") +def test_api_custom_data_multiple_open_trades(botclient, fee): + use_db = True + Trade.use_db = use_db + Trade.reset_trades() + CustomDataWrapper.reset_custom_data() + create_mock_trades(fee, False, use_db) + trades = Trade.get_trades_proxy() + assert len(trades) == 6 + + assert isinstance(trades[0], Trade) + + trades = Trade.get_trades_proxy(is_open=True) + assert len(trades) == 4 + + create_mock_trades_usdt(fee, use_db=True) + + trade1 = Trade.get_trades_proxy(is_open=True)[0] + trade2 = Trade.get_trades_proxy(is_open=True)[1] + + # Initially, no custom data should be present. + assert trade1.get_all_custom_data() == [] + assert trade2.get_all_custom_data() == [] + + # Set custom data for the two open trades. + trade1.set_custom_data("test_str", "test_value_t1") + trade1.set_custom_data("test_float", 1.54) + trade1.set_custom_data("test_dict", {"test_t1": "vl_t1"}) + + trade2.set_custom_data("test_str", "test_value_t2") + trade2.set_custom_data("test_float", 1.55) + trade2.set_custom_data("test_dict", {"test_t2": "vl_t2"}) + + _, client = botclient + + # CASE 1: Checking all custom data for both trades. + rc = client_get(client, f"{BASE_URI}/trades/open/custom-data") + assert_response(rc) + + response_json = rc.json() + + # Expecting two trade entries in the response + assert len(response_json) == 2, ( + f"\nError: Expected 2 trade entries, but got {len(response_json)}.\n" + ) + + # Define expected custom data for each trade. + # The keys now use the actual trade_ids from the custom data. + expected_custom_data = { + 1: [ + { + "id": 1, + "ft_trade_id": 1, + "cd_key": "test_str", + "cd_type": "str", + "cd_value": "test_value_t1", + }, + { + "id": 2, + "ft_trade_id": 1, + "cd_key": "test_float", + "cd_type": "float", + "cd_value": "1.54", + }, + { + "id": 3, + "ft_trade_id": 1, + "cd_key": "test_dict", + "cd_type": "dict", + "cd_value": '{"test_t1": "vl_t1"}', + }, + ], + 4: [ + { + "id": 4, + "ft_trade_id": 4, + "cd_key": "test_str", + "cd_type": "str", + "cd_value": "test_value_t2", + }, + { + "id": 5, + "ft_trade_id": 4, + "cd_key": "test_float", + "cd_type": "float", + "cd_value": "1.55", + }, + { + "id": 6, + "ft_trade_id": 4, + "cd_key": "test_dict", + "cd_type": "dict", + "cd_value": '{"test_t2": "vl_t2"}', + }, + ], + } + + # Iterate over each trade's data in the response and validate entries. + for trade_entry in response_json: + trade_id = trade_entry.get("trade_id") + assert trade_id in expected_custom_data, f"\nUnexpected trade_id: {trade_id}" + + custom_data_list = trade_entry.get("custom_data") + expected_data = expected_custom_data[trade_id] + assert len(custom_data_list) == len(expected_data), ( + f"\nError for trade_id {trade_id}: \ + Expected {len(expected_data)} entries, but got {len(custom_data_list)}.\n" + ) + + # For each expected entry, check that the response contains the correct entry. + for expected in expected_data: + matched_item = None + for item in custom_data_list: + if item["cd_key"] == expected["cd_key"]: + matched_item = item + break + + assert matched_item is not None, ( + f"\nError: For trade_id {trade_id}, \ + missing expected entry for key '{expected['cd_key']}'\n" + f"Expected: {expected}\n" + ) + + # Validate key fields. + mismatches = [] + for field in ["id", "ft_trade_id", "cd_key", "cd_type", "cd_value"]: + if matched_item[field] != expected[field]: + mismatches.append( + f"{field}: Expected {expected[field]}, Got {matched_item[field]}" + ) + # Check for field presence of created_at and updated_at without comparing values. + for field in ["created_at", "updated_at"]: + if field not in matched_item: + mismatches.append(f"Missing field: {field}") + + assert not mismatches, ( + f"\nError in entry '{expected['cd_key']}' for trade_id {trade_id}:\n" + + "\n".join(mismatches) + ) + + @pytest.mark.parametrize("is_short", [True, False]) def test_api_delete_trade(botclient, mocker, fee, markets, is_short): ftbot, client = botclient