mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
fix(mcp): Handle big_number charts and make semantic warnings non-blocking (#37142)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Tests for the get_chart_data request schema
|
||||
Tests for the get_chart_data request schema and big_number chart handling.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
@@ -24,6 +24,134 @@ import pytest
|
||||
from superset.mcp_service.chart.schemas import GetChartDataRequest
|
||||
|
||||
|
||||
class TestBigNumberChartFallback:
|
||||
"""Tests for big_number chart fallback query construction."""
|
||||
|
||||
def test_big_number_uses_singular_metric(self):
|
||||
"""Test that big_number charts use 'metric' (singular) from form_data."""
|
||||
# Mock form_data for big_number chart
|
||||
form_data = {
|
||||
"metric": {"label": "Count", "expressionType": "SIMPLE", "column": None},
|
||||
"viz_type": "big_number",
|
||||
}
|
||||
|
||||
# Verify the metric extraction logic
|
||||
metric = form_data.get("metric")
|
||||
metrics = [metric] if metric else []
|
||||
|
||||
assert len(metrics) == 1
|
||||
assert metrics[0]["label"] == "Count"
|
||||
|
||||
def test_big_number_total_uses_singular_metric(self):
|
||||
"""Test that big_number_total charts use 'metric' (singular)."""
|
||||
form_data = {
|
||||
"metric": {"label": "Total Sales", "expressionType": "SQL"},
|
||||
"viz_type": "big_number_total",
|
||||
}
|
||||
|
||||
metric = form_data.get("metric")
|
||||
metrics = [metric] if metric else []
|
||||
|
||||
assert len(metrics) == 1
|
||||
assert metrics[0]["label"] == "Total Sales"
|
||||
|
||||
def test_big_number_empty_metric_returns_empty_list(self):
|
||||
"""Test handling of big_number chart with no metric configured."""
|
||||
form_data = {
|
||||
"metric": None,
|
||||
"viz_type": "big_number",
|
||||
}
|
||||
|
||||
metric = form_data.get("metric")
|
||||
metrics = [metric] if metric else []
|
||||
|
||||
assert len(metrics) == 0
|
||||
|
||||
def test_big_number_no_groupby_columns(self):
|
||||
"""Test that big_number charts don't have groupby columns."""
|
||||
form_data = {
|
||||
"metric": {"label": "Count"},
|
||||
"viz_type": "big_number",
|
||||
"groupby": ["should_be_ignored"], # This should be ignored
|
||||
}
|
||||
|
||||
viz_type = form_data.get("viz_type", "")
|
||||
if viz_type.startswith("big_number"):
|
||||
groupby_columns: list[str] = [] # big_number charts don't group by
|
||||
else:
|
||||
groupby_columns = form_data.get("groupby", [])
|
||||
|
||||
assert groupby_columns == []
|
||||
|
||||
def test_standard_chart_uses_plural_metrics(self):
|
||||
"""Test that non-big_number charts use 'metrics' (plural)."""
|
||||
form_data = {
|
||||
"metrics": [
|
||||
{"label": "Sum of Sales"},
|
||||
{"label": "Avg of Quantity"},
|
||||
],
|
||||
"groupby": ["region", "category"],
|
||||
"viz_type": "table",
|
||||
}
|
||||
|
||||
viz_type = form_data.get("viz_type", "")
|
||||
if viz_type.startswith("big_number"):
|
||||
metric = form_data.get("metric")
|
||||
metrics = [metric] if metric else []
|
||||
groupby_columns: list[str] = []
|
||||
else:
|
||||
metrics = form_data.get("metrics", [])
|
||||
groupby_columns = form_data.get("groupby", [])
|
||||
|
||||
assert len(metrics) == 2
|
||||
assert len(groupby_columns) == 2
|
||||
|
||||
def test_viz_type_detection_for_single_metric_charts(self):
|
||||
"""Test viz_type detection handles all single-metric chart types."""
|
||||
# Chart types that use "metric" (singular) instead of "metrics" (plural)
|
||||
single_metric_types = ("big_number", "pop_kpi")
|
||||
|
||||
# big_number variants match via startswith
|
||||
big_number_types = ["big_number", "big_number_total"]
|
||||
for viz_type in big_number_types:
|
||||
is_single_metric = (
|
||||
viz_type.startswith("big_number") or viz_type in single_metric_types
|
||||
)
|
||||
assert is_single_metric is True
|
||||
|
||||
# pop_kpi (BigNumberPeriodOverPeriod) matches via exact match
|
||||
assert "pop_kpi" in single_metric_types
|
||||
|
||||
# Verify standard chart types don't match
|
||||
other_types = ["table", "line", "bar", "pie", "echarts_timeseries"]
|
||||
for viz_type in other_types:
|
||||
is_single_metric = (
|
||||
viz_type.startswith("big_number") or viz_type in single_metric_types
|
||||
)
|
||||
assert is_single_metric is False
|
||||
|
||||
def test_pop_kpi_uses_singular_metric(self):
|
||||
"""Test that pop_kpi (BigNumberPeriodOverPeriod) uses singular metric."""
|
||||
form_data = {
|
||||
"metric": {"label": "Period Comparison", "expressionType": "SQL"},
|
||||
"viz_type": "pop_kpi",
|
||||
}
|
||||
|
||||
viz_type = form_data.get("viz_type", "")
|
||||
single_metric_types = ("big_number", "pop_kpi")
|
||||
if viz_type.startswith("big_number") or viz_type in single_metric_types:
|
||||
metric = form_data.get("metric")
|
||||
metrics = [metric] if metric else []
|
||||
groupby_columns: list[str] = []
|
||||
else:
|
||||
metrics = form_data.get("metrics", [])
|
||||
groupby_columns = form_data.get("groupby", [])
|
||||
|
||||
assert len(metrics) == 1
|
||||
assert metrics[0]["label"] == "Period Comparison"
|
||||
assert groupby_columns == []
|
||||
|
||||
|
||||
class TestGetChartDataRequestSchema:
|
||||
"""Test the GetChartDataRequest schema validation."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user