You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by dp...@apache.org on 2020/03/30 15:10:27 UTC

[incubator-superset] branch master updated: [dashboards] Fix, API update slug uniqueness refusing empty string (#9417)

This is an automated email from the ASF dual-hosted git repository.

dpgaspar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 752de8f  [dashboards] Fix, API update slug uniqueness refusing empty string (#9417)
752de8f is described below

commit 752de8fe9de4a3e4f41404cc3d6d762ea9848f2f
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Mon Mar 30 16:10:08 2020 +0100

    [dashboards] Fix, API update slug uniqueness refusing empty string (#9417)
    
    * [dashboards] Fix, API update slug uniqueness refusing empty string
    
    * [dashboards] tests
---
 superset/dashboards/commands/update.py |  2 +-
 superset/dashboards/dao.py             | 14 ++++++++------
 tests/dashboards/api_tests.py          | 15 ++++++++++++++-
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/superset/dashboards/commands/update.py b/superset/dashboards/commands/update.py
index 27cd13d..f324835 100644
--- a/superset/dashboards/commands/update.py
+++ b/superset/dashboards/commands/update.py
@@ -57,7 +57,7 @@ class UpdateDashboardCommand(BaseCommand):
     def validate(self) -> None:
         exceptions: List[ValidationError] = []
         owner_ids: Optional[List[int]] = self._properties.get("owners")
-        slug: str = self._properties.get("slug", "")
+        slug: Optional[str] = self._properties.get("slug")
 
         # Validate/populate model exists
         self._model = DashboardDAO.find_by_id(self._model_id)
diff --git a/superset/dashboards/dao.py b/superset/dashboards/dao.py
index 86684bb..923a9c9 100644
--- a/superset/dashboards/dao.py
+++ b/superset/dashboards/dao.py
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 import logging
-from typing import List
+from typing import List, Optional
 
 from sqlalchemy.exc import SQLAlchemyError
 
@@ -39,11 +39,13 @@ class DashboardDAO(BaseDAO):
         return not db.session.query(dashboard_query.exists()).scalar()
 
     @staticmethod
-    def validate_update_slug_uniqueness(dashboard_id: int, slug: str) -> bool:
-        dashboard_query = db.session.query(Dashboard).filter(
-            Dashboard.slug == slug, Dashboard.id != dashboard_id
-        )
-        return not db.session.query(dashboard_query.exists()).scalar()
+    def validate_update_slug_uniqueness(dashboard_id: int, slug: Optional[str]) -> bool:
+        if slug is not None:
+            dashboard_query = db.session.query(Dashboard).filter(
+                Dashboard.slug == slug, Dashboard.id != dashboard_id
+            )
+            return not db.session.query(dashboard_query.exists()).scalar()
+        return True
 
     @staticmethod
     def bulk_delete(models: List[Dashboard], commit=True):
diff --git a/tests/dashboards/api_tests.py b/tests/dashboards/api_tests.py
index e00adcb..45b588f 100644
--- a/tests/dashboards/api_tests.py
+++ b/tests/dashboards/api_tests.py
@@ -50,7 +50,7 @@ class DashboardApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
     def insert_dashboard(
         self,
         dashboard_title: str,
-        slug: str,
+        slug: Optional[str],
         owners: List[int],
         slices: Optional[List[Slice]] = None,
         position_json: str = "",
@@ -647,6 +647,19 @@ class DashboardApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(dashboard2)
         db.session.commit()
 
+        dashboard1 = self.insert_dashboard("title1", None, [admin_id])
+        dashboard2 = self.insert_dashboard("title2", None, [admin_id])
+        self.login(username="admin")
+        # Accept empty slugs and don't validate them has unique
+        dashboard_data = {"dashboard_title": "title2_changed", "slug": ""}
+        uri = f"api/v1/dashboard/{dashboard2.id}"
+        rv = self.client.put(uri, json=dashboard_data)
+        self.assertEqual(rv.status_code, 200)
+
+        db.session.delete(dashboard1)
+        db.session.delete(dashboard2)
+        db.session.commit()
+
     def test_update_published(self):
         """
             Dashboard API: Test update published patch