From 2150f0ee0bec2d664009f76e9844fb7c8e6853fc Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Tue, 16 Apr 2024 17:03:13 -0400 Subject: [PATCH 1/3] fix: Fix slug repeating language and change tab name --- platform_plugin_aspects/extensions/filters.py | 2 +- .../extensions/tests/test_filters.py | 4 +- .../static/html/superset.html | 2 +- platform_plugin_aspects/tests/test_utils.py | 38 ++++++++++++++++++- platform_plugin_aspects/utils.py | 35 +++++++++++++---- test_settings.py | 4 +- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/platform_plugin_aspects/extensions/filters.py b/platform_plugin_aspects/extensions/filters.py index 982f389..c50bd68 100644 --- a/platform_plugin_aspects/extensions/filters.py +++ b/platform_plugin_aspects/extensions/filters.py @@ -55,7 +55,7 @@ def run_filter( section_data = { "fragment": frag, "section_key": BLOCK_CATEGORY, - "section_display_name": _("Analytics"), + "section_display_name": _("Reports"), "course_id": str(context.get("course_id")), "superset_guest_token_url": str(context.get("superset_guest_token_url")), "superset_url": str(context.get("superset_url")), diff --git a/platform_plugin_aspects/extensions/tests/test_filters.py b/platform_plugin_aspects/extensions/tests/test_filters.py index adc229e..0954322 100644 --- a/platform_plugin_aspects/extensions/tests/test_filters.py +++ b/platform_plugin_aspects/extensions/tests/test_filters.py @@ -42,7 +42,7 @@ def test_run_filter_with_language( { "course_id": self.course_id, "section_key": BLOCK_CATEGORY, - "section_display_name": "Analytics", + "section_display_name": "Reports", "superset_url": "http://superset-dummy-url/", "superset_guest_token_url": f"https://lms.url/superset_guest_token/{self.course_id}", "template_path_prefix": "/instructor_dashboard/", @@ -70,7 +70,7 @@ def test_run_filter_without_language( { "course_id": self.course_id, "section_key": BLOCK_CATEGORY, - "section_display_name": "Analytics", + "section_display_name": "Reports", "superset_url": "http://superset-dummy-url/", "superset_guest_token_url": f"https://lms.url/superset_guest_token/{self.course_id}", "template_path_prefix": "/instructor_dashboard/", diff --git a/platform_plugin_aspects/static/html/superset.html b/platform_plugin_aspects/static/html/superset.html index fd5e9fb..792d346 100644 --- a/platform_plugin_aspects/static/html/superset.html +++ b/platform_plugin_aspects/static/html/superset.html @@ -29,7 +29,7 @@

{{display_name}}

{% endif %} diff --git a/platform_plugin_aspects/tests/test_utils.py b/platform_plugin_aspects/tests/test_utils.py index 11ca2aa..be480cd 100644 --- a/platform_plugin_aspects/tests/test_utils.py +++ b/platform_plugin_aspects/tests/test_utils.py @@ -121,7 +121,8 @@ def test_generate_superset_context(self): context["superset_guest_token_url"], f"https://lms.url/superset_guest_token/{COURSE_ID}", ) - self.assertEqual(context["superset_dashboards"], dashboards) + + self.assertEqual(len(context["superset_dashboards"]), len(dashboards)) self.assertEqual(context["superset_url"], "http://superset-dummy-url/") self.assertNotIn("superset_token", context) self.assertNotIn("exception", context) @@ -195,3 +196,38 @@ def test_generate_guest_token_succesful(self, mock_superset_client): mock_superset_client.assert_called_once() self.assertEqual(token, "test-token") + + @patch("platform_plugin_aspects.utils.SupersetClient") + def test_generate_guest_token_loc(self, mock_superset_client): + """ + Test generate_guest_token works. + """ + response_mock = Mock(status_code=200) + mock_superset_client.return_value.session.post.return_value = response_mock + response_mock.json.return_value = { + "token": "test-token", + } + + filter_mock = Mock() + user_mock = Mock() + dashboards = [ + { + "name": "test", + "uuid": "1d6bf904-f53f-47fd-b1c9-6cd7e284d286", + "allow_translations": True, + } + ] + + token = generate_guest_token( + user=user_mock, + course=COURSE_ID, + dashboards=dashboards, + filters=[filter_mock], + ) + + mock_superset_client.assert_called_once() + self.assertEqual(token, "test-token") + + # We should have one resource for en_US, one for es_419, and one untranslated + calls = mock_superset_client.return_value.session.post.call_args + self.assertEqual(len(calls[1]["json"]["resources"]), 3) diff --git a/platform_plugin_aspects/utils.py b/platform_plugin_aspects/utils.py index cb1fe39..ed7bf93 100644 --- a/platform_plugin_aspects/utils.py +++ b/platform_plugin_aspects/utils.py @@ -4,6 +4,8 @@ from __future__ import annotations +import copy +import json import logging import os import uuid @@ -49,12 +51,15 @@ def generate_superset_context( course_id = context["course_id"] superset_config = settings.SUPERSET_CONFIG + # We're modifying this, keep a local copy + rtn_dashboards = copy.deepcopy(dashboards) + if language: - for dashboard in dashboards: + for dashboard in rtn_dashboards: if not dashboard.get("allow_translations"): continue dashboard["slug"] = f"{dashboard['slug']}-{language}" - dashboard["uuid"] = str(get_uuid5(dashboard["uuid"], language)) + dashboard["uuid"] = get_localized_uuid(dashboard["uuid"], language) superset_url = _fix_service_url(superset_config.get("service_url")) @@ -69,7 +74,8 @@ def generate_superset_context( context.update( { - "superset_dashboards": dashboards, + "superset_dashboards": rtn_dashboards, + "superset_dashboards_json": json.dumps(rtn_dashboards), "superset_url": superset_url, "superset_guest_token_url": guest_token_url, } @@ -104,11 +110,24 @@ def generate_guest_token(user, course, dashboards, filters) -> str: formatted_filters = [filter.format(course=course, user=user) for filter in filters] + resources = [] + + # Get permissions for all localized versions of the dashboards + for dashboard in dashboards: + resources.append({"type": "dashboard", "id": dashboard["uuid"]}) + + if dashboard.get("allow_translations"): + for locale in settings.SUPERSET_DASHBOARD_LOCALES: + resources.append( + { + "type": "dashboard", + "id": get_localized_uuid(dashboard["uuid"], locale), + } + ) + data = { "user": _superset_user_data(user), - "resources": [ - {"type": "dashboard", "id": dashboard["uuid"]} for dashboard in dashboards - ], + "resources": resources, "rls": [{"clause": filter} for filter in formatted_filters], } @@ -245,10 +264,10 @@ def get_ccx_courses(course_id): return [] -def get_uuid5(base_uuid, language): +def get_localized_uuid(base_uuid, language): """ Generate an idempotent uuid. """ base_uuid = uuid.UUID(base_uuid) base_namespace = uuid.uuid5(base_uuid, "superset") - return uuid.uuid5(base_namespace, language) + return str(uuid.uuid5(base_namespace, language)) diff --git a/test_settings.py b/test_settings.py index 8ab4b80..d13b797 100644 --- a/test_settings.py +++ b/test_settings.py @@ -33,8 +33,8 @@ # Disable caching in tests. CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', + "default": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", } } From 1c6217cc2887857cad43a57276160f31b5a6943b Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Wed, 17 Apr 2024 10:22:36 -0400 Subject: [PATCH 2/3] chore: Bump version, update changelog --- CHANGELOG.rst | 9 +++++++++ platform_plugin_aspects/__init__.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f07e857..a208e5f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,15 @@ Unreleased * +0.7.1 - 2024-04-17 +****************** + +Fixed +===== + +* Fixed issue with embedded dashboards throwing javascript errors +* Fixed issues with translated embedded dashboards erroring in Superset + 0.7.0 - 2024-04-12 ****************** diff --git a/platform_plugin_aspects/__init__.py b/platform_plugin_aspects/__init__.py index 1c8e7db..468a968 100644 --- a/platform_plugin_aspects/__init__.py +++ b/platform_plugin_aspects/__init__.py @@ -5,6 +5,6 @@ import os from pathlib import Path -__version__ = "0.7.0" +__version__ = "0.7.1" ROOT_DIRECTORY = Path(os.path.dirname(os.path.abspath(__file__))) From 8c9b9478c34bc3a201c3f6b7a5df5022eb74d2d6 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Wed, 17 Apr 2024 11:44:50 -0400 Subject: [PATCH 3/3] refactor: Use json_script instead of python json for dashboards --- platform_plugin_aspects/static/html/superset.html | 4 +++- platform_plugin_aspects/utils.py | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform_plugin_aspects/static/html/superset.html b/platform_plugin_aspects/static/html/superset.html index 792d346..df2caee 100644 --- a/platform_plugin_aspects/static/html/superset.html +++ b/platform_plugin_aspects/static/html/superset.html @@ -28,8 +28,10 @@

{{display_name}}

{% endif %} + {{superset_dashboards|json_script:"superset_dashboards"}} + diff --git a/platform_plugin_aspects/utils.py b/platform_plugin_aspects/utils.py index ed7bf93..69e6856 100644 --- a/platform_plugin_aspects/utils.py +++ b/platform_plugin_aspects/utils.py @@ -5,7 +5,6 @@ from __future__ import annotations import copy -import json import logging import os import uuid @@ -75,7 +74,6 @@ def generate_superset_context( context.update( { "superset_dashboards": rtn_dashboards, - "superset_dashboards_json": json.dumps(rtn_dashboards), "superset_url": superset_url, "superset_guest_token_url": guest_token_url, }