-
Notifications
You must be signed in to change notification settings - Fork 17.7k
fix(mcp): include embedded_uuid in get_dashboard_info response #41195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
4c9dc89
643ed59
5bf5849
8badd8c
db98186
82991ab
dc405aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,6 +96,7 @@ async def test_list_dashboards_basic(mock_list, mcp_server): | |
| dashboard.uuid = "test-dashboard-uuid-1" | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -162,6 +163,7 @@ async def test_list_dashboards_with_filters(mock_list, mcp_server): | |
| dashboard.uuid = None | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -257,6 +259,7 @@ async def test_list_dashboards_with_search(mock_list, mcp_server): | |
| dashboard.uuid = None | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -351,6 +354,7 @@ async def test_get_dashboard_info_success( | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -429,6 +433,7 @@ async def test_get_dashboard_info_permalink_does_not_double_sanitize( | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| mock_info.return_value = dashboard | ||
| permalink_value = { | ||
|
|
@@ -521,6 +526,7 @@ async def test_get_dashboard_info_permalink_key_includes_filter_state( | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| mock_info.return_value = dashboard | ||
|
|
||
|
|
@@ -767,6 +773,7 @@ async def test_get_dashboard_info_does_not_expose_access_list_or_roles( | |
| dashboard.owners = [owner] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [dashboard_role] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_info.return_value = dashboard | ||
|
|
||
|
|
@@ -838,6 +845,7 @@ async def test_get_dashboard_info_restricted_user_redacts_data_model_metadata( | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_info.return_value = dashboard | ||
|
|
||
|
|
@@ -890,6 +898,7 @@ async def test_get_dashboard_info_restricted_user_redacts_permalink_filter_state | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_info.return_value = dashboard | ||
|
|
||
|
|
@@ -1012,6 +1021,88 @@ async def test_list_dashboards_omits_requested_user_directory_fields( | |
| assert field not in data["columns_available"] | ||
|
|
||
|
|
||
| @patch("superset.mcp_service.mcp_core.ModelGetInfoCore._find_object") | ||
| @pytest.mark.asyncio | ||
| async def test_get_dashboard_info_includes_embedded_uuid(mock_find_object, mcp_server): | ||
| """Test that get_dashboard_info returns embedded_uuid when set.""" | ||
| from superset.models.embedded_dashboard import EmbeddedDashboard | ||
|
|
||
| dashboard = Mock() | ||
| dashboard.id = 1 | ||
| dashboard.dashboard_title = "Embedded Dashboard" | ||
| dashboard.slug = "" | ||
| dashboard.description = None | ||
| dashboard.css = None | ||
| dashboard.certified_by = None | ||
| dashboard.certification_details = None | ||
| dashboard.json_metadata = "{}" | ||
| dashboard.published = True | ||
| dashboard.is_managed_externally = False | ||
| dashboard.external_url = None | ||
| dashboard.created_on = None | ||
| dashboard.changed_on = None | ||
| dashboard.created_on_humanized = None | ||
| dashboard.changed_on_humanized = None | ||
| dashboard.uuid = "94b826a5-dbd5-473d-ab58-1af676ee07e4" | ||
| dashboard.url = "/dashboard/1" | ||
| dashboard.slices = [] | ||
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| embedded = Mock(spec=EmbeddedDashboard) | ||
| embedded.uuid = "37c56048-d3f1-452d-b3ae-0879802dcb1f" | ||
| dashboard.embedded = [embedded] | ||
|
|
||
| mock_find_object.return_value = dashboard | ||
| async with Client(mcp_server) as client: | ||
| result = await client.call_tool( | ||
| "get_dashboard_info", {"request": {"identifier": 1}} | ||
| ) | ||
| assert result.data["uuid"] == "94b826a5-dbd5-473d-ab58-1af676ee07e4" | ||
| assert result.data["embedded_uuid"] == "37c56048-d3f1-452d-b3ae-0879802dcb1f" | ||
|
|
||
|
|
||
| @patch("superset.mcp_service.mcp_core.ModelGetInfoCore._find_object") | ||
| @pytest.mark.asyncio | ||
| async def test_get_dashboard_info_embedded_uuid_none_when_not_embedded( | ||
| mock_find_object, mcp_server | ||
| ): | ||
|
Comment on lines
+1069
to
+1071
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Add parameter and return type annotations to this newly added async test function signature so the new code is fully typed. [custom_rule] Severity Level: Minor Why it matters? 🤔This newly added async test function lacks parameter type hints and a return type annotation. Because it is introduced in the changed code, it matches the typing rule violation exactly. (Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 1069:1071
**Comment:**
*Custom Rule: Add parameter and return type annotations to this newly added async test function signature so the new code is fully typed.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||
| """Test that embedded_uuid is None when the dashboard has not been configured | ||
| for embedding.""" | ||
| dashboard = Mock() | ||
| dashboard.id = 2 | ||
| dashboard.dashboard_title = "Non-Embedded Dashboard" | ||
| dashboard.slug = "" | ||
| dashboard.description = None | ||
| dashboard.css = None | ||
| dashboard.certified_by = None | ||
| dashboard.certification_details = None | ||
| dashboard.json_metadata = "{}" | ||
| dashboard.published = True | ||
| dashboard.is_managed_externally = False | ||
| dashboard.external_url = None | ||
| dashboard.created_on = None | ||
| dashboard.changed_on = None | ||
| dashboard.created_on_humanized = None | ||
| dashboard.changed_on_humanized = None | ||
| dashboard.uuid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" | ||
| dashboard.url = "/dashboard/2" | ||
| dashboard.slices = [] | ||
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_find_object.return_value = dashboard | ||
| async with Client(mcp_server) as client: | ||
| result = await client.call_tool( | ||
| "get_dashboard_info", {"request": {"identifier": 2}} | ||
| ) | ||
| assert result.data.get("embedded_uuid") is None | ||
|
|
||
|
|
||
| # TODO (Phase 3+): Add tests for get_dashboard_available_filters tool | ||
|
|
||
|
|
||
|
|
@@ -1044,6 +1135,7 @@ async def test_get_dashboard_info_by_uuid(mock_find_object, mcp_server): | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_find_object.return_value = dashboard | ||
| async with Client(mcp_server) as client: | ||
|
|
@@ -1083,6 +1175,7 @@ async def test_get_dashboard_info_by_slug(mock_find_object, mcp_server): | |
| dashboard.owners = [] | ||
| dashboard.tags = [] | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
|
|
||
| mock_find_object.return_value = dashboard | ||
| async with Client(mcp_server) as client: | ||
|
|
@@ -1122,6 +1215,7 @@ async def test_list_dashboards_custom_uuid_slug_columns(mock_list, mcp_server): | |
| dashboard.external_url = None | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -1203,6 +1297,7 @@ async def test_list_dashboards_sanitizes_dashboard_descriptions_and_filter_text( | |
| dashboard.external_url = None | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| dashboard._mapping = { | ||
| "id": dashboard.id, | ||
|
|
@@ -1343,6 +1438,7 @@ async def test_default_columns_in_response(self, mock_list, mcp_server): | |
| dashboard.external_url = None | ||
| dashboard.thumbnail_url = None | ||
| dashboard.roles = [] | ||
| dashboard.embedded = [] | ||
| dashboard.charts = [] | ||
| mock_list.return_value = ([dashboard], 1) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Add explicit type annotations for all parameters and the return type in this new async test function to comply with the project typing rule for newly introduced code. [custom_rule]
Severity Level: Minor⚠️
Why it matters? 🤔
This is a newly added Python async function in a modified file, and its parameters are untyped with no return annotation. That directly violates the rule requiring new Python code to be fully typed.
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖