mirror of
https://github.com/apache/superset.git
synced 2026-07-27 17:12:36 +00:00
fix(mcp): make list-item truncation cap configurable in get_dashboard_info (#41698)
(cherry picked from commit 62ccdfacc2)
This commit is contained in:
@@ -677,3 +677,75 @@ class TestTruncateOversizedResponse:
|
||||
assert isinstance(result, dict)
|
||||
assert result["id"] == 1 # Scalar fields preserved
|
||||
assert len(notes) > 0
|
||||
|
||||
@staticmethod
|
||||
def _build_large_dashboard_response() -> dict[str, Any]:
|
||||
"""A dashboard with 463 charts and 48 native_filters, shared by the
|
||||
default- and custom-max_list_items regression tests below."""
|
||||
return {
|
||||
"id": 1,
|
||||
"dashboard_title": "x" * 2000, # forces Phase 2 to trigger
|
||||
"charts": [{"id": i, "slice_name": f"chart_{i}"} for i in range(463)],
|
||||
"native_filters": [{"id": i, "name": f"filter_{i}"} for i in range(48)],
|
||||
}
|
||||
|
||||
def test_large_dashboard_respects_default_max_list_items(self) -> None:
|
||||
"""Regression test for the Medialab large-dashboard report.
|
||||
|
||||
A dashboard with 463 charts and 48 native_filters should have
|
||||
native_filters (48 items) left untouched under the new default cap
|
||||
of 100, while charts (463 items) is truncated to 100 — a clear
|
||||
improvement over the old flat 30-item cap, which truncated both.
|
||||
"""
|
||||
response: dict[str, Any] = self._build_large_dashboard_response()
|
||||
result: Any
|
||||
was_truncated: bool
|
||||
notes: list[str]
|
||||
result, was_truncated, notes = truncate_oversized_response(response, 3000)
|
||||
assert was_truncated is True
|
||||
assert isinstance(result, dict)
|
||||
assert len(result["charts"]) == 100
|
||||
assert len(result["native_filters"]) == 48
|
||||
assert any("charts" in n and "463" in n for n in notes)
|
||||
assert not any("native_filters" in n for n in notes)
|
||||
|
||||
def test_large_dashboard_respects_custom_max_list_items(self) -> None:
|
||||
"""A custom max_list_items below both list sizes should truncate both fields."""
|
||||
response: dict[str, Any] = self._build_large_dashboard_response()
|
||||
result: Any
|
||||
was_truncated: bool
|
||||
notes: list[str]
|
||||
result, was_truncated, notes = truncate_oversized_response(
|
||||
response, 3000, max_list_items=30
|
||||
)
|
||||
assert was_truncated is True
|
||||
assert isinstance(result, dict)
|
||||
assert len(result["charts"]) == 30
|
||||
assert len(result["native_filters"]) == 30
|
||||
assert any("charts" in n and "30" in n for n in notes)
|
||||
assert any("native_filters" in n and "30" in n for n in notes)
|
||||
|
||||
def test_custom_max_list_items_below_phase_four_survives_phase_four(self) -> None:
|
||||
"""A max_list_items below Phase 4's hardcoded 10 should not be widened.
|
||||
|
||||
Phase 2 truncates ``charts`` to 5 first; the response is still over
|
||||
budget because of the oversized ``form_data`` dict, so truncation
|
||||
proceeds to Phase 4, whose ``_truncate_lists(..., max_items=10)``
|
||||
call only shrinks lists larger than 10 — it must leave the
|
||||
already-smaller 5-item list untouched rather than re-expanding it.
|
||||
"""
|
||||
response: dict[str, Any] = {
|
||||
"id": 1,
|
||||
"charts": [{"id": i, "slice_name": f"chart_{i}"} for i in range(300)],
|
||||
"form_data": {f"key_{i}": f"val_{i}" for i in range(50)},
|
||||
}
|
||||
result: Any
|
||||
was_truncated: bool
|
||||
notes: list[str]
|
||||
result, was_truncated, notes = truncate_oversized_response(
|
||||
response, 200, max_list_items=5
|
||||
)
|
||||
assert was_truncated is True
|
||||
assert isinstance(result, dict)
|
||||
assert len(result["charts"]) == 5
|
||||
assert any("form_data" in n for n in notes)
|
||||
|
||||
Reference in New Issue
Block a user