Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions openwisp_utils/admin_theme/dashboard.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
import html
from urllib.parse import quote

from django.core.exceptions import ImproperlyConfigured
from django.db.models import Count
Expand Down Expand Up @@ -209,10 +210,8 @@ def get_dashboard_context(request):
label = qs_key
# get human readable label if predefined labels are available
# otherwise use the result got from the DB
filters.append(quote(label, safe=""))
if labels_i18n and qs_key in labels_i18n:
# store original label as filter, but only
# if we have more than the empty default label defined
filters.append(label)
label = labels_i18n[qs_key]
else:
# HTML escape labels coming from values in the DB
Expand Down
27 changes: 27 additions & 0 deletions tests/test_project/tests/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,30 @@ def test_get_dashboard_context_html_escape(self):
context["dashboard_charts"][1]["query_params"]["labels"][0],
"<strong>Projects with operators</strong>",
)

def test_filter_not_double_encoded(self):
project = Project.objects.create(name="Dongwon T&I")
Operator.objects.create(project=project, first_name="test", last_name="test")
mocked_user = MockUser(is_superuser=True)
mocked_request = MockRequest(user=mocked_user)
context = get_dashboard_context(mocked_request)
target_chart = None
for chart in context["dashboard_charts"].values():
if chart.get("name") == "Operator Project Distribution":
target_chart = chart
break
self.assertIsNotNone(target_chart)
filters = target_chart.get("filters", [])
labels = target_chart.get("query_params", {}).get("labels", [])
self.assertIn("Dongwon%20T%26I", filters)
self.assertNotIn("Dongwon T&I", filters)
self.assertIn("Dongwon T&I", labels)
filter_index = None
for i, label in enumerate(labels):
if "Dongwon" in label:
filter_index = i
break
self.assertIsNotNone(filter_index)
final_url = target_chart["target_link"] + filters[filter_index]
self.assertNotIn("&I", final_url.split("=", 1)[-1])
self.assertIn("%26", final_url)
Loading