Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions tests/test_query_cross_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,32 @@ def test_without_dry_run_still_raises(self, monkeypatch: MonkeyPatch) -> None:
_mock_all(monkeypatch)
with pytest.raises(ValueError, match="non consentita"):
layer_query(datasets=["ds_a"], mode="sql", sql="SELECT * FROM unknown_table")


class TestMCPWrapperDryRun:
"""Regressione: il wrapper MCP aggregate_ops.layer_query propaga dry_run.

La PR #457 ha aggiunto dry_run al backend (domain.layer) e al tool MCP
(server.py) ma non al wrapper intermedio (aggregate_ops.layer_query) →
TypeError: layer_query() got an unexpected keyword argument 'dry_run'
sul percorso reale del tool.
"""

def test_wrapper_propagates_dry_run(self, monkeypatch: MonkeyPatch) -> None:
"""Il wrapper MCP accetta dry_run e lo passa al backend."""
from toolkit.mcp.aggregate_ops import layer_query as mcp_layer_query

received: dict[str, object] = {}

def fake_backend(**kwargs: object) -> dict[str, object]:
received.update(kwargs)
return {"valid": True, "plan": "PLAN", "dry_run": True}

monkeypatch.setattr("toolkit.mcp.aggregate_ops._layer_query_core", fake_backend)

res = mcp_layer_query(
datasets=["ds_a"], layer="clean", mode="sql", sql="SELECT 1", dry_run=True
)

assert res["valid"] is True
assert received.get("dry_run") is True
3 changes: 3 additions & 0 deletions toolkit/mcp/aggregate_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def layer_query(
sql: str | None = None,
mart_index: int = 0,
table: str | None = None,
dry_run: bool = False,
) -> dict[str, Any]:
"""Query unificata su layer RAW/CLEAN/MART.

Expand All @@ -71,6 +72,7 @@ def layer_query(
sql: Query SQL per mode=sql.
mart_index: Indice tabella mart (solo pipeline mode).
table: Nome tabella mart (es ``"mart_top_sa"``).
dry_run: Se True (mode=sql), valida lo scope SQL e fa EXPLAIN senza eseguire.

Raises:
ToolkitClientError: se parametri invalidi o file non trovato.
Expand All @@ -97,6 +99,7 @@ def layer_query(
sql=sql,
mart_index=mart_index,
table=table,
dry_run=dry_run,
)
except ValueError as exc:
raise ToolkitClientError(str(exc), code=ErrorCode.INVALID_PARAMS) from exc
Expand Down
Loading