feat: filter with created_by for charts and dashboards (#21199)

* feat: filter with created_by for charts and dashboards

* add tests

* update tests

* update tests
This commit is contained in:
Lily Kuang 2022-08-30 12:27:38 -07:00 committed by GitHub
parent 1aa1864d13
commit 05354a96bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 102 additions and 2 deletions

View File

@ -114,4 +114,6 @@ export enum FilterOperator {
chartIsCertified = 'chart_is_certified',
dashboardIsCertified = 'dashboard_is_certified',
datasetIsCertified = 'dataset_is_certified',
dashboardHasCreatedBy = 'dashboard_has_created_by',
chartHasCreatedBy = 'chart_has_created_by',
}

View File

@ -52,6 +52,7 @@ from superset.charts.filters import (
ChartCertifiedFilter,
ChartFavoriteFilter,
ChartFilter,
ChartHasCreatedByFilter,
)
from superset.charts.schemas import (
CHART_SCHEMAS,
@ -205,6 +206,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
search_filters = {
"id": [ChartFavoriteFilter, ChartCertifiedFilter],
"slice_name": [ChartAllTextFilter],
"created_by": [ChartHasCreatedByFilter],
}
# Will just affect _info endpoint

View File

@ -93,3 +93,19 @@ class ChartFilter(BaseFilter): # pylint: disable=too-few-public-methods
models.SqlaTable.id.in_(owner_ids_query),
)
)
class ChartHasCreatedByFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
Custom filter for the GET list that filters all charts created by user
"""
name = _("Has created by")
arg_name = "chart_has_created_by"
def apply(self, query: Query, value: Any) -> Query:
if value is True:
return query.filter(and_(Slice.created_by_fk.isnot(None)))
if value is False:
return query.filter(and_(Slice.created_by_fk.is_(None)))
return query

View File

@ -60,6 +60,7 @@ from superset.dashboards.filters import (
DashboardCertifiedFilter,
DashboardCreatedByMeFilter,
DashboardFavoriteFilter,
DashboardHasCreatedByFilter,
DashboardTitleOrSlugFilter,
FilterRelatedRoles,
)
@ -218,7 +219,7 @@ class DashboardRestApi(BaseSupersetModelRestApi):
search_filters = {
"dashboard_title": [DashboardTitleOrSlugFilter],
"id": [DashboardFavoriteFilter, DashboardCertifiedFilter],
"created_by": [DashboardCreatedByMeFilter],
"created_by": [DashboardCreatedByMeFilter, DashboardHasCreatedByFilter],
}
base_order = ("changed_on", "desc")

View File

@ -156,7 +156,6 @@ class DashboardAccessFilter(BaseFilter): # pylint: disable=too-few-public-metho
if is_feature_enabled("EMBEDDED_SUPERSET") and security_manager.is_guest_user(
g.user
):
guest_user: GuestUser = g.user
embedded_dashboard_ids = [
r["id"]
@ -233,3 +232,19 @@ class DashboardCertifiedFilter(BaseFilter): # pylint: disable=too-few-public-me
)
)
return query
class DashboardHasCreatedByFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
Custom filter for the GET list that filters all dashboards created by user
"""
name = _("Has created by")
arg_name = "dashboard_has_created_by"
def apply(self, query: Query, value: Any) -> Query:
if value is True:
return query.filter(and_(Dashboard.created_by_fk.isnot(None)))
if value is False:
return query.filter(and_(Dashboard.created_by_fk.is_(None)))
return query

View File

@ -1357,3 +1357,31 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin, InsertChartMixin):
}
]
}
def test_gets_created_by_user_charts_filter(self):
arguments = {
"filters": [{"col": "id", "opr": "chart_has_created_by", "value": True}],
"keys": ["none"],
"columns": ["slice_name"],
}
self.login(username="admin")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 8)
def test_gets_not_created_by_user_charts_filter(self):
arguments = {
"filters": [{"col": "id", "opr": "chart_has_created_by", "value": False}],
"keys": ["none"],
"columns": ["slice_name"],
}
self.login(username="admin")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 8)

View File

@ -1836,3 +1836,39 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin, InsertChartMixi
# get returns 404
resp = self.get_assert_metric(uri, "get_embedded")
self.assertEqual(resp.status_code, 404)
@pytest.mark.usefixtures("create_created_by_admin_dashboards")
def test_gets_created_by_user_dashboards_filter(self):
arguments = {
"filters": [
{"col": "id", "opr": "dashboard_has_created_by", "value": True}
],
"keys": ["none"],
"columns": ["dashboard_title"],
}
self.login(username="admin")
uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 7)
def test_gets_not_created_by_user_dashboards_filter(self):
arguments = {
"filters": [
{"col": "id", "opr": "dashboard_has_created_by", "value": False}
],
"keys": ["none"],
"columns": ["dashboard_title"],
}
dashboard = self.insert_dashboard(f"title", f"slug", [])
self.login(username="admin")
uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 6)
db.session.delete(dashboard)
db.session.commit()