Skip to content

Commit

Permalink
[charts] New, custom filter for name OR description (#9492)
Browse files Browse the repository at this point in the history
* [charts] New, custom filter for name OR description

* Improve test
  • Loading branch information
dpgaspar authored Apr 11, 2020
1 parent 11ac8c7 commit 622561f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
3 changes: 2 additions & 1 deletion superset/charts/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
ChartUpdateFailedError,
)
from superset.charts.commands.update import UpdateChartCommand
from superset.charts.filters import ChartFilter
from superset.charts.filters import ChartFilter, ChartNameOrDescriptionFilter
from superset.charts.schemas import (
ChartPostSchema,
ChartPutSchema,
Expand Down Expand Up @@ -111,6 +111,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
)
base_order = ("changed_on", "desc")
base_filters = [["id", ChartFilter, lambda: []]]
search_filters = {"slice_name": [ChartNameOrDescriptionFilter]}

# Will just affect _info endpoint
edit_columns = ["slice_name"]
Expand Down
20 changes: 20 additions & 0 deletions superset/charts/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,33 @@
# under the License.
from typing import Any

from flask_babel import lazy_gettext as _
from sqlalchemy import or_
from sqlalchemy.orm.query import Query

from superset import security_manager
from superset.models.slice import Slice
from superset.views.base import BaseFilter


class ChartNameOrDescriptionFilter(
BaseFilter
): # pylint: disable=too-few-public-methods
name = _("Name or Description")
arg_name = "name_or_description"

def apply(self, query: Query, value: Any) -> Query:
if not value:
return query
ilike_value = f"%{value}%"
return query.filter(
or_(
Slice.slice_name.ilike(ilike_value),
Slice.description.ilike(ilike_value),
)
)


class ChartFilter(BaseFilter): # pylint: disable=too-few-public-methods
def apply(self, query: Query, value: Any) -> Query:
if security_manager.all_datasource_access():
Expand Down
50 changes: 50 additions & 0 deletions tests/charts/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,56 @@ def test_get_charts_filter(self):
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 5)

def test_get_charts_custom_filter(self):
"""
Chart API: Test get charts custom filter
"""
admin = self.get_user("admin")
chart1 = self.insert_chart("foo", [admin.id], 1, description="ZY_bar")
chart2 = self.insert_chart("zy_foo", [admin.id], 1, description="desc1")
chart3 = self.insert_chart("foo", [admin.id], 1, description="desc1zy_")
chart4 = self.insert_chart("bar", [admin.id], 1, description="foo")

arguments = {
"filters": [
{"col": "slice_name", "opr": "name_or_description", "value": "zy_"}
],
"order_column": "slice_name",
"order_direction": "asc",
}
self.login(username="admin")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 3)

expected_response = [
{"description": "ZY_bar", "slice_name": "foo",},
{"description": "desc1zy_", "slice_name": "foo",},
{"description": "desc1", "slice_name": "zy_foo",},
]
for index, item in enumerate(data["result"]):
self.assertEqual(
item["description"], expected_response[index]["description"]
)
self.assertEqual(item["slice_name"], expected_response[index]["slice_name"])

self.logout()
self.login(username="gamma")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 0)

# rollback changes
db.session.delete(chart1)
db.session.delete(chart2)
db.session.delete(chart3)
db.session.delete(chart4)
db.session.commit()

def test_get_charts_page(self):
"""
Chart API: Test get charts filter
Expand Down

0 comments on commit 622561f

Please sign in to comment.