summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorsarahboyce <sarahvboyce95@gmail.com>2023-03-06 15:24:39 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-03-16 08:38:44 +0100
commitd2b688b966f5d30414899549412d370e1317ddb8 (patch)
tree04be2a73653c70c27d9a0bf1baeaa99b86ef8107 /tests
parentd03dc63177ad3ba6e685e314eed45d6a8ec5cb0c (diff)
Fixed #1873 -- Handled multi-valued query parameters in admin changelist filters.
Diffstat (limited to 'tests')
-rw-r--r--tests/admin_changelist/test_date_hierarchy.py4
-rw-r--r--tests/admin_filters/tests.py94
-rw-r--r--tests/admin_utils/tests.py15
3 files changed, 111 insertions, 2 deletions
diff --git a/tests/admin_changelist/test_date_hierarchy.py b/tests/admin_changelist/test_date_hierarchy.py
index a8c10f7cd8..03afaa33d9 100644
--- a/tests/admin_changelist/test_date_hierarchy.py
+++ b/tests/admin_changelist/test_date_hierarchy.py
@@ -25,8 +25,8 @@ class DateHierarchyTests(TestCase):
request.user = self.superuser
changelist = EventAdmin(Event, custom_site).get_changelist_instance(request)
_, _, lookup_params, *_ = changelist.get_filters(request)
- self.assertEqual(lookup_params["date__gte"], expected_from_date)
- self.assertEqual(lookup_params["date__lt"], expected_to_date)
+ self.assertEqual(lookup_params["date__gte"], [expected_from_date])
+ self.assertEqual(lookup_params["date__lt"], [expected_to_date])
def test_bounded_params(self):
tests = (
diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py
index cd71ed8a9f..a3af966005 100644
--- a/tests/admin_filters/tests.py
+++ b/tests/admin_filters/tests.py
@@ -1533,6 +1533,100 @@ class ListFiltersTests(TestCase):
expected_displays,
)
+ def test_multi_related_field_filter(self):
+ modeladmin = DecadeFilterBookAdmin(Book, site)
+ request = self.request_factory.get(
+ "/",
+ [("author__id__exact", self.alfred.pk), ("author__id__exact", self.bob.pk)],
+ )
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ queryset = changelist.get_queryset(request)
+ self.assertSequenceEqual(
+ queryset,
+ list(
+ Book.objects.filter(
+ author__pk__in=[self.alfred.pk, self.bob.pk]
+ ).order_by("-id")
+ ),
+ )
+ filterspec = changelist.get_filters(request)[0][0]
+ choices = list(filterspec.choices(changelist))
+ expected_choice_values = [
+ ("All", False, "?"),
+ ("alfred", True, f"?author__id__exact={self.alfred.pk}"),
+ ("bob", True, f"?author__id__exact={self.bob.pk}"),
+ ("lisa", False, f"?author__id__exact={self.lisa.pk}"),
+ ]
+ for i, (display, selected, query_string) in enumerate(expected_choice_values):
+ self.assertEqual(choices[i]["display"], display)
+ self.assertIs(choices[i]["selected"], selected)
+ self.assertEqual(choices[i]["query_string"], query_string)
+
+ def test_multi_choice_field_filter(self):
+ modeladmin = DecadeFilterBookAdmin(Book, site)
+ request = self.request_factory.get(
+ "/",
+ [("category__exact", "non-fiction"), ("category__exact", "fiction")],
+ )
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ queryset = changelist.get_queryset(request)
+ self.assertSequenceEqual(
+ queryset,
+ list(
+ Book.objects.filter(category__in=["non-fiction", "fiction"]).order_by(
+ "-id"
+ )
+ ),
+ )
+ filterspec = changelist.get_filters(request)[0][3]
+ choices = list(filterspec.choices(changelist))
+ expected_choice_values = [
+ ("All", False, "?"),
+ ("Non-Fictional", True, "?category__exact=non-fiction"),
+ ("Fictional", True, "?category__exact=fiction"),
+ ("We don't know", False, "?category__exact="),
+ ("Not categorized", False, "?category__isnull=True"),
+ ]
+ for i, (display, selected, query_string) in enumerate(expected_choice_values):
+ self.assertEqual(choices[i]["display"], display)
+ self.assertIs(choices[i]["selected"], selected)
+ self.assertEqual(choices[i]["query_string"], query_string)
+
+ def test_multi_all_values_field_filter(self):
+ modeladmin = DecadeFilterBookAdmin(Book, site)
+ request = self.request_factory.get(
+ "/",
+ [
+ ("author__email", "bob@example.com"),
+ ("author__email", "lisa@example.com"),
+ ],
+ )
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ queryset = changelist.get_queryset(request)
+ self.assertSequenceEqual(
+ queryset,
+ list(
+ Book.objects.filter(
+ author__email__in=["bob@example.com", "lisa@example.com"]
+ ).order_by("-id")
+ ),
+ )
+ filterspec = changelist.get_filters(request)[0][5]
+ choices = list(filterspec.choices(changelist))
+ expected_choice_values = [
+ ("All", False, "?"),
+ ("alfred@example.com", False, "?author__email=alfred%40example.com"),
+ ("bob@example.com", True, "?author__email=bob%40example.com"),
+ ("lisa@example.com", True, "?author__email=lisa%40example.com"),
+ ]
+ for i, (display, selected, query_string) in enumerate(expected_choice_values):
+ self.assertEqual(choices[i]["display"], display)
+ self.assertIs(choices[i]["selected"], selected)
+ self.assertEqual(choices[i]["query_string"], query_string)
+
def test_two_characters_long_field(self):
"""
list_filter works with two-characters long field names (#16080).
diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py
index 113f5f7024..cbe6b8bb1d 100644
--- a/tests/admin_utils/tests.py
+++ b/tests/admin_utils/tests.py
@@ -7,6 +7,7 @@ from django.contrib import admin
from django.contrib.admin import helpers
from django.contrib.admin.utils import (
NestedObjects,
+ build_q_object_from_lookup_parameters,
display_for_field,
display_for_value,
flatten,
@@ -424,3 +425,17 @@ class UtilsTests(SimpleTestCase):
def test_quote(self):
self.assertEqual(quote("something\nor\nother"), "something_0Aor_0Aother")
+
+ def test_build_q_object_from_lookup_parameters(self):
+ parameters = {
+ "title__in": [["Article 1", "Article 2"]],
+ "hist__iexact": ["history"],
+ "site__pk": [1, 2],
+ }
+ q_obj = build_q_object_from_lookup_parameters(parameters)
+ self.assertEqual(
+ q_obj,
+ models.Q(title__in=["Article 1", "Article 2"])
+ & models.Q(hist__iexact="history")
+ & (models.Q(site__pk=1) | models.Q(site__pk=2)),
+ )