From 3af26aa30e82bbb6d5c9988fc7d23e1fcc9fe74b Mon Sep 17 00:00:00 2001 From: Sage Abdullah Date: Thu, 16 Nov 2023 10:12:20 +0000 Subject: [PATCH] Restore the ability to have content type facets when searching pages with an empty query (#11243) --- CHANGELOG.txt | 1 + docs/releases/5.2.1.md | 1 + wagtail/admin/tests/pages/test_page_search.py | 78 ++++++++++++++++++- wagtail/admin/views/pages/search.py | 25 +++--- 4 files changed, 91 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f8046a3eed..514120ea4b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -52,6 +52,7 @@ Changelog * Fix: Fix performance regression on reports from calling `decorate_paginated_queryset` before pagination / filtering (Alex Tomkins) * Fix: Make searching on specific fields work correctly on Elasticsearch when boost is in use (Matt Westcott) * Fix: Prevent snippet permission post-migrate hook from failing on multiple database configurations (Joe Tsoi) + * Fix: Reinstate ability to filter on page type when searching on an empty query (Sage Abdullah) * Docs: Fix code example for `{% picture ... as ... %}` template tag (Rezyapkin) diff --git a/docs/releases/5.2.1.md b/docs/releases/5.2.1.md index 37ab9ee60a..f54fc79043 100644 --- a/docs/releases/5.2.1.md +++ b/docs/releases/5.2.1.md @@ -25,6 +25,7 @@ depth: 1 * Fix performance regression on reports from calling `decorate_paginated_queryset` before pagination / filtering (Alex Tomkins) * Make searching on specific fields work correctly on Elasticsearch when boost is in use (Matt Westcott) * Prevent snippet permission post-migrate hook from failing on multiple database configurations (Joe Tsoi) + * Reinstate ability to filter on page type when searching on an empty query (Sage Abdullah) ### Documentation diff --git a/wagtail/admin/tests/pages/test_page_search.py b/wagtail/admin/tests/pages/test_page_search.py index 725b457c11..d30b83e7a2 100644 --- a/wagtail/admin/tests/pages/test_page_search.py +++ b/wagtail/admin/tests/pages/test_page_search.py @@ -6,7 +6,7 @@ from django.test import TransactionTestCase from django.urls import reverse from wagtail.models import Page -from wagtail.test.testapp.models import SimplePage, SingleEventPage +from wagtail.test.testapp.models import EventIndex, SimplePage, SingleEventPage from wagtail.test.utils import WagtailTestUtils from wagtail.test.utils.timestamps import local_datetime @@ -212,3 +212,79 @@ class TestPageSearch(WagtailTestUtils, TransactionTestCase): # Incorrect content_type response = self.get({"content_type": "demosite.standardpage.error"}) self.assertEqual(response.status_code, 404) + + def test_empty_search_renders_content_type_facets(self): + root_page = Page.objects.get(id=2) + event_index = EventIndex( + title="ALL THE EVENTS", + intro="It's just a nod to the canon", + ) + root_page.add_child(instance=event_index) + + params = [{"q": ""}, {}] + url = reverse("wagtailadmin_pages:search") + for param in params: + with self.subTest(param=param): + response = self.get(param) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "wagtailadmin/pages/search.html") + self.assertEqual(response.context["query_string"], "") + + self.assertContains(response, "Page types") + self.assertContains(response, "All (3)") + # The test fixture contains the root page and the welcome page + # with the base page type + self.assertContains(response, "Page (2)") + + self.assertContains(response, "ALL THE EVENTS") + + self.assertContains(response, "Event index (1)") + self.assertContains( + response, + f"{url}?q=&content_type=tests.eventindex", + ) + + def test_empty_search_with_content_type_filter(self): + root_page = Page.objects.get(id=2) + event_index = EventIndex( + title="ALL THE EVENTS", + intro="It's just a nod to the canon", + ) + new_event = SingleEventPage( + title="Lunar event", + location="the moon", + audience="public", + cost="free", + date_from="2001-01-01", + latest_revision_created_at=local_datetime(2016, 1, 1), + ) + root_page.add_child(instance=event_index) + root_page.add_child(instance=new_event) + + params = [ + {"q": "", "content_type": "tests.singleeventpage"}, + {"content_type": "tests.singleeventpage"}, + ] + url = reverse("wagtailadmin_pages:search") + for param in params: + with self.subTest(param=param): + response = self.get(param) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "wagtailadmin/pages/search.html") + self.assertEqual(response.context["query_string"], "") + + self.assertContains(response, "Page types") + self.assertContains(response, "All (4)") + # The test fixture contains the root page and the welcome page + # with the base page type + self.assertContains(response, "Page (2)") + self.assertContains(response, "Single event page (1)") + + self.assertContains(response, "Lunar event") + self.assertNotContains(response, "ALL THE EVENTS") + + self.assertContains(response, "Event index (1)") + self.assertContains( + response, + f"{url}?q=&content_type=tests.eventindex", + ) diff --git a/wagtail/admin/views/pages/search.py b/wagtail/admin/views/pages/search.py index 2f8fd886e7..5322d999bc 100644 --- a/wagtail/admin/views/pages/search.py +++ b/wagtail/admin/views/pages/search.py @@ -143,20 +143,19 @@ class BaseSearchView(PermissionCheckedMixin, BaseListingView): if self.selected_content_type: pages = pages.filter(content_type=self.selected_content_type) - if self.q: - # Parse query and filter - pages, self.all_pages = page_filter_search( - self.q, pages, self.all_pages, self.ordering - ) + # Parse query and filter + pages, self.all_pages = page_filter_search( + self.q, pages, self.all_pages, self.ordering + ) - # Facets - if pages.supports_facet: - self.content_types = [ - (ContentType.objects.get(id=content_type_id), count) - for content_type_id, count in self.all_pages.facet( - "content_type_id" - ).items() - ] + # Facets + if pages.supports_facet: + self.content_types = [ + (ContentType.objects.get(id=content_type_id), count) + for content_type_id, count in self.all_pages.facet( + "content_type_id" + ).items() + ] return pages