From 324432ff921f6033ed8a08cf8acd87c29f20267c Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Fri, 13 Mar 2026 16:37:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AF=B9=20key=5Ffie?= =?UTF-8?q?ld/key=5Fvalue=20=E5=8F=82=E6=95=B0=E7=9A=84=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E8=87=AA=E5=8A=A8=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=BA=20filters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytests/test_plugin_runtime.py | 38 +++++++++++++++++++++++++++++++ src/plugin_runtime/integration.py | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/pytests/test_plugin_runtime.py b/pytests/test_plugin_runtime.py index 004b7292..887628e5 100644 --- a/pytests/test_plugin_runtime.py +++ b/pytests/test_plugin_runtime.py @@ -1832,6 +1832,44 @@ class TestSupervisor: class TestIntegration: """运行时集成层启动/清理测试""" + @pytest.mark.asyncio + async def test_cap_database_get_with_filters_does_not_reference_unbound_key_value(self, monkeypatch): + from src.plugin_runtime import integration as integration_module + import src.common.database.database_model as real_db_models + from src.services import database_service as real_database_service + + captured: dict[str, object] = {} + + class DummyModel: + pass + + async def fake_db_get(model_class, filters=None, limit=None, order_by=None, single_result=False): + captured["model_class"] = model_class + captured["filters"] = filters + captured["limit"] = limit + captured["order_by"] = order_by + captured["single_result"] = single_result + return [{"id": 1}] + + monkeypatch.setattr(real_database_service, "db_get", fake_db_get) + monkeypatch.setattr(real_db_models, "DemoTable", DummyModel, raising=False) + + result = await integration_module.PluginRuntimeManager._cap_database_get( + "plugin_a", + "database.get", + { + "table": "DemoTable", + "filters": {"status": "active"}, + "limit": 5, + }, + ) + + assert result == {"success": True, "result": [{"id": 1}]} + assert captured["model_class"] is DummyModel + assert captured["filters"] == {"status": "active"} + assert captured["limit"] == 5 + assert captured["single_result"] is False + @pytest.mark.asyncio async def test_component_enable_rejects_ambiguous_short_name(self, monkeypatch): from src.plugin_runtime import integration as integration_module diff --git a/src/plugin_runtime/integration.py b/src/plugin_runtime/integration.py index 8e4c2cf4..3eb7cd4a 100644 --- a/src/plugin_runtime/integration.py +++ b/src/plugin_runtime/integration.py @@ -942,9 +942,9 @@ class PluginRuntimeManager: # 兼容 SDK 的 key_field/key_value 参数,自动转换为 filters filters = args.get("filters") + key_value = args.get("key_value") if not filters: key_field = args.get("key_field", "id") - key_value = args.get("key_value") if key_value is not None: filters = {key_field: key_value}