wagtail 6.3.1__py3-none-any.whl → 6.4rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtail/__init__.py +1 -1
- wagtail/actions/publish_revision.py +4 -5
- wagtail/admin/auth.py +0 -2
- wagtail/admin/checks.py +1 -1
- wagtail/admin/filters.py +3 -1
- wagtail/admin/forms/account.py +21 -11
- wagtail/admin/forms/collections.py +2 -9
- wagtail/admin/forms/formsets.py +32 -0
- wagtail/admin/forms/pages.py +5 -1
- wagtail/admin/forms/workflows.py +2 -13
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +68 -1
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.po +5 -1
- wagtail/admin/locale/en/LC_MESSAGES/django.po +312 -356
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -16
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +5 -5
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +29 -0
- wagtail/admin/menu.py +0 -13
- wagtail/admin/panels/base.py +2 -2
- wagtail/admin/panels/group.py +4 -1
- wagtail/admin/panels/inline_panel.py +5 -2
- wagtail/admin/panels/model_utils.py +36 -0
- wagtail/admin/panels/page_utils.py +2 -40
- wagtail/admin/panels/signal_handlers.py +0 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/streamfield.css +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -8
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +7 -0
- wagtail/admin/templates/wagtailadmin/404.html +4 -0
- wagtail/admin/templates/wagtailadmin/chooser/browse.html +2 -1
- wagtail/admin/templates/wagtailadmin/chooser/tables/parent_page_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/collections/_privacy_switch.html +8 -1
- wagtail/admin/templates/wagtailadmin/generic/confirm_delete.html +15 -9
- wagtail/admin/templates/wagtailadmin/generic/confirm_unpublish.html +21 -25
- wagtail/admin/templates/wagtailadmin/generic/form.html +1 -1
- wagtail/admin/templates/wagtailadmin/generic/preview_error.html +3 -0
- wagtail/admin/templates/wagtailadmin/generic/revisions/compare.html +63 -76
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -2
- wagtail/admin/templates/wagtailadmin/pages/edit.html +1 -5
- wagtail/admin/templates/wagtailadmin/panels/inline_panel_child.html +1 -0
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +6 -22
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/header.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +32 -39
- wagtail/admin/templates/wagtailadmin/shared/revisions/confirm_unschedule.html +13 -17
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +15 -3
- wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +4 -2
- wagtail/admin/templates/wagtailadmin/workflows/create.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_formset.html +6 -23
- wagtail/admin/templatetags/wagtailadmin_tags.py +12 -0
- wagtail/admin/templatetags/wagtailuserbar.py +2 -3
- wagtail/admin/tests/pages/test_create_page.py +110 -1
- wagtail/admin/tests/pages/test_edit_page.py +3 -2
- wagtail/admin/tests/pages/test_explorer_view.py +18 -0
- wagtail/admin/tests/pages/test_page_usage.py +24 -20
- wagtail/admin/tests/pages/test_preview.py +69 -1
- wagtail/admin/tests/pages/test_revisions.py +40 -6
- wagtail/admin/tests/test_account_management.py +39 -1
- wagtail/admin/tests/test_audit_log.py +4 -2
- wagtail/admin/tests/test_block_preview.py +224 -0
- wagtail/admin/tests/test_edit_handlers.py +23 -6
- wagtail/admin/tests/test_page_chooser.py +50 -3
- wagtail/admin/tests/test_privacy.py +49 -26
- wagtail/admin/tests/test_site_summary.py +15 -10
- wagtail/admin/tests/test_templatetags.py +19 -0
- wagtail/admin/tests/test_userbar.py +82 -1
- wagtail/admin/tests/test_views_generic.py +27 -12
- wagtail/admin/tests/test_workflows.py +69 -0
- wagtail/admin/tests/tests.py +23 -4
- wagtail/admin/tests/ui/test_sidebar.py +1 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +15 -13
- wagtail/admin/ui/side_panels.py +7 -4
- wagtail/admin/urls/__init__.py +6 -0
- wagtail/admin/urls/pages.py +1 -1
- wagtail/admin/userbar.py +21 -1
- wagtail/admin/views/account.py +5 -0
- wagtail/admin/views/chooser.py +5 -1
- wagtail/admin/views/collections.py +0 -2
- wagtail/admin/views/generic/base.py +20 -10
- wagtail/admin/views/generic/history.py +0 -1
- wagtail/admin/views/generic/models.py +79 -21
- wagtail/admin/views/generic/preview.py +50 -1
- wagtail/admin/views/mixins.py +4 -2
- wagtail/admin/views/pages/bulk_actions/delete.py +11 -23
- wagtail/admin/views/pages/bulk_actions/page_bulk_action.py +17 -0
- wagtail/admin/views/pages/bulk_actions/publish.py +11 -31
- wagtail/admin/views/pages/bulk_actions/unpublish.py +11 -31
- wagtail/admin/views/pages/create.py +1 -0
- wagtail/admin/views/pages/edit.py +38 -30
- wagtail/admin/views/pages/revisions.py +43 -114
- wagtail/admin/views/pages/utils.py +0 -1
- wagtail/admin/views/tags.py +6 -2
- wagtail/admin/views/workflows.py +8 -6
- wagtail/admin/viewsets/model.py +0 -4
- wagtail/admin/viewsets/pages.py +0 -1
- wagtail/admin/widgets/tags.py +1 -0
- wagtail/api/v2/tests/test_documents.py +4 -2
- wagtail/api/v2/tests/test_images.py +4 -2
- wagtail/api/v2/tests/test_pages.py +8 -4
- wagtail/blocks/base.py +59 -1
- wagtail/blocks/field_block.py +6 -0
- wagtail/blocks/list_block.py +4 -0
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +5 -1
- wagtail/blocks/struct_block.py +6 -0
- wagtail/compat.py +16 -0
- wagtail/contrib/forms/forms.py +27 -7
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/forms/tests/test_models.py +7 -5
- wagtail/contrib/forms/tests/test_views.py +75 -0
- wagtail/contrib/frontend_cache/backends/cloudfront.py +1 -1
- wagtail/contrib/frontend_cache/tasks.py +83 -0
- wagtail/contrib/frontend_cache/tests.py +48 -33
- wagtail/contrib/frontend_cache/utils.py +2 -70
- wagtail/contrib/redirects/base_formats.py +2 -2
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +3 -0
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +24 -37
- wagtail/contrib/redirects/templates/wagtailredirects/add.html +1 -24
- wagtail/contrib/redirects/templates/wagtailredirects/confirm_delete.html +3 -13
- wagtail/contrib/redirects/tests/test_redirects.py +122 -110
- wagtail/contrib/redirects/tests/test_signal_handlers.py +75 -69
- wagtail/contrib/redirects/urls.py +2 -2
- wagtail/contrib/redirects/views.py +35 -73
- wagtail/contrib/search_promotions/admin_urls.py +10 -3
- wagtail/contrib/search_promotions/forms.py +55 -26
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +44 -54
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +21 -31
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/confirm_delete.html +3 -12
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +11 -34
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotion_form.html +1 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js +2 -1
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +0 -1
- wagtail/contrib/search_promotions/tests.py +814 -13
- wagtail/contrib/search_promotions/views/__init__.py +1 -0
- wagtail/contrib/search_promotions/views/reports.py +56 -0
- wagtail/contrib/search_promotions/views/settings.py +258 -0
- wagtail/contrib/search_promotions/wagtail_hooks.py +12 -1
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/templates/wagtailsettings/edit.html +1 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +2 -5
- wagtail/contrib/settings/tests/generic/test_register.py +1 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +2 -5
- wagtail/contrib/settings/tests/site_specific/test_register.py +1 -1
- wagtail/contrib/settings/views.py +9 -23
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/tests.py +4 -1
- wagtail/contrib/typed_table_block/blocks.py +3 -0
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/contrib/typed_table_block/tests.py +33 -0
- wagtail/documents/locale/en/LC_MESSAGES/django.po +26 -26
- wagtail/documents/migrations/0011_add_choose_permissions.py +1 -0
- wagtail/documents/models.py +1 -0
- wagtail/documents/signal_handlers.py +6 -2
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/edit.html +1 -3
- wagtail/documents/templates/wagtaildocs/multiple/add.html +7 -1
- wagtail/documents/tests/test_admin_views.py +74 -33
- wagtail/documents/tests/test_views.py +21 -12
- wagtail/documents/views/chooser.py +1 -0
- wagtail/documents/views/documents.py +1 -2
- wagtail/documents/views/multiple.py +0 -1
- wagtail/documents/views/serve.py +9 -2
- wagtail/documents/wagtail_hooks.py +6 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/oembed_providers.py +0 -64
- wagtail/fields.py +3 -0
- wagtail/images/apps.py +2 -1
- wagtail/images/blocks.py +14 -2
- wagtail/images/forms.py +40 -3
- wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ar/LC_MESSAGES/django.po +4 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +49 -49
- wagtail/images/migrations/0023_add_choose_permissions.py +1 -0
- wagtail/images/rich_text/contentstate.py +1 -0
- wagtail/images/rich_text/editor_html.py +1 -0
- wagtail/images/signal_handlers.py +17 -10
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
- wagtail/images/tasks.py +18 -0
- wagtail/images/templates/wagtailimages/images/edit.html +1 -3
- wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
- wagtail/images/templates/wagtailimages/multiple/add.html +7 -2
- wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
- wagtail/images/tests/test_admin_views.py +53 -29
- wagtail/images/tests/test_blocks.py +34 -2
- wagtail/images/tests/test_models.py +12 -10
- wagtail/images/tests/tests.py +10 -0
- wagtail/images/views/chooser.py +1 -0
- wagtail/images/views/images.py +1 -3
- wagtail/images/views/multiple.py +0 -1
- wagtail/images/views/serve.py +18 -2
- wagtail/images/widgets.py +3 -0
- wagtail/locale/en/LC_MESSAGES/django.po +228 -216
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/management/commands/publish_scheduled.py +1 -1
- wagtail/migrations/0087_alter_grouppagepermission_unique_together_and_more.py +16 -8
- wagtail/models/__init__.py +300 -119
- wagtail/models/i18n.py +2 -2
- wagtail/models/panels.py +37 -0
- wagtail/models/sites.py +7 -6
- wagtail/permission_policies/pages.py +2 -2
- wagtail/project_template/project_name/settings/base.py +4 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +145 -0
- wagtail/search/backends/database/mysql/mysql.py +25 -17
- wagtail/search/backends/database/postgres/postgres.py +44 -83
- wagtail/search/backends/database/sqlite/sqlite.py +25 -17
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/search/query.py +8 -2
- wagtail/search/signal_handlers.py +6 -9
- wagtail/search/tasks.py +10 -0
- wagtail/search/tests/test_elasticsearch7_backend.py +21 -0
- wagtail/search/tests/test_index_functions.py +10 -6
- wagtail/search/tests/test_postgres_backend.py +0 -14
- wagtail/signal_handlers.py +5 -20
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -13
- wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/sv/LC_MESSAGES/django.po +4 -3
- wagtail/snippets/tests/test_preview.py +5 -0
- wagtail/snippets/tests/test_snippets.py +100 -45
- wagtail/snippets/tests/test_usage.py +29 -24
- wagtail/snippets/tests/test_viewset.py +1 -1
- wagtail/snippets/views/snippets.py +0 -12
- wagtail/tasks.py +41 -0
- wagtail/templates/wagtailcore/shared/block_preview.html +29 -0
- wagtail/test/earlypage/__init__.py +0 -0
- wagtail/test/earlypage/migrations/0001_initial.py +37 -0
- wagtail/test/earlypage/migrations/__init__.py +0 -0
- wagtail/test/earlypage/models.py +14 -0
- wagtail/test/settings.py +3 -0
- wagtail/test/testapp/fixtures/test.json +7 -0
- wagtail/test/testapp/fixtures/test_specific.json +6 -3
- wagtail/test/testapp/models.py +58 -44
- wagtail/test/testapp/templates/tests/custom_block_preview.html +16 -0
- wagtail/test/testapp/templates/tests/static_block_preview.html +5 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/tests/test_blocks.py +189 -2
- wagtail/tests/test_hooks.py +166 -1
- wagtail/tests/test_management_commands.py +54 -13
- wagtail/tests/test_page_allowed_http_methods.py +32 -0
- wagtail/tests/test_page_model.py +68 -0
- wagtail/tests/test_page_privacy.py +10 -0
- wagtail/tests/test_page_queryset.py +79 -0
- wagtail/tests/test_reference_index.py +84 -75
- wagtail/tests/test_streamfield.py +30 -0
- wagtail/tests/test_utils.py +61 -0
- wagtail/users/forms.py +2 -9
- wagtail/users/locale/en/LC_MESSAGES/django.po +17 -17
- wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +4 -3
- wagtail/users/templates/wagtailusers/groups/create.html +0 -5
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_form.html +1 -1
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +6 -6
- wagtail/users/tests/test_admin_views.py +96 -4
- wagtail/users/tests/test_utils.py +76 -0
- wagtail/users/utils.py +43 -11
- wagtail/utils/setup.py +2 -2
- wagtail/utils/templates.py +26 -0
- wagtail/utils/widgets.py +1 -0
- wagtail/views.py +9 -1
- wagtail/wagtail_hooks.py +67 -29
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/RECORD +300 -287
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/rangy-core.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/uuidv4.min.js +0 -1
- wagtail/contrib/search_promotions/views.py +0 -323
- wagtail/images/static/wagtailimages/js/vendor/canvas-to-blob.min.js +0 -1
- wagtail/users/static/wagtailusers/js/group-form.js +0 -1
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from datetime import date, datetime, timedelta
|
|
3
|
-
from io import StringIO
|
|
3
|
+
from io import BytesIO, StringIO
|
|
4
4
|
|
|
5
5
|
from django.contrib.auth.models import Permission
|
|
6
6
|
from django.core import management
|
|
7
7
|
from django.test import TestCase
|
|
8
8
|
from django.urls import reverse
|
|
9
|
+
from django.utils import timezone
|
|
10
|
+
from openpyxl import load_workbook
|
|
9
11
|
|
|
10
12
|
from wagtail.admin.admin_url_finder import AdminURLFinder
|
|
13
|
+
from wagtail.admin.tests.test_reports_views import BaseReportViewTestCase
|
|
11
14
|
from wagtail.contrib.search_promotions.models import (
|
|
12
15
|
Query,
|
|
13
16
|
QueryDailyHits,
|
|
@@ -16,7 +19,9 @@ from wagtail.contrib.search_promotions.models import (
|
|
|
16
19
|
from wagtail.contrib.search_promotions.templatetags.wagtailsearchpromotions_tags import (
|
|
17
20
|
get_search_promotions,
|
|
18
21
|
)
|
|
22
|
+
from wagtail.log_actions import registry as log_registry
|
|
19
23
|
from wagtail.test.utils import WagtailTestUtils
|
|
24
|
+
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
class TestSearchPromotions(TestCase):
|
|
@@ -171,7 +176,7 @@ class TestGetSearchPromotionsTemplateTag(TestCase):
|
|
|
171
176
|
self.assertEqual(search_picks, [])
|
|
172
177
|
|
|
173
178
|
|
|
174
|
-
class TestSearchPromotionsIndexView(WagtailTestUtils, TestCase):
|
|
179
|
+
class TestSearchPromotionsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
175
180
|
def setUp(self):
|
|
176
181
|
self.user = self.login()
|
|
177
182
|
|
|
@@ -179,6 +184,10 @@ class TestSearchPromotionsIndexView(WagtailTestUtils, TestCase):
|
|
|
179
184
|
response = self.client.get(reverse("wagtailsearchpromotions:index"))
|
|
180
185
|
self.assertEqual(response.status_code, 200)
|
|
181
186
|
self.assertTemplateUsed(response, "wagtailsearchpromotions/index.html")
|
|
187
|
+
self.assertBreadcrumbsItemsRendered(
|
|
188
|
+
[{"url": "", "label": "Promoted search results"}],
|
|
189
|
+
response.content,
|
|
190
|
+
)
|
|
182
191
|
|
|
183
192
|
def test_search(self):
|
|
184
193
|
response = self.client.get(
|
|
@@ -459,14 +468,24 @@ class TestSearchPromotionsIndexView(WagtailTestUtils, TestCase):
|
|
|
459
468
|
self.assertIsNone(soup.select_one(f'a[href="{add_url}"]'))
|
|
460
469
|
|
|
461
470
|
|
|
462
|
-
class TestSearchPromotionsAddView(WagtailTestUtils, TestCase):
|
|
471
|
+
class TestSearchPromotionsAddView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
463
472
|
def setUp(self):
|
|
464
|
-
self.login()
|
|
473
|
+
self.user = self.login()
|
|
465
474
|
|
|
466
475
|
def test_simple(self):
|
|
467
476
|
response = self.client.get(reverse("wagtailsearchpromotions:add"))
|
|
468
477
|
self.assertEqual(response.status_code, 200)
|
|
469
478
|
self.assertTemplateUsed(response, "wagtailsearchpromotions/add.html")
|
|
479
|
+
self.assertBreadcrumbsItemsRendered(
|
|
480
|
+
[
|
|
481
|
+
{
|
|
482
|
+
"url": reverse("wagtailsearchpromotions:index"),
|
|
483
|
+
"label": "Promoted search results",
|
|
484
|
+
},
|
|
485
|
+
{"url": "", "label": "New: Promoted search result"},
|
|
486
|
+
],
|
|
487
|
+
response.content,
|
|
488
|
+
)
|
|
470
489
|
|
|
471
490
|
def test_post(self):
|
|
472
491
|
# Submit
|
|
@@ -488,6 +507,160 @@ class TestSearchPromotionsAddView(WagtailTestUtils, TestCase):
|
|
|
488
507
|
# Check that the search pick was created
|
|
489
508
|
self.assertTrue(Query.get("test").editors_picks.filter(page_id=1).exists())
|
|
490
509
|
|
|
510
|
+
# Ensure that only one log entry was created for the search pick
|
|
511
|
+
search_picks = list(Query.get("test").editors_picks.all())
|
|
512
|
+
self.assertEqual(len(search_picks), 1)
|
|
513
|
+
self.assertTrue(search_picks[0].page_id, 1)
|
|
514
|
+
logs = log_registry.get_logs_for_instance(search_picks[0])
|
|
515
|
+
self.assertEqual(len(logs), 1)
|
|
516
|
+
self.assertEqual(logs[0].action, "wagtail.create")
|
|
517
|
+
|
|
518
|
+
def test_with_multiple_picks(self):
|
|
519
|
+
# Submit
|
|
520
|
+
post_data = {
|
|
521
|
+
"query_string": "test",
|
|
522
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
523
|
+
"editors_picks-INITIAL_FORMS": 0,
|
|
524
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
525
|
+
"editors_picks-0-DELETE": "",
|
|
526
|
+
"editors_picks-0-ORDER": 0,
|
|
527
|
+
"editors_picks-0-page": 1,
|
|
528
|
+
"editors_picks-0-description": "Hello",
|
|
529
|
+
"editors_picks-1-DELETE": "",
|
|
530
|
+
"editors_picks-1-ORDER": 1,
|
|
531
|
+
"editors_picks-1-page": "",
|
|
532
|
+
"editors_picks-1-external_link_url": "https://wagtail.org",
|
|
533
|
+
"editors_picks-1-external_link_text": "Wagtail",
|
|
534
|
+
"editors_picks-1-description": "The landing page",
|
|
535
|
+
}
|
|
536
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
537
|
+
|
|
538
|
+
# User should be redirected back to the index
|
|
539
|
+
self.assertRedirects(response, reverse("wagtailsearchpromotions:index"))
|
|
540
|
+
|
|
541
|
+
# Check that the search pick was created
|
|
542
|
+
search_picks = list(
|
|
543
|
+
Query.get("test").editors_picks.all().order_by("description")
|
|
544
|
+
)
|
|
545
|
+
self.assertEqual(len(search_picks), 2)
|
|
546
|
+
self.assertEqual(search_picks[0].page_id, 1)
|
|
547
|
+
self.assertEqual(search_picks[0].description, "Hello")
|
|
548
|
+
self.assertEqual(search_picks[1].external_link_url, "https://wagtail.org")
|
|
549
|
+
self.assertEqual(search_picks[1].description, "The landing page")
|
|
550
|
+
|
|
551
|
+
# Ensure that only one log entry was created for each search pick
|
|
552
|
+
for search_pick in search_picks:
|
|
553
|
+
logs = log_registry.get_logs_for_instance(search_pick)
|
|
554
|
+
self.assertEqual(len(logs), 1)
|
|
555
|
+
self.assertEqual(logs[0].action, "wagtail.create")
|
|
556
|
+
self.assertEqual(logs[0].user, self.user)
|
|
557
|
+
|
|
558
|
+
def test_post_with_existing_query_string(self):
|
|
559
|
+
# Create an existing query with search picks
|
|
560
|
+
query = Query.get("test")
|
|
561
|
+
search_pick_1 = query.editors_picks.create(
|
|
562
|
+
page_id=1, sort_order=0, description="Root page"
|
|
563
|
+
)
|
|
564
|
+
search_pick_2 = query.editors_picks.create(
|
|
565
|
+
page_id=2, sort_order=1, description="Homepage"
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
# Submit
|
|
569
|
+
post_data = {
|
|
570
|
+
"query_string": "test",
|
|
571
|
+
"editors_picks-TOTAL_FORMS": 1,
|
|
572
|
+
"editors_picks-INITIAL_FORMS": 0,
|
|
573
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
574
|
+
"editors_picks-0-DELETE": "",
|
|
575
|
+
"editors_picks-0-ORDER": 1,
|
|
576
|
+
"editors_picks-0-external_link_url": "https://wagtail.org",
|
|
577
|
+
"editors_picks-0-external_link_text": "Wagtail",
|
|
578
|
+
"editors_picks-0-description": "A Django-based CMS",
|
|
579
|
+
}
|
|
580
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
581
|
+
|
|
582
|
+
# User should be redirected back to the index
|
|
583
|
+
self.assertRedirects(response, reverse("wagtailsearchpromotions:index"))
|
|
584
|
+
|
|
585
|
+
# Check that the submitted search pick is created
|
|
586
|
+
# and the existing ones are still there
|
|
587
|
+
self.assertEqual(
|
|
588
|
+
set(
|
|
589
|
+
Query.get("test")
|
|
590
|
+
.editors_picks.all()
|
|
591
|
+
.values_list("page_id", "external_link_url")
|
|
592
|
+
),
|
|
593
|
+
{
|
|
594
|
+
(search_pick_1.page_id, ""),
|
|
595
|
+
(search_pick_2.page_id, ""),
|
|
596
|
+
(None, "https://wagtail.org"),
|
|
597
|
+
},
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
def test_post_with_invalid_query_string(self):
|
|
601
|
+
# Submit
|
|
602
|
+
post_data = {
|
|
603
|
+
"query_string": "",
|
|
604
|
+
"editors_picks-TOTAL_FORMS": 1,
|
|
605
|
+
"editors_picks-INITIAL_FORMS": 0,
|
|
606
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
607
|
+
"editors_picks-0-DELETE": "",
|
|
608
|
+
"editors_picks-0-ORDER": 0,
|
|
609
|
+
"editors_picks-0-page": 1,
|
|
610
|
+
"editors_picks-0-description": "Hello",
|
|
611
|
+
}
|
|
612
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
613
|
+
|
|
614
|
+
# User should be given an error on the specific field in the form
|
|
615
|
+
self.assertEqual(response.status_code, 200)
|
|
616
|
+
|
|
617
|
+
self.assertFormError(
|
|
618
|
+
response.context["form"], "query_string", "This field is required."
|
|
619
|
+
)
|
|
620
|
+
# The formset should still contain the submitted data
|
|
621
|
+
self.assertEqual(len(response.context["searchpicks_formset"].forms), 1)
|
|
622
|
+
self.assertEqual(
|
|
623
|
+
response.context["searchpicks_formset"].forms[0].cleaned_data["page"].id,
|
|
624
|
+
1,
|
|
625
|
+
)
|
|
626
|
+
self.assertEqual(
|
|
627
|
+
response.context["searchpicks_formset"]
|
|
628
|
+
.forms[0]
|
|
629
|
+
.cleaned_data["description"],
|
|
630
|
+
"Hello",
|
|
631
|
+
)
|
|
632
|
+
# Should not raise an error anywhere else
|
|
633
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, "page", [])
|
|
634
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
635
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
636
|
+
|
|
637
|
+
def test_post_with_invalid_page(self):
|
|
638
|
+
# Submit
|
|
639
|
+
post_data = {
|
|
640
|
+
"query_string": "test",
|
|
641
|
+
"editors_picks-TOTAL_FORMS": 1,
|
|
642
|
+
"editors_picks-INITIAL_FORMS": 0,
|
|
643
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
644
|
+
"editors_picks-0-DELETE": "",
|
|
645
|
+
"editors_picks-0-ORDER": 0,
|
|
646
|
+
"editors_picks-0-page": 9999999999,
|
|
647
|
+
"editors_picks-0-description": "Hello",
|
|
648
|
+
}
|
|
649
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
650
|
+
|
|
651
|
+
# User should be given an error on the specific field in the form
|
|
652
|
+
self.assertEqual(response.status_code, 200)
|
|
653
|
+
self.assertFormSetError(
|
|
654
|
+
response.context["searchpicks_formset"],
|
|
655
|
+
0,
|
|
656
|
+
"page",
|
|
657
|
+
"Select a valid choice. "
|
|
658
|
+
"That choice is not one of the available choices.",
|
|
659
|
+
)
|
|
660
|
+
# Should not raise an error anywhere else
|
|
661
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
662
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
663
|
+
|
|
491
664
|
def test_post_with_external_link(self):
|
|
492
665
|
# Submit
|
|
493
666
|
post_data = {
|
|
@@ -547,14 +720,16 @@ class TestSearchPromotionsAddView(WagtailTestUtils, TestCase):
|
|
|
547
720
|
}
|
|
548
721
|
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
549
722
|
|
|
550
|
-
# User should be given an error
|
|
723
|
+
# User should be given an error on a specific form in the formset
|
|
551
724
|
self.assertEqual(response.status_code, 200)
|
|
552
725
|
self.assertFormSetError(
|
|
553
726
|
response.context["searchpicks_formset"],
|
|
554
|
-
|
|
727
|
+
0,
|
|
555
728
|
None,
|
|
556
729
|
"Please only select a page OR enter an external link.",
|
|
557
730
|
)
|
|
731
|
+
# Should not raise an error on the top-level formset
|
|
732
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
558
733
|
|
|
559
734
|
def test_post_missing_recommendation(self):
|
|
560
735
|
post_data = {
|
|
@@ -568,14 +743,42 @@ class TestSearchPromotionsAddView(WagtailTestUtils, TestCase):
|
|
|
568
743
|
}
|
|
569
744
|
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
570
745
|
|
|
571
|
-
# User should be given an error
|
|
746
|
+
# User should be given an error on a specific form in the formset
|
|
572
747
|
self.assertEqual(response.status_code, 200)
|
|
573
748
|
self.assertFormSetError(
|
|
574
749
|
response.context["searchpicks_formset"],
|
|
575
|
-
|
|
750
|
+
0,
|
|
576
751
|
None,
|
|
577
752
|
"You must recommend a page OR an external link.",
|
|
578
753
|
)
|
|
754
|
+
# Should not raise an error on the top-level formset
|
|
755
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
756
|
+
|
|
757
|
+
def test_post_invalid_external_link(self):
|
|
758
|
+
post_data = {
|
|
759
|
+
"query_string": "test",
|
|
760
|
+
"editors_picks-TOTAL_FORMS": 1,
|
|
761
|
+
"editors_picks-INITIAL_FORMS": 0,
|
|
762
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
763
|
+
"editors_picks-0-DELETE": "",
|
|
764
|
+
"editors_picks-0-ORDER": 0,
|
|
765
|
+
"editors_picks-0-external_link_url": "notalink",
|
|
766
|
+
"editors_picks-0-external_link_text": "Wagtail",
|
|
767
|
+
"editors_picks-0-description": "Hello",
|
|
768
|
+
}
|
|
769
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
770
|
+
|
|
771
|
+
# User should be given an error on the specific field in the form
|
|
772
|
+
self.assertEqual(response.status_code, 200)
|
|
773
|
+
self.assertFormSetError(
|
|
774
|
+
response.context["searchpicks_formset"],
|
|
775
|
+
0,
|
|
776
|
+
"external_link_url",
|
|
777
|
+
"Enter a valid URL.",
|
|
778
|
+
)
|
|
779
|
+
# Should not raise an error anywhere else
|
|
780
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
781
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
579
782
|
|
|
580
783
|
def test_post_missing_external_text(self):
|
|
581
784
|
post_data = {
|
|
@@ -589,17 +792,55 @@ class TestSearchPromotionsAddView(WagtailTestUtils, TestCase):
|
|
|
589
792
|
}
|
|
590
793
|
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
591
794
|
|
|
592
|
-
# User should be given an error
|
|
795
|
+
# User should be given an error on the specific field in the form
|
|
593
796
|
self.assertEqual(response.status_code, 200)
|
|
594
797
|
self.assertFormSetError(
|
|
595
798
|
response.context["searchpicks_formset"],
|
|
596
|
-
|
|
597
|
-
|
|
799
|
+
0,
|
|
800
|
+
"external_link_text",
|
|
598
801
|
"You must enter an external link text if you enter an external link URL.",
|
|
599
802
|
)
|
|
600
803
|
|
|
804
|
+
# Should not raise an error anywhere else
|
|
805
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
806
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
601
807
|
|
|
602
|
-
|
|
808
|
+
def test_get_with_no_permission(self):
|
|
809
|
+
self.user.is_superuser = False
|
|
810
|
+
self.user.save()
|
|
811
|
+
# Only basic access_admin permission is given
|
|
812
|
+
self.user.user_permissions.add(
|
|
813
|
+
Permission.objects.get(
|
|
814
|
+
content_type__app_label="wagtailadmin",
|
|
815
|
+
codename="access_admin",
|
|
816
|
+
)
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
response = self.client.get(reverse("wagtailsearchpromotions:add"))
|
|
820
|
+
self.assertEqual(response.status_code, 302)
|
|
821
|
+
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
822
|
+
|
|
823
|
+
def test_get_with_add_permission_only(self):
|
|
824
|
+
self.user.is_superuser = False
|
|
825
|
+
self.user.save()
|
|
826
|
+
# Only basic access_admin permission is given
|
|
827
|
+
self.user.user_permissions.add(
|
|
828
|
+
Permission.objects.get(
|
|
829
|
+
content_type__app_label="wagtailadmin",
|
|
830
|
+
codename="access_admin",
|
|
831
|
+
),
|
|
832
|
+
Permission.objects.get(
|
|
833
|
+
content_type__app_label="wagtailsearchpromotions",
|
|
834
|
+
codename="add_searchpromotion",
|
|
835
|
+
),
|
|
836
|
+
)
|
|
837
|
+
|
|
838
|
+
response = self.client.get(reverse("wagtailsearchpromotions:add"))
|
|
839
|
+
self.assertEqual(response.status_code, 200)
|
|
840
|
+
self.assertTemplateUsed(response, "wagtailsearchpromotions/add.html")
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
class TestSearchPromotionsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
603
844
|
def setUp(self):
|
|
604
845
|
self.user = self.login()
|
|
605
846
|
|
|
@@ -623,6 +864,17 @@ class TestSearchPromotionsEditView(WagtailTestUtils, TestCase):
|
|
|
623
864
|
expected_url = "/admin/searchpicks/%d/" % self.query.id
|
|
624
865
|
self.assertEqual(url_finder.get_edit_url(self.search_pick), expected_url)
|
|
625
866
|
|
|
867
|
+
self.assertBreadcrumbsItemsRendered(
|
|
868
|
+
[
|
|
869
|
+
{
|
|
870
|
+
"url": reverse("wagtailsearchpromotions:index"),
|
|
871
|
+
"label": "Promoted search results",
|
|
872
|
+
},
|
|
873
|
+
{"url": "", "label": "hello"},
|
|
874
|
+
],
|
|
875
|
+
response.content,
|
|
876
|
+
)
|
|
877
|
+
|
|
626
878
|
def test_post(self):
|
|
627
879
|
# Submit
|
|
628
880
|
post_data = {
|
|
@@ -654,6 +906,136 @@ class TestSearchPromotionsEditView(WagtailTestUtils, TestCase):
|
|
|
654
906
|
"Description has changed",
|
|
655
907
|
)
|
|
656
908
|
|
|
909
|
+
search_picks = list(
|
|
910
|
+
Query.get("Hello").editors_picks.all().order_by("description")
|
|
911
|
+
)
|
|
912
|
+
self.assertEqual(len(search_picks), 2)
|
|
913
|
+
self.assertEqual(search_picks[0].page_id, 1)
|
|
914
|
+
self.assertEqual(search_picks[0].description, "Description has changed")
|
|
915
|
+
self.assertEqual(search_picks[1].page_id, 2)
|
|
916
|
+
self.assertEqual(search_picks[1].description, "Homepage")
|
|
917
|
+
|
|
918
|
+
# Ensure that only one log entry was created for each search pick
|
|
919
|
+
for search_pick in search_picks:
|
|
920
|
+
logs = log_registry.get_logs_for_instance(search_pick)
|
|
921
|
+
self.assertEqual(len(logs), 1)
|
|
922
|
+
self.assertEqual(logs[0].action, "wagtail.edit")
|
|
923
|
+
self.assertEqual(logs[0].user, self.user)
|
|
924
|
+
|
|
925
|
+
def test_post_with_invalid_query_string(self):
|
|
926
|
+
# Submit
|
|
927
|
+
post_data = {
|
|
928
|
+
"query_string": "",
|
|
929
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
930
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
931
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
932
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
933
|
+
"editors_picks-0-DELETE": "",
|
|
934
|
+
"editors_picks-0-ORDER": 0,
|
|
935
|
+
"editors_picks-0-page": 1,
|
|
936
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
937
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
938
|
+
"editors_picks-1-DELETE": "",
|
|
939
|
+
"editors_picks-1-ORDER": 1,
|
|
940
|
+
"editors_picks-1-page": 2,
|
|
941
|
+
"editors_picks-1-description": "Homepage",
|
|
942
|
+
}
|
|
943
|
+
response = self.client.post(reverse("wagtailsearchpromotions:add"), post_data)
|
|
944
|
+
|
|
945
|
+
# User should be given an error on the specific field in the form
|
|
946
|
+
self.assertEqual(response.status_code, 200)
|
|
947
|
+
self.assertFormError(
|
|
948
|
+
response.context["form"], "query_string", "This field is required."
|
|
949
|
+
)
|
|
950
|
+
# The formset should still contain the submitted data
|
|
951
|
+
self.assertEqual(len(response.context["searchpicks_formset"].forms), 2)
|
|
952
|
+
self.assertEqual(
|
|
953
|
+
response.context["searchpicks_formset"].forms[0].cleaned_data["page"].id,
|
|
954
|
+
1,
|
|
955
|
+
)
|
|
956
|
+
self.assertEqual(
|
|
957
|
+
response.context["searchpicks_formset"]
|
|
958
|
+
.forms[0]
|
|
959
|
+
.cleaned_data["description"],
|
|
960
|
+
"Description has changed",
|
|
961
|
+
)
|
|
962
|
+
# Should not raise an error anywhere else
|
|
963
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, "page", [])
|
|
964
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
965
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
966
|
+
|
|
967
|
+
def test_post_with_invalid_page(self):
|
|
968
|
+
# Submit
|
|
969
|
+
post_data = {
|
|
970
|
+
"query_string": "Hello",
|
|
971
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
972
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
973
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
974
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
975
|
+
"editors_picks-0-DELETE": "",
|
|
976
|
+
"editors_picks-0-ORDER": 0,
|
|
977
|
+
"editors_picks-0-page": 1,
|
|
978
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
979
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
980
|
+
"editors_picks-1-DELETE": "",
|
|
981
|
+
"editors_picks-1-ORDER": 1,
|
|
982
|
+
"editors_picks-1-page": 9214599,
|
|
983
|
+
"editors_picks-1-description": "Homepage",
|
|
984
|
+
}
|
|
985
|
+
response = self.client.post(
|
|
986
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
987
|
+
)
|
|
988
|
+
|
|
989
|
+
# User should be given an error on the specific field in the form
|
|
990
|
+
self.assertEqual(response.status_code, 200)
|
|
991
|
+
self.assertFormSetError(
|
|
992
|
+
response.context["searchpicks_formset"],
|
|
993
|
+
1,
|
|
994
|
+
"page",
|
|
995
|
+
"Select a valid choice. "
|
|
996
|
+
"That choice is not one of the available choices.",
|
|
997
|
+
)
|
|
998
|
+
# Should not raise an error anywhere else
|
|
999
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
1000
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 1, None, [])
|
|
1001
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
1002
|
+
|
|
1003
|
+
def test_post_change_query_string(self):
|
|
1004
|
+
current_picks = set(self.query.editors_picks.all())
|
|
1005
|
+
# Submit
|
|
1006
|
+
post_data = {
|
|
1007
|
+
"query_string": "Hello again",
|
|
1008
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1009
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1010
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1011
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1012
|
+
"editors_picks-0-DELETE": "",
|
|
1013
|
+
"editors_picks-0-ORDER": 0,
|
|
1014
|
+
"editors_picks-0-page": 1,
|
|
1015
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
1016
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1017
|
+
"editors_picks-1-DELETE": "",
|
|
1018
|
+
"editors_picks-1-ORDER": 1,
|
|
1019
|
+
"editors_picks-1-page": 2,
|
|
1020
|
+
"editors_picks-1-description": "Homepage",
|
|
1021
|
+
}
|
|
1022
|
+
response = self.client.post(
|
|
1023
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1024
|
+
)
|
|
1025
|
+
|
|
1026
|
+
# User should be redirected back to the index
|
|
1027
|
+
self.assertRedirects(response, reverse("wagtailsearchpromotions:index"))
|
|
1028
|
+
|
|
1029
|
+
# Ensure search picks from the old query are moved to the new one
|
|
1030
|
+
new_query = Query.get("Hello again")
|
|
1031
|
+
self.assertEqual(set(new_query.editors_picks.all()), current_picks)
|
|
1032
|
+
self.search_pick.refresh_from_db()
|
|
1033
|
+
self.assertEqual(self.search_pick.query, new_query)
|
|
1034
|
+
self.assertEqual(self.query.editors_picks.count(), 0)
|
|
1035
|
+
|
|
1036
|
+
# Check that the search pick description was edited
|
|
1037
|
+
self.assertEqual(self.search_pick.description, "Description has changed")
|
|
1038
|
+
|
|
657
1039
|
def test_post_reorder(self):
|
|
658
1040
|
# Check order before reordering
|
|
659
1041
|
self.assertEqual(Query.get("Hello").editors_picks.all()[0], self.search_pick)
|
|
@@ -695,6 +1077,45 @@ class TestSearchPromotionsEditView(WagtailTestUtils, TestCase):
|
|
|
695
1077
|
self.assertEqual(Query.get("Hello").editors_picks.all()[0], self.search_pick_2)
|
|
696
1078
|
self.assertEqual(Query.get("Hello").editors_picks.all()[1], self.search_pick)
|
|
697
1079
|
|
|
1080
|
+
def test_post_with_external_link(self):
|
|
1081
|
+
# Submit
|
|
1082
|
+
post_data = {
|
|
1083
|
+
"query_string": "Hello",
|
|
1084
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1085
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1086
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1087
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1088
|
+
"editors_picks-0-DELETE": "",
|
|
1089
|
+
"editors_picks-0-ORDER": 1, # Change
|
|
1090
|
+
"editors_picks-0-external_link_url": "https://wagtail.org",
|
|
1091
|
+
"editors_picks-0-external_link_text": "Wagtail",
|
|
1092
|
+
"editors_picks-0-description": "Root page",
|
|
1093
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1094
|
+
"editors_picks-1-DELETE": "",
|
|
1095
|
+
"editors_picks-1-ORDER": 0, # Change
|
|
1096
|
+
"editors_picks-1-external_link_url": "https://djangoproject.com",
|
|
1097
|
+
"editors_picks-1-external_link_text": "Django",
|
|
1098
|
+
"editors_picks-1-description": "Homepage",
|
|
1099
|
+
}
|
|
1100
|
+
response = self.client.post(
|
|
1101
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1102
|
+
)
|
|
1103
|
+
|
|
1104
|
+
# User should be redirected back to the index
|
|
1105
|
+
self.assertRedirects(response, reverse("wagtailsearchpromotions:index"))
|
|
1106
|
+
|
|
1107
|
+
# Check that the search pick was created
|
|
1108
|
+
self.assertTrue(
|
|
1109
|
+
Query.get("Hello")
|
|
1110
|
+
.editors_picks.filter(external_link_url="https://wagtail.org")
|
|
1111
|
+
.exists()
|
|
1112
|
+
)
|
|
1113
|
+
self.assertTrue(
|
|
1114
|
+
Query.get("Hello")
|
|
1115
|
+
.editors_picks.filter(external_link_url="https://djangoproject.com")
|
|
1116
|
+
.exists()
|
|
1117
|
+
)
|
|
1118
|
+
|
|
698
1119
|
def test_post_delete_recommendation(self):
|
|
699
1120
|
# Submit
|
|
700
1121
|
post_data = {
|
|
@@ -759,10 +1180,184 @@ class TestSearchPromotionsEditView(WagtailTestUtils, TestCase):
|
|
|
759
1180
|
"Please specify at least one recommendation for this search term.",
|
|
760
1181
|
)
|
|
761
1182
|
|
|
1183
|
+
def test_post_with_page_and_external_link(self):
|
|
1184
|
+
post_data = {
|
|
1185
|
+
"query_string": "Hello",
|
|
1186
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1187
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1188
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1189
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1190
|
+
"editors_picks-0-DELETE": "",
|
|
1191
|
+
"editors_picks-0-ORDER": 0,
|
|
1192
|
+
"editors_picks-0-page": 1,
|
|
1193
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
1194
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1195
|
+
"editors_picks-1-DELETE": "",
|
|
1196
|
+
"editors_picks-1-ORDER": 1,
|
|
1197
|
+
"editors_picks-1-page": 2,
|
|
1198
|
+
"editors_picks-1-external_link_url": "https://wagtail.org",
|
|
1199
|
+
"editors_picks-1-external_link_text": "Wagtail",
|
|
1200
|
+
"editors_picks-1-description": "Homepage",
|
|
1201
|
+
}
|
|
1202
|
+
response = self.client.post(
|
|
1203
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
# User should be given an error on a specific form in the formset
|
|
1207
|
+
self.assertEqual(response.status_code, 200)
|
|
1208
|
+
self.assertFormSetError(
|
|
1209
|
+
response.context["searchpicks_formset"],
|
|
1210
|
+
1,
|
|
1211
|
+
None,
|
|
1212
|
+
"Please only select a page OR enter an external link.",
|
|
1213
|
+
)
|
|
1214
|
+
# Should not raise an error anywhere else
|
|
1215
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
1216
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 0, None, [])
|
|
1217
|
+
|
|
1218
|
+
def test_post_missing_recommendation(self):
|
|
1219
|
+
post_data = {
|
|
1220
|
+
"query_string": "Hello",
|
|
1221
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1222
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1223
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1224
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1225
|
+
"editors_picks-0-DELETE": "",
|
|
1226
|
+
"editors_picks-0-ORDER": 0,
|
|
1227
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
1228
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1229
|
+
"editors_picks-1-DELETE": "",
|
|
1230
|
+
"editors_picks-1-ORDER": 1,
|
|
1231
|
+
"editors_picks-1-external_link_url": "https://wagtail.org",
|
|
1232
|
+
"editors_picks-1-external_link_text": "Wagtail",
|
|
1233
|
+
"editors_picks-1-description": "Homepage",
|
|
1234
|
+
}
|
|
1235
|
+
response = self.client.post(
|
|
1236
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1237
|
+
)
|
|
1238
|
+
|
|
1239
|
+
# User should be given an error on a specific form in the formset
|
|
1240
|
+
self.assertEqual(response.status_code, 200)
|
|
1241
|
+
self.assertFormSetError(
|
|
1242
|
+
response.context["searchpicks_formset"],
|
|
1243
|
+
0,
|
|
1244
|
+
None,
|
|
1245
|
+
"You must recommend a page OR an external link.",
|
|
1246
|
+
)
|
|
1247
|
+
# Should not raise an error anywhere else
|
|
1248
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
1249
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 1, None, [])
|
|
1250
|
+
|
|
1251
|
+
def test_post_invalid_external_link(self):
|
|
1252
|
+
post_data = {
|
|
1253
|
+
"query_string": "Hello",
|
|
1254
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1255
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1256
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1257
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1258
|
+
"editors_picks-0-DELETE": "",
|
|
1259
|
+
"editors_picks-0-ORDER": 0,
|
|
1260
|
+
"editors_picks-0-page": 1,
|
|
1261
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
1262
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1263
|
+
"editors_picks-1-DELETE": "",
|
|
1264
|
+
"editors_picks-1-ORDER": 1,
|
|
1265
|
+
"editors_picks-1-external_link_url": "notalink",
|
|
1266
|
+
"editors_picks-1-external_link_text": "Wagtail",
|
|
1267
|
+
"editors_picks-1-description": "Homepage",
|
|
1268
|
+
}
|
|
1269
|
+
response = self.client.post(
|
|
1270
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1271
|
+
)
|
|
1272
|
+
|
|
1273
|
+
# User should be given an error on the specific field in the form
|
|
1274
|
+
self.assertEqual(response.status_code, 200)
|
|
1275
|
+
self.assertFormSetError(
|
|
1276
|
+
response.context["searchpicks_formset"],
|
|
1277
|
+
1,
|
|
1278
|
+
"external_link_url",
|
|
1279
|
+
"Enter a valid URL.",
|
|
1280
|
+
)
|
|
1281
|
+
# Should not raise an error anywhere else
|
|
1282
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 1, None, [])
|
|
1283
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
1284
|
+
|
|
1285
|
+
def test_post_missing_external_text(self):
|
|
1286
|
+
post_data = {
|
|
1287
|
+
"query_string": "Hello",
|
|
1288
|
+
"editors_picks-TOTAL_FORMS": 2,
|
|
1289
|
+
"editors_picks-INITIAL_FORMS": 2,
|
|
1290
|
+
"editors_picks-MAX_NUM_FORMS": 1000,
|
|
1291
|
+
"editors_picks-0-id": self.search_pick.id,
|
|
1292
|
+
"editors_picks-0-DELETE": "",
|
|
1293
|
+
"editors_picks-0-ORDER": 0,
|
|
1294
|
+
"editors_picks-0-page": 1,
|
|
1295
|
+
"editors_picks-0-description": "Description has changed", # Change
|
|
1296
|
+
"editors_picks-1-id": self.search_pick_2.id,
|
|
1297
|
+
"editors_picks-1-DELETE": "",
|
|
1298
|
+
"editors_picks-1-ORDER": 1,
|
|
1299
|
+
"editors_picks-1-external_link_url": "https://wagtail.org",
|
|
1300
|
+
"editors_picks-1-description": "Homepage",
|
|
1301
|
+
}
|
|
1302
|
+
response = self.client.post(
|
|
1303
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)), post_data
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1306
|
+
# User should be given an error on the specific field in the form
|
|
1307
|
+
self.assertEqual(response.status_code, 200)
|
|
1308
|
+
self.assertFormSetError(
|
|
1309
|
+
response.context["searchpicks_formset"],
|
|
1310
|
+
1,
|
|
1311
|
+
"external_link_text",
|
|
1312
|
+
"You must enter an external link text if you enter an external link URL.",
|
|
1313
|
+
)
|
|
1314
|
+
|
|
1315
|
+
# Should not raise an error anywhere else
|
|
1316
|
+
self.assertFormSetError(response.context["searchpicks_formset"], 1, None, [])
|
|
1317
|
+
self.assertFormSetError(response.context["searchpicks_formset"], None, None, [])
|
|
1318
|
+
|
|
1319
|
+
def test_get_with_no_permission(self):
|
|
1320
|
+
self.user.is_superuser = False
|
|
1321
|
+
self.user.save()
|
|
1322
|
+
# Only basic access_admin permission is given
|
|
1323
|
+
self.user.user_permissions.add(
|
|
1324
|
+
Permission.objects.get(
|
|
1325
|
+
content_type__app_label="wagtailadmin",
|
|
1326
|
+
codename="access_admin",
|
|
1327
|
+
)
|
|
1328
|
+
)
|
|
1329
|
+
|
|
1330
|
+
response = self.client.get(
|
|
1331
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)),
|
|
1332
|
+
)
|
|
1333
|
+
self.assertEqual(response.status_code, 302)
|
|
1334
|
+
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
1335
|
+
|
|
1336
|
+
def test_get_with_edit_permission_only(self):
|
|
1337
|
+
self.user.is_superuser = False
|
|
1338
|
+
self.user.save()
|
|
1339
|
+
# Only basic access_admin permission is given
|
|
1340
|
+
self.user.user_permissions.add(
|
|
1341
|
+
Permission.objects.get(
|
|
1342
|
+
content_type__app_label="wagtailadmin",
|
|
1343
|
+
codename="access_admin",
|
|
1344
|
+
),
|
|
1345
|
+
Permission.objects.get(
|
|
1346
|
+
content_type__app_label="wagtailsearchpromotions",
|
|
1347
|
+
codename="change_searchpromotion",
|
|
1348
|
+
),
|
|
1349
|
+
)
|
|
1350
|
+
|
|
1351
|
+
response = self.client.get(
|
|
1352
|
+
reverse("wagtailsearchpromotions:edit", args=(self.query.id,)),
|
|
1353
|
+
)
|
|
1354
|
+
self.assertEqual(response.status_code, 200)
|
|
1355
|
+
self.assertTemplateUsed(response, "wagtailsearchpromotions/edit.html")
|
|
1356
|
+
|
|
762
1357
|
|
|
763
1358
|
class TestSearchPromotionsDeleteView(WagtailTestUtils, TestCase):
|
|
764
1359
|
def setUp(self):
|
|
765
|
-
self.login()
|
|
1360
|
+
self.user = self.login()
|
|
766
1361
|
|
|
767
1362
|
# Create a search pick to delete
|
|
768
1363
|
self.query = Query.get("Hello")
|
|
@@ -799,6 +1394,44 @@ class TestSearchPromotionsDeleteView(WagtailTestUtils, TestCase):
|
|
|
799
1394
|
SearchPromotion.objects.filter(id=self.search_pick.id).exists()
|
|
800
1395
|
)
|
|
801
1396
|
|
|
1397
|
+
def test_get_with_no_permission(self):
|
|
1398
|
+
self.user.is_superuser = False
|
|
1399
|
+
self.user.save()
|
|
1400
|
+
# Only basic access_admin permission is given
|
|
1401
|
+
self.user.user_permissions.add(
|
|
1402
|
+
Permission.objects.get(
|
|
1403
|
+
content_type__app_label="wagtailadmin",
|
|
1404
|
+
codename="access_admin",
|
|
1405
|
+
)
|
|
1406
|
+
)
|
|
1407
|
+
|
|
1408
|
+
response = self.client.get(
|
|
1409
|
+
reverse("wagtailsearchpromotions:delete", args=(self.query.id,)),
|
|
1410
|
+
)
|
|
1411
|
+
self.assertEqual(response.status_code, 302)
|
|
1412
|
+
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
1413
|
+
|
|
1414
|
+
def test_get_with_edit_permission_only(self):
|
|
1415
|
+
self.user.is_superuser = False
|
|
1416
|
+
self.user.save()
|
|
1417
|
+
# Only basic access_admin permission is given
|
|
1418
|
+
self.user.user_permissions.add(
|
|
1419
|
+
Permission.objects.get(
|
|
1420
|
+
content_type__app_label="wagtailadmin",
|
|
1421
|
+
codename="access_admin",
|
|
1422
|
+
),
|
|
1423
|
+
Permission.objects.get(
|
|
1424
|
+
content_type__app_label="wagtailsearchpromotions",
|
|
1425
|
+
codename="delete_searchpromotion",
|
|
1426
|
+
),
|
|
1427
|
+
)
|
|
1428
|
+
|
|
1429
|
+
response = self.client.get(
|
|
1430
|
+
reverse("wagtailsearchpromotions:delete", args=(self.query.id,)),
|
|
1431
|
+
)
|
|
1432
|
+
self.assertEqual(response.status_code, 200)
|
|
1433
|
+
self.assertTemplateUsed(response, "wagtailsearchpromotions/confirm_delete.html")
|
|
1434
|
+
|
|
802
1435
|
|
|
803
1436
|
class TestGarbageCollectManagementCommand(TestCase):
|
|
804
1437
|
def test_garbage_collect_command(self):
|
|
@@ -972,3 +1605,171 @@ class TestQueryPopularity(TestCase):
|
|
|
972
1605
|
self.assertEqual(popular_queries[0], Query.get("unpopular query"))
|
|
973
1606
|
self.assertEqual(popular_queries[1], Query.get("popular query"))
|
|
974
1607
|
self.assertEqual(popular_queries[2], Query.get("little popular query"))
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
class TestQueryHitsReportView(BaseReportViewTestCase):
|
|
1611
|
+
url_name = "wagtailsearchpromotions:search_terms"
|
|
1612
|
+
|
|
1613
|
+
@classmethod
|
|
1614
|
+
def setUpTestData(self):
|
|
1615
|
+
self.query = Query.get("A query with three hits")
|
|
1616
|
+
self.query.add_hit()
|
|
1617
|
+
self.query.add_hit()
|
|
1618
|
+
self.query.add_hit()
|
|
1619
|
+
Query.get("a query with no hits")
|
|
1620
|
+
Query.get("A query with one hit").add_hit()
|
|
1621
|
+
query = Query.get("A query with two hits")
|
|
1622
|
+
query.add_hit()
|
|
1623
|
+
query.add_hit()
|
|
1624
|
+
|
|
1625
|
+
def test_simple(self):
|
|
1626
|
+
response = self.get()
|
|
1627
|
+
self.assertEqual(response.status_code, 200)
|
|
1628
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
1629
|
+
self.assertTemplateUsed(
|
|
1630
|
+
response,
|
|
1631
|
+
"wagtailadmin/reports/base_report_results.html",
|
|
1632
|
+
)
|
|
1633
|
+
self.assertBreadcrumbs(
|
|
1634
|
+
[{"url": "", "label": "Search terms"}],
|
|
1635
|
+
response.content,
|
|
1636
|
+
)
|
|
1637
|
+
|
|
1638
|
+
soup = self.get_soup(response.content)
|
|
1639
|
+
trs = soup.select("main tr")
|
|
1640
|
+
|
|
1641
|
+
# Default ordering should be by hits descending
|
|
1642
|
+
self.assertEqual(
|
|
1643
|
+
[[cell.text.strip() for cell in tr.select("th,td")] for tr in trs],
|
|
1644
|
+
[
|
|
1645
|
+
["Search term(s)", "Views"],
|
|
1646
|
+
["a query with three hits", "3"],
|
|
1647
|
+
["a query with two hits", "2"],
|
|
1648
|
+
["a query with one hit", "1"],
|
|
1649
|
+
],
|
|
1650
|
+
)
|
|
1651
|
+
|
|
1652
|
+
self.assertNotContains(response, "There are no results.")
|
|
1653
|
+
self.assertActiveFilterNotRendered(soup)
|
|
1654
|
+
self.assertPageTitle(soup, "Search terms - Wagtail")
|
|
1655
|
+
|
|
1656
|
+
def test_get_with_no_permissions(self):
|
|
1657
|
+
self.user.is_superuser = False
|
|
1658
|
+
self.user.save()
|
|
1659
|
+
self.user.user_permissions.add(
|
|
1660
|
+
Permission.objects.get(
|
|
1661
|
+
content_type__app_label="wagtailadmin", codename="access_admin"
|
|
1662
|
+
)
|
|
1663
|
+
)
|
|
1664
|
+
|
|
1665
|
+
response = self.get()
|
|
1666
|
+
|
|
1667
|
+
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
1668
|
+
|
|
1669
|
+
def test_csv_export(self):
|
|
1670
|
+
response = self.get(params={"export": "csv"})
|
|
1671
|
+
self.assertEqual(response.status_code, 200)
|
|
1672
|
+
|
|
1673
|
+
data_lines = response.getvalue().decode().splitlines()
|
|
1674
|
+
self.assertEqual(
|
|
1675
|
+
data_lines,
|
|
1676
|
+
[
|
|
1677
|
+
"Search term(s),Views",
|
|
1678
|
+
"a query with three hits,3",
|
|
1679
|
+
"a query with two hits,2",
|
|
1680
|
+
"a query with one hit,1",
|
|
1681
|
+
],
|
|
1682
|
+
)
|
|
1683
|
+
|
|
1684
|
+
def test_xlsx_export(self):
|
|
1685
|
+
response = self.get(params={"export": "xlsx"})
|
|
1686
|
+
self.assertEqual(response.status_code, 200)
|
|
1687
|
+
workbook_data = response.getvalue()
|
|
1688
|
+
worksheet = load_workbook(filename=BytesIO(workbook_data))["Sheet1"]
|
|
1689
|
+
cell_array = [[cell.value for cell in row] for row in worksheet.rows]
|
|
1690
|
+
self.assertEqual(
|
|
1691
|
+
cell_array,
|
|
1692
|
+
[
|
|
1693
|
+
["Search term(s)", "Views"],
|
|
1694
|
+
["a query with three hits", 3],
|
|
1695
|
+
["a query with two hits", 2],
|
|
1696
|
+
["a query with one hit", 1],
|
|
1697
|
+
],
|
|
1698
|
+
)
|
|
1699
|
+
|
|
1700
|
+
def test_ordering(self):
|
|
1701
|
+
cases = {
|
|
1702
|
+
"query_string": [
|
|
1703
|
+
["a query with one hit", "1"],
|
|
1704
|
+
["a query with three hits", "3"],
|
|
1705
|
+
["a query with two hits", "2"],
|
|
1706
|
+
],
|
|
1707
|
+
"-query_string": [
|
|
1708
|
+
["a query with two hits", "2"],
|
|
1709
|
+
["a query with three hits", "3"],
|
|
1710
|
+
["a query with one hit", "1"],
|
|
1711
|
+
],
|
|
1712
|
+
"_hits": [
|
|
1713
|
+
["a query with one hit", "1"],
|
|
1714
|
+
["a query with two hits", "2"],
|
|
1715
|
+
["a query with three hits", "3"],
|
|
1716
|
+
],
|
|
1717
|
+
"-_hits": [
|
|
1718
|
+
["a query with three hits", "3"],
|
|
1719
|
+
["a query with two hits", "2"],
|
|
1720
|
+
["a query with one hit", "1"],
|
|
1721
|
+
],
|
|
1722
|
+
}
|
|
1723
|
+
for ordering, results in cases.items():
|
|
1724
|
+
with self.subTest(ordering=ordering):
|
|
1725
|
+
response = self.get(params={"ordering": ordering})
|
|
1726
|
+
self.assertEqual(response.status_code, 200)
|
|
1727
|
+
soup = self.get_soup(response.content)
|
|
1728
|
+
trs = soup.select("main tbody tr")
|
|
1729
|
+
self.assertEqual(
|
|
1730
|
+
[[cell.text.strip() for cell in tr.select("td")] for tr in trs],
|
|
1731
|
+
results,
|
|
1732
|
+
)
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
class TestFilteredQueryHitsView(BaseReportViewTestCase):
|
|
1736
|
+
url_name = "wagtailsearchpromotions:search_terms"
|
|
1737
|
+
|
|
1738
|
+
def setUp(self):
|
|
1739
|
+
self.user = self.login()
|
|
1740
|
+
self.query_hit = Query.get("This will be found")
|
|
1741
|
+
self.date = timezone.now().date()
|
|
1742
|
+
self.query_hit.add_hit(date=self.date)
|
|
1743
|
+
|
|
1744
|
+
def test_search_by_query_string(self):
|
|
1745
|
+
response = self.get(params={"q": "Found"})
|
|
1746
|
+
self.assertEqual(response.status_code, 200)
|
|
1747
|
+
self.assertContains(response, "this will be found")
|
|
1748
|
+
self.assertNotContains(response, "There are no results.")
|
|
1749
|
+
self.assertActiveFilterNotRendered(self.get_soup(response.content))
|
|
1750
|
+
|
|
1751
|
+
response = self.get(params={"q": "Not found"})
|
|
1752
|
+
self.assertEqual(response.status_code, 200)
|
|
1753
|
+
self.assertContains(response, "There are no results.")
|
|
1754
|
+
self.assertNotContains(response, "this will be found")
|
|
1755
|
+
self.assertActiveFilterNotRendered(self.get_soup(response.content))
|
|
1756
|
+
|
|
1757
|
+
def test_filter_by_date(self):
|
|
1758
|
+
params = {
|
|
1759
|
+
"hit_date_from": self.date.replace(day=1, month=1),
|
|
1760
|
+
}
|
|
1761
|
+
response = self.get(params=params)
|
|
1762
|
+
self.assertEqual(response.status_code, 200)
|
|
1763
|
+
self.assertContains(response, "this will be found")
|
|
1764
|
+
self.assertNotContains(response, "There are no results.")
|
|
1765
|
+
self.assertActiveFilter(
|
|
1766
|
+
self.get_soup(response.content), "hit_date_from", params["hit_date_from"]
|
|
1767
|
+
)
|
|
1768
|
+
|
|
1769
|
+
params["hit_date_from"] = self.date.replace(year=self.date.year + 1)
|
|
1770
|
+
params["hit_date_to"] = self.date.replace(year=self.date.year + 2)
|
|
1771
|
+
|
|
1772
|
+
response = self.get(params=params)
|
|
1773
|
+
self.assertEqual(response.status_code, 200)
|
|
1774
|
+
self.assertContains(response, "There are no results.")
|
|
1775
|
+
self.assertNotContains(response, "this will be found")
|