diff --git a/superset/reports/notifications/email.py b/superset/reports/notifications/email.py index 73f30f10636ff..da5244a5eac4c 100644 --- a/superset/reports/notifications/email.py +++ b/superset/reports/notifications/email.py @@ -30,6 +30,7 @@ from superset.reports.notifications.base import BaseNotification from superset.reports.notifications.exceptions import NotificationError from superset.utils.core import send_email_smtp +from superset.utils.urls import modify_url_query logger = logging.getLogger(__name__) @@ -94,6 +95,11 @@ def _get_content(self) -> EmailContent: html_table = "" call_to_action = __("Explore in Superset") + url = ( + modify_url_query(self._content.url, standalone="0") + if self._content.url is not None + else "" + ) img_tags = [] for msgid in images.keys(): img_tags.append( @@ -122,7 +128,7 @@ def _get_content(self) -> EmailContent:

{description}

- {call_to_action}

+ {call_to_action}

{html_table} {img_tag} diff --git a/superset/utils/urls.py b/superset/utils/urls.py index 029e2ada7ae76..a8a6148813d96 100644 --- a/superset/utils/urls.py +++ b/superset/utils/urls.py @@ -33,3 +33,18 @@ def headless_url(path: str, user_friendly: bool = False) -> str: def get_url_path(view: str, user_friendly: bool = False, **kwargs: Any) -> str: with current_app.test_request_context(): return headless_url(url_for(view, **kwargs), user_friendly=user_friendly) + + +def modify_url_query(url: str, **kwargs: Any) -> str: + """ + Replace or add parameters to a URL. + """ + parts = list(urllib.parse.urlsplit(url)) + params = urllib.parse.parse_qs(parts[3]) + for k, v in kwargs.items(): + if not isinstance(v, list): + v = [v] + params[k] = v + + parts[3] = "&".join(f"{k}={urllib.parse.quote(v[0])}" for k, v in params.items()) + return urllib.parse.urlunsplit(parts) diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index d91d2cd158898..f03666ec9aded 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -694,9 +694,9 @@ def test_email_chart_report_schedule( # assert that the link sent is correct assert ( 'Explore in Superset' + 'standalone=0&force=false">Explore in Superset' in email_mock.call_args[0][2] ) # Assert the email smtp address @@ -737,9 +737,9 @@ def test_email_chart_report_schedule_force_screenshot( # assert that the link sent is correct assert ( 'Explore in Superset' + 'standalone=0&force=true">Explore in Superset' in email_mock.call_args[0][2] ) # Assert the email smtp address @@ -774,9 +774,9 @@ def test_email_chart_alert_schedule( # assert that the link sent is correct assert ( 'Explore in Superset' + 'standalone=0&force=true">Explore in Superset' in email_mock.call_args[0][2] ) # Assert the email smtp address @@ -842,9 +842,9 @@ def test_email_chart_report_schedule_with_csv( # assert that the link sent is correct assert ( 'Explore in Superset' + 'standalone=0&force=false">Explore in Superset' in email_mock.call_args[0][2] ) # Assert the email smtp address diff --git a/tests/unit_tests/utils/urls_tests.py b/tests/unit_tests/utils/urls_tests.py new file mode 100644 index 0000000000000..dba38cb81af07 --- /dev/null +++ b/tests/unit_tests/utils/urls_tests.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# 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. +from superset.utils.urls import modify_url_query + +EXPLORE_CHART_LINK = "http://localhost:9000/superset/explore/?form_data=%7B%22slice_id%22%3A+76%7D&standalone=true&force=false" + +EXPLORE_DASHBOARD_LINK = "http://localhost:9000/superset/dashboard/3/?standalone=3" + + +def test_convert_chart_link() -> None: + test_url = modify_url_query(EXPLORE_CHART_LINK, standalone="0") + assert ( + test_url + == "http://localhost:9000/superset/explore/?form_data=%7B%22slice_id%22%3A%2076%7D&standalone=0&force=false" + ) + + +def test_convert_dashboard_link() -> None: + test_url = modify_url_query(EXPLORE_DASHBOARD_LINK, standalone="0") + assert test_url == "http://localhost:9000/superset/dashboard/3/?standalone=0"