aminghadersohi commented on code in PR #38405: URL: https://github.com/apache/superset/pull/38405#discussion_r2931760187
########## superset/mcp_service/chart/viz_type_names.py: ########## @@ -0,0 +1,120 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +User-friendly display names for chart viz_type identifiers. + +The single source of truth for frontend-only chart display names is the +JSON file ``viz_type_display_names.json`` in this directory. A sync- +validation test ensures it stays aligned with ``VizType.ts``. + +Legacy chart names are read from ``BaseViz.verbose_name`` in +``superset/viz.py``, avoiding a duplicate hardcoded list. +""" + +import logging +from pathlib import Path + +from superset.utils import json + +logger = logging.getLogger(__name__) + +_JSON_PATH = Path(__file__).parent / "viz_type_display_names.json" + + +def _load_frontend_display_names() -> dict[str, str]: + """Load frontend-only display names from the JSON source of truth.""" + return json.loads(_JSON_PATH.read_text(encoding="utf-8")) Review Comment: Valid. Wrapped `_load_frontend_display_names()` in try/except catching `FileNotFoundError`, `OSError`, and `ValueError`. Returns `{}` on failure with warning log. Added two tests. Fixed in 4ec8ffb. ########## tests/unit_tests/mcp_service/chart/test_viz_type_names.py: ########## @@ -0,0 +1,274 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Tests for viz_type display name mapping.""" + +import re +from pathlib import Path +from unittest.mock import MagicMock, patch + +import pytest + +from superset.mcp_service.chart.schemas import serialize_chart_object +from superset.mcp_service.chart.viz_type_names import ( + _FRONTEND_ONLY_NAMES, + get_viz_type_display_name, + VIZ_TYPE_DISPLAY_NAMES, +) +from superset.utils import json + +# Paths to the source-of-truth files +_JSON_PATH = ( + Path(__file__).resolve().parents[4] + / "superset" + / "mcp_service" + / "chart" + / "viz_type_display_names.json" +) +_VIZTYPE_TS_PATH = ( + Path(__file__).resolve().parents[4] + / "superset-frontend" + / "packages" + / "superset-ui-core" + / "src" + / "chart" + / "types" + / "VizType.ts" +) + + [email protected](autouse=True) +def _reset_cache(): + """Reset the lazy display-names cache between tests.""" + import superset.mcp_service.chart.viz_type_names as mod + + mod._display_names_cache = None + yield + mod._display_names_cache = None + + [email protected]( + ("viz_type", "expected"), + [ + # Frontend-only modern plugins + ("echarts_timeseries_line", "Line Chart"), + ("echarts_timeseries_bar", "Bar Chart"), + ("pie", "Pie Chart"), + ("pivot_table_v2", "Pivot Table"), + ("big_number_total", "Big Number"), + ("table", "Table"), + ("word_cloud", "Word Cloud"), + ("funnel", "Funnel Chart"), + ("sankey_v2", "Sankey Chart"), + ], +) +def test_frontend_only_viz_types_have_display_names( + viz_type: str, expected: str +) -> None: + assert get_viz_type_display_name(viz_type) == expected + + +def test_legacy_viz_names_loaded_from_viz_py() -> None: + """Legacy chart names are read from BaseViz.verbose_name in viz.py.""" + + class FakeLegacyViz: + viz_type = "fake_legacy" + verbose_name = "Fake Legacy Chart" + + @classmethod + def __subclasses__(cls): + return set() + + class FakeBaseViz: + viz_type = None + verbose_name = "Base Viz" + + @classmethod + def __subclasses__(cls): + return {FakeLegacyViz} + + with patch( + "superset.mcp_service.chart.viz_type_names.BaseViz", + FakeBaseViz, + create=True, + ): + # Patch the import inside _get_legacy_viz_names + import superset.mcp_service.chart.viz_type_names as mod + + with patch.object(mod, "_get_legacy_viz_names") as mock_legacy: + mock_legacy.return_value = {"fake_legacy": "Fake Legacy Chart"} + mod._display_names_cache = None + Review Comment: Agreed. Rewrote the test to patch `sys.modules["superset.viz"]` with a fake module containing a `FakeBaseViz` class hierarchy. Exercises the real function end-to-end. Fixed in 4ec8ffb. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
