wagtail 6.1.3__py3-none-any.whl → 6.2rc1__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/copy_for_translation.py +15 -1
- wagtail/admin/checks.py +20 -30
- wagtail/admin/forms/pages.py +10 -0
- wagtail/admin/icons.py +43 -0
- wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +30 -0
- wagtail/admin/menu.py +2 -2
- wagtail/admin/migrations/0004_editingsession.py +57 -0
- wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
- wagtail/admin/models.py +36 -3
- wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +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/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.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/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
- wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
- wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
- wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
- wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
- wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
- wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
- wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
- wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
- wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
- wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
- wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
- wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
- wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
- wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
- wagtail/admin/tests/formats/en/__init__.py +0 -0
- wagtail/admin/tests/formats/en/formats.py +1 -0
- wagtail/admin/tests/pages/test_create_page.py +47 -0
- wagtail/admin/tests/pages/test_edit_page.py +10 -8
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
- wagtail/admin/tests/test_checks.py +53 -3
- wagtail/admin/tests/test_collections_views.py +62 -1
- wagtail/admin/tests/test_edit_handlers.py +37 -0
- wagtail/admin/tests/test_editing_sessions.py +1336 -0
- wagtail/admin/tests/test_icon_sprite.py +12 -21
- wagtail/admin/tests/test_page_chooser.py +309 -7
- wagtail/admin/tests/test_privacy.py +82 -0
- wagtail/admin/tests/test_reports_views.py +464 -70
- wagtail/admin/tests/test_userbar.py +93 -6
- wagtail/admin/tests/test_workflows.py +223 -33
- wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
- wagtail/admin/ui/editing_sessions.py +57 -0
- wagtail/admin/urls/__init__.py +9 -15
- wagtail/admin/urls/editing_sessions.py +17 -0
- wagtail/admin/urls/reports.py +33 -1
- wagtail/admin/userbar.py +77 -20
- wagtail/admin/views/chooser.py +49 -22
- wagtail/admin/views/collections.py +0 -11
- wagtail/admin/views/editing_sessions.py +193 -0
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/history.py +9 -3
- wagtail/admin/views/generic/mixins.py +44 -3
- wagtail/admin/views/generic/models.py +46 -72
- wagtail/admin/views/generic/permissions.py +20 -10
- wagtail/admin/views/home.py +2 -31
- wagtail/admin/views/page_privacy.py +20 -5
- wagtail/admin/views/pages/choose_parent.py +62 -0
- wagtail/admin/views/pages/edit.py +28 -0
- wagtail/admin/views/reports/aging_pages.py +6 -10
- wagtail/admin/views/reports/audit_logging.py +13 -42
- wagtail/admin/views/reports/base.py +31 -4
- wagtail/admin/views/reports/locked_pages.py +5 -8
- wagtail/admin/views/reports/page_types_usage.py +6 -10
- wagtail/admin/views/reports/workflows.py +36 -12
- wagtail/admin/viewsets/base.py +8 -3
- wagtail/admin/viewsets/chooser.py +1 -1
- wagtail/admin/viewsets/model.py +26 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/api/v2/filters.py +6 -0
- wagtail/api/v2/tests/test_documents.py +1 -1
- wagtail/api/v2/tests/test_images.py +1 -1
- wagtail/api/v2/tests/test_pages.py +11 -1
- wagtail/api/v2/utils.py +2 -2
- wagtail/blocks/base.py +35 -12
- wagtail/blocks/definition_lookup.py +85 -0
- wagtail/blocks/list_block.py +12 -0
- wagtail/blocks/migrations/migrate_operation.py +2 -0
- wagtail/blocks/stream_block.py +19 -0
- wagtail/blocks/struct_block.py +19 -0
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
- wagtail/contrib/frontend_cache/backends/azure.py +179 -0
- wagtail/contrib/frontend_cache/backends/base.py +28 -0
- wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
- wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
- wagtail/contrib/frontend_cache/backends/http.py +64 -0
- wagtail/contrib/frontend_cache/tests.py +59 -17
- wagtail/contrib/frontend_cache/utils.py +26 -8
- wagtail/contrib/redirects/filters.py +15 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
- wagtail/contrib/redirects/models.py +6 -5
- wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
- wagtail/contrib/redirects/tests/test_redirects.py +141 -1
- wagtail/contrib/redirects/urls.py +1 -2
- wagtail/contrib/redirects/views.py +39 -80
- wagtail/contrib/routable_page/models.py +6 -4
- wagtail/contrib/routable_page/tests.py +11 -0
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/simple_translation/models.py +2 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/blocks.py +19 -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 +38 -0
- wagtail/coreutils.py +1 -1
- wagtail/documents/__init__.py +1 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/documents/models.py +5 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/tests/test_models.py +5 -1
- wagtail/embeds/apps.py +2 -0
- wagtail/embeds/embeds.py +12 -14
- wagtail/embeds/finders/__init__.py +2 -0
- wagtail/embeds/finders/facebook.py +17 -33
- wagtail/embeds/finders/instagram.py +19 -16
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/signal_handlers.py +13 -0
- wagtail/embeds/tests/test_embeds.py +7 -7
- wagtail/fields.py +58 -14
- wagtail/images/__init__.py +1 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
- wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/images/models.py +2 -0
- wagtail/images/static/wagtailimages/js/image-chooser-modal.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/templates/wagtailimages/images/edit.html +4 -4
- wagtail/images/tests/test_admin_views.py +26 -2
- wagtail/images/views/chooser.py +6 -1
- wagtail/locale/en/LC_MESSAGES/django.po +84 -80
- wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/locales/tests.py +16 -0
- wagtail/locales/wagtail_hooks.py +0 -9
- wagtail/migrations/0094_alter_page_locale.py +19 -0
- wagtail/models/__init__.py +11 -5
- wagtail/models/i18n.py +6 -1
- wagtail/project_template/requirements.txt +1 -1
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/signals.py +4 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/sites/tests.py +15 -0
- wagtail/sites/wagtail_hooks.py +0 -9
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
- wagtail/snippets/permissions.py +5 -3
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
- wagtail/snippets/tests/test_snippets.py +78 -12
- wagtail/snippets/tests/test_viewset.py +22 -0
- wagtail/snippets/views/snippets.py +19 -14
- wagtail/snippets/wagtail_hooks.py +2 -10
- wagtail/templatetags/wagtailcore_tags.py +3 -0
- wagtail/test/dummy_external_storage.py +1 -1
- wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
- wagtail/test/routablepage/models.py +4 -0
- wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
- wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
- wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
- wagtail/test/testapp/models.py +24 -0
- wagtail/test/testapp/views.py +1 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/test/urls_multilang.py +6 -1
- wagtail/test/urls_multilang_non_root.py +11 -0
- wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
- wagtail/tests/test_audit_log.py +72 -2
- wagtail/tests/test_blocks.py +103 -0
- wagtail/tests/test_signals.py +49 -2
- wagtail/tests/test_streamfield.py +153 -0
- wagtail/tests/test_utils.py +14 -0
- wagtail/tests/tests.py +5 -0
- wagtail/users/apps.py +1 -0
- wagtail/users/forms.py +7 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
- wagtail/users/models.py +1 -0
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
- wagtail/users/templatetags/wagtailusers_tags.py +9 -0
- wagtail/users/tests/__init__.py +7 -1
- wagtail/users/tests/test_admin_views.py +117 -32
- wagtail/users/views/groups.py +4 -0
- wagtail/users/views/users.py +58 -14
- wagtail/users/wagtail_hooks.py +7 -123
- wagtail/utils/utils.py +1 -0
- wagtail/utils/version.py +5 -2
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/METADATA +3 -3
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/RECORD +248 -222
- wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
- wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
- wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
- wagtail/contrib/frontend_cache/backends.py +0 -400
- wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
- wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
- wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
|
@@ -11,6 +11,7 @@ from django.test import RequestFactory, TestCase
|
|
|
11
11
|
from django.test.utils import override_settings
|
|
12
12
|
from django.urls import reverse
|
|
13
13
|
from django.utils import timezone, translation
|
|
14
|
+
from freezegun import freeze_time
|
|
14
15
|
from openpyxl import load_workbook
|
|
15
16
|
|
|
16
17
|
from wagtail.admin.views.mixins import ExcelDateFormatter
|
|
@@ -31,32 +32,115 @@ from wagtail.test.testapp.models import (
|
|
|
31
32
|
SimplePage,
|
|
32
33
|
)
|
|
33
34
|
from wagtail.test.utils import WagtailTestUtils
|
|
35
|
+
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
|
|
36
|
+
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BaseReportViewTestCase(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
40
|
+
url_name = None
|
|
41
|
+
header_buttons_parent_selector = "#w-slim-header-buttons"
|
|
42
|
+
drilldown_selector = ".w-drilldown"
|
|
43
|
+
extra_params = ""
|
|
44
|
+
results_only = False
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def setUpClass(cls):
|
|
48
|
+
super().setUpClass()
|
|
49
|
+
cls.url = reverse(cls.url_name)
|
|
50
|
+
if cls.results_only:
|
|
51
|
+
cls.header_buttons_parent_selector = (
|
|
52
|
+
'[data-controller="w-teleport"]'
|
|
53
|
+
'[data-w-teleport-target-value="#w-slim-header-buttons"]'
|
|
54
|
+
)
|
|
55
|
+
cls.drilldown_selector = (
|
|
56
|
+
'[data-controller="w-teleport"]'
|
|
57
|
+
'[data-w-teleport-target-value="#filters-drilldown"]'
|
|
58
|
+
)
|
|
59
|
+
cls.extra_params = "&_w_filter_fragment=true"
|
|
34
60
|
|
|
35
|
-
|
|
36
|
-
class TestLockedPagesView(WagtailTestUtils, TestCase):
|
|
37
61
|
def setUp(self):
|
|
38
62
|
self.user = self.login()
|
|
39
63
|
|
|
40
64
|
def get(self, params={}):
|
|
41
|
-
|
|
65
|
+
if self.results_only:
|
|
66
|
+
params["_w_filter_fragment"] = "true"
|
|
67
|
+
return self.client.get(self.url, params)
|
|
68
|
+
|
|
69
|
+
def assertActiveFilter(self, soup, name, value):
|
|
70
|
+
# Should render the export buttons inside the header "more" dropdown
|
|
71
|
+
# with the filtered URL. When used in a results-only view, these are
|
|
72
|
+
# teleported to the correct element in the skeleton.
|
|
73
|
+
links_parent = soup.select_one(self.header_buttons_parent_selector)
|
|
74
|
+
self.assertIsNotNone(links_parent)
|
|
75
|
+
links = links_parent.select(".w-dropdown a")
|
|
76
|
+
unfiltered_url = reverse(self.url_name)
|
|
77
|
+
filtered_url = f"{unfiltered_url}?{name}={value}{self.extra_params}"
|
|
78
|
+
self.assertEqual(len(links), 2)
|
|
79
|
+
self.assertEqual(
|
|
80
|
+
[link.get("href") for link in links],
|
|
81
|
+
[f"{filtered_url}&export=xlsx", f"{filtered_url}&export=csv"],
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Should render the active filter pill
|
|
85
|
+
active_filter = soup.select_one(".w-active-filters .w-pill__content")
|
|
86
|
+
clear_button = soup.select_one(".w-active-filters .w-pill__remove")
|
|
87
|
+
self.assertIsNotNone(active_filter)
|
|
88
|
+
self.assertIsNotNone(clear_button)
|
|
89
|
+
self.assertNotIn(name, clear_button.attrs.get("data-w-swap-src-value"))
|
|
90
|
+
self.assertEqual(clear_button.attrs.get("data-w-swap-reflect-value"), "true")
|
|
91
|
+
|
|
92
|
+
def assertActiveFilterNotRendered(self, soup):
|
|
93
|
+
self.assertIsNone(soup.select_one(".w-active-filters"))
|
|
94
|
+
|
|
95
|
+
def assertBreadcrumbs(self, breadcrumbs, html):
|
|
96
|
+
if self.results_only:
|
|
97
|
+
self.assertBreadcrumbsNotRendered(html)
|
|
98
|
+
else:
|
|
99
|
+
self.assertBreadcrumbsItemsRendered(breadcrumbs, html)
|
|
100
|
+
|
|
101
|
+
def assertPageTitle(self, soup, title):
|
|
102
|
+
page_title = soup.select_one("title")
|
|
103
|
+
if self.results_only:
|
|
104
|
+
self.assertIsNone(page_title)
|
|
105
|
+
else:
|
|
106
|
+
self.assertIsNotNone(page_title)
|
|
107
|
+
self.assertEqual(page_title.text.strip(), title)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TestLockedPagesView(BaseReportViewTestCase):
|
|
111
|
+
url_name = "wagtailadmin_reports:locked_pages"
|
|
42
112
|
|
|
43
113
|
def test_simple(self):
|
|
44
114
|
response = self.get()
|
|
45
115
|
self.assertEqual(response.status_code, 200)
|
|
46
|
-
self.
|
|
116
|
+
self.assertTemplateNotUsed(
|
|
117
|
+
response,
|
|
118
|
+
"wagtailadmin/reports/base_page_report.html",
|
|
119
|
+
)
|
|
120
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
121
|
+
self.assertTemplateUsed(
|
|
122
|
+
response,
|
|
123
|
+
"wagtailadmin/reports/locked_pages_results.html",
|
|
124
|
+
)
|
|
125
|
+
self.assertBreadcrumbs(
|
|
126
|
+
[{"url": "", "label": "Locked pages"}],
|
|
127
|
+
response.content,
|
|
128
|
+
)
|
|
47
129
|
|
|
48
130
|
# Initially there should be no locked pages
|
|
49
131
|
self.assertContains(response, "No locked pages found.")
|
|
50
132
|
|
|
51
|
-
#
|
|
52
|
-
self.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<option value="" selected>---------</option>
|
|
56
|
-
</select>
|
|
57
|
-
""",
|
|
58
|
-
response.content.decode(),
|
|
133
|
+
# Should render the filter inside the drilldown
|
|
134
|
+
soup = self.get_soup(response.content)
|
|
135
|
+
locked_by_options = soup.select(
|
|
136
|
+
f"{self.drilldown_selector} select[name='locked_by'] option"
|
|
59
137
|
)
|
|
138
|
+
# No user locked anything, so there should be no option for the filter
|
|
139
|
+
self.assertEqual(len(locked_by_options), 1)
|
|
140
|
+
self.assertEqual(locked_by_options[0].text, "---------")
|
|
141
|
+
self.assertEqual(locked_by_options[0].get("value"), "")
|
|
142
|
+
self.assertActiveFilterNotRendered(soup)
|
|
143
|
+
self.assertPageTitle(soup, "Locked pages - Wagtail")
|
|
60
144
|
|
|
61
145
|
parent_page = Page.objects.first()
|
|
62
146
|
parent_page.add_child(
|
|
@@ -79,20 +163,35 @@ class TestLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
79
163
|
# Now the listing should contain our locked page
|
|
80
164
|
response = self.get()
|
|
81
165
|
self.assertEqual(response.status_code, 200)
|
|
82
|
-
self.
|
|
166
|
+
self.assertTemplateNotUsed(
|
|
167
|
+
response,
|
|
168
|
+
"wagtailadmin/reports/base_page_report.html",
|
|
169
|
+
)
|
|
170
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
171
|
+
self.assertTemplateUsed(
|
|
172
|
+
response,
|
|
173
|
+
"wagtailadmin/reports/locked_pages_results.html",
|
|
174
|
+
)
|
|
175
|
+
self.assertBreadcrumbs(
|
|
176
|
+
[{"url": "", "label": "Locked pages"}],
|
|
177
|
+
response.content,
|
|
178
|
+
)
|
|
83
179
|
self.assertNotContains(response, "No locked pages found.")
|
|
84
180
|
self.assertContains(response, "First locked page")
|
|
85
181
|
self.assertContains(response, "Second locked page")
|
|
86
182
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<option value="{self.user.pk}">{self.user}</option>
|
|
92
|
-
</select>
|
|
93
|
-
""",
|
|
94
|
-
response.content.decode(),
|
|
183
|
+
# Should render the filter inside the drilldown
|
|
184
|
+
soup = self.get_soup(response.content)
|
|
185
|
+
locked_by_options = soup.select(
|
|
186
|
+
f"{self.drilldown_selector} select[name='locked_by'] option"
|
|
95
187
|
)
|
|
188
|
+
# The options should only display users who have locked pages
|
|
189
|
+
self.assertEqual(len(locked_by_options), 2)
|
|
190
|
+
self.assertEqual(locked_by_options[0].text, "---------")
|
|
191
|
+
self.assertIsNone(locked_by_options[0].value)
|
|
192
|
+
self.assertEqual(locked_by_options[1].text, str(self.user))
|
|
193
|
+
self.assertEqual(locked_by_options[1].get("value"), str(self.user.pk))
|
|
194
|
+
self.assertActiveFilterNotRendered(soup)
|
|
96
195
|
|
|
97
196
|
# Locked by current user shown in indicator
|
|
98
197
|
self.assertContains(response, "locked-indicator indicator--is-inverse")
|
|
@@ -119,7 +218,15 @@ class TestLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
119
218
|
response = self.get()
|
|
120
219
|
|
|
121
220
|
self.assertEqual(response.status_code, 200)
|
|
122
|
-
self.
|
|
221
|
+
self.assertTemplateNotUsed(
|
|
222
|
+
response,
|
|
223
|
+
"wagtailadmin/reports/base_page_report.html",
|
|
224
|
+
)
|
|
225
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
226
|
+
self.assertTemplateUsed(
|
|
227
|
+
response,
|
|
228
|
+
"wagtailadmin/reports/locked_pages_results.html",
|
|
229
|
+
)
|
|
123
230
|
self.assertContains(response, "No locked pages found.")
|
|
124
231
|
|
|
125
232
|
def test_get_with_no_permissions(self):
|
|
@@ -210,8 +317,9 @@ class TestLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
210
317
|
self.assertEqual(worksheet["E2"].number_format, ExcelDateFormatter().get())
|
|
211
318
|
|
|
212
319
|
|
|
213
|
-
class TestFilteredLockedPagesView(
|
|
320
|
+
class TestFilteredLockedPagesView(BaseReportViewTestCase):
|
|
214
321
|
fixtures = ["test.json"]
|
|
322
|
+
url_name = "wagtailadmin_reports:locked_pages"
|
|
215
323
|
|
|
216
324
|
def setUp(self):
|
|
217
325
|
self.user = self.login()
|
|
@@ -229,9 +337,6 @@ class TestFilteredLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
229
337
|
self.christmas_page.locked_at = timezone.now()
|
|
230
338
|
self.christmas_page.save()
|
|
231
339
|
|
|
232
|
-
def get(self, params={}):
|
|
233
|
-
return self.client.get(reverse("wagtailadmin_reports:locked_pages"), params)
|
|
234
|
-
|
|
235
340
|
def test_filter_by_live(self):
|
|
236
341
|
response = self.get(params={"live": "true"})
|
|
237
342
|
self.assertEqual(response.status_code, 200)
|
|
@@ -245,6 +350,9 @@ class TestFilteredLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
245
350
|
self.assertNotContains(response, "My locked page")
|
|
246
351
|
self.assertNotContains(response, "Christmas")
|
|
247
352
|
|
|
353
|
+
soup = self.get_soup(response.content)
|
|
354
|
+
self.assertActiveFilter(soup, "live", "false")
|
|
355
|
+
|
|
248
356
|
def test_filter_by_user(self):
|
|
249
357
|
response = self.get(params={"locked_by": self.user.pk})
|
|
250
358
|
self.assertEqual(response.status_code, 200)
|
|
@@ -253,8 +361,14 @@ class TestFilteredLockedPagesView(WagtailTestUtils, TestCase):
|
|
|
253
361
|
self.assertNotContains(response, "My locked page")
|
|
254
362
|
|
|
255
363
|
|
|
256
|
-
class
|
|
364
|
+
class TestFilteredLockedPagesResultsView(TestFilteredLockedPagesView):
|
|
365
|
+
url_name = "wagtailadmin_reports:locked_pages_results"
|
|
366
|
+
results_only = True
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class TestFilteredLogEntriesView(BaseReportViewTestCase):
|
|
257
370
|
fixtures = ["test.json"]
|
|
371
|
+
url_name = "wagtailadmin_reports:site_history"
|
|
258
372
|
|
|
259
373
|
def setUp(self):
|
|
260
374
|
self.user = self.login()
|
|
@@ -275,17 +389,32 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
275
389
|
)
|
|
276
390
|
editors.user_set.add(self.editor)
|
|
277
391
|
|
|
392
|
+
# timezone matches TIME_ZONE = "Asia/Tokyo" in tests/settings.py
|
|
393
|
+
with freeze_time("2024-05-06 12:00:00+09:00"):
|
|
394
|
+
self.today = timezone.now()
|
|
395
|
+
|
|
278
396
|
self.create_log = PageLogEntry.objects.log_action(
|
|
279
|
-
self.home_page,
|
|
397
|
+
self.home_page,
|
|
398
|
+
"wagtail.create",
|
|
399
|
+
timestamp=self.today - timezone.timedelta(days=4),
|
|
400
|
+
user=self.user,
|
|
280
401
|
)
|
|
281
402
|
self.edit_log_1 = PageLogEntry.objects.log_action(
|
|
282
|
-
self.home_page,
|
|
403
|
+
self.home_page,
|
|
404
|
+
"wagtail.edit",
|
|
405
|
+
timestamp=self.today - timezone.timedelta(days=3),
|
|
283
406
|
)
|
|
284
407
|
self.edit_log_2 = PageLogEntry.objects.log_action(
|
|
285
|
-
self.home_page,
|
|
408
|
+
self.home_page,
|
|
409
|
+
"wagtail.edit",
|
|
410
|
+
timestamp=self.today - timezone.timedelta(days=2),
|
|
411
|
+
user=self.editor,
|
|
286
412
|
)
|
|
287
413
|
self.edit_log_3 = PageLogEntry.objects.log_action(
|
|
288
|
-
self.home_page,
|
|
414
|
+
self.home_page,
|
|
415
|
+
"wagtail.edit",
|
|
416
|
+
timestamp=self.today - timezone.timedelta(days=1),
|
|
417
|
+
title="The FINAL cut",
|
|
289
418
|
)
|
|
290
419
|
|
|
291
420
|
self.create_comment_log = PageLogEntry.objects.log_action(
|
|
@@ -322,30 +451,37 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
322
451
|
self.create_custom_log = ModelLogEntry.objects.log_action(
|
|
323
452
|
self.custom_model,
|
|
324
453
|
"wagtail.create",
|
|
454
|
+
timestamp=self.today - timezone.timedelta(days=3),
|
|
325
455
|
)
|
|
326
456
|
|
|
327
457
|
self.edit_custom_log = ModelLogEntry.objects.log_action(
|
|
328
458
|
self.custom_model,
|
|
329
459
|
"wagtail.edit",
|
|
460
|
+
timestamp=self.today - timezone.timedelta(days=2),
|
|
461
|
+
title="the final CUT",
|
|
330
462
|
)
|
|
331
463
|
|
|
332
|
-
def get(self, params={}):
|
|
333
|
-
return self.client.get(reverse("wagtailadmin_reports:site_history"), params)
|
|
334
|
-
|
|
335
464
|
def assert_log_entries(self, response, expected):
|
|
336
465
|
actual = set(response.context["object_list"])
|
|
337
466
|
self.assertSetEqual(actual, set(expected))
|
|
338
467
|
|
|
339
468
|
def assert_filter_actions(self, response, expected):
|
|
469
|
+
soup = self.get_soup(response.content)
|
|
340
470
|
actual = {
|
|
341
|
-
choice
|
|
342
|
-
for choice in
|
|
471
|
+
choice.get("value")
|
|
472
|
+
for choice in soup.select(
|
|
473
|
+
f"{self.drilldown_selector} input[name='action'][type='checkbox']"
|
|
474
|
+
)
|
|
343
475
|
}
|
|
344
476
|
self.assertSetEqual(actual, set(expected))
|
|
345
477
|
|
|
346
478
|
def test_unfiltered(self):
|
|
347
479
|
response = self.get()
|
|
348
480
|
self.assertEqual(response.status_code, 200)
|
|
481
|
+
self.assertBreadcrumbs(
|
|
482
|
+
[{"url": "", "label": "Site history"}],
|
|
483
|
+
response.content,
|
|
484
|
+
)
|
|
349
485
|
self.assert_log_entries(
|
|
350
486
|
response,
|
|
351
487
|
[
|
|
@@ -372,6 +508,10 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
372
508
|
],
|
|
373
509
|
)
|
|
374
510
|
|
|
511
|
+
soup = self.get_soup(response.content)
|
|
512
|
+
self.assertActiveFilterNotRendered(soup)
|
|
513
|
+
self.assertPageTitle(soup, "Site history - Wagtail")
|
|
514
|
+
|
|
375
515
|
# The editor should not see the Advert's log entries.
|
|
376
516
|
self.login(user=self.editor)
|
|
377
517
|
response = self.get()
|
|
@@ -400,6 +540,9 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
400
540
|
],
|
|
401
541
|
)
|
|
402
542
|
|
|
543
|
+
soup = self.get_soup(response.content)
|
|
544
|
+
self.assertActiveFilterNotRendered(soup)
|
|
545
|
+
|
|
403
546
|
def test_filter_by_action(self):
|
|
404
547
|
response = self.get(params={"action": "wagtail.edit"})
|
|
405
548
|
self.assertEqual(response.status_code, 200)
|
|
@@ -425,23 +568,174 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
425
568
|
],
|
|
426
569
|
)
|
|
427
570
|
|
|
428
|
-
|
|
429
|
-
|
|
571
|
+
soup = self.get_soup(response.content)
|
|
572
|
+
self.assertActiveFilter(soup, "action", "wagtail.edit")
|
|
573
|
+
|
|
574
|
+
def test_filter_by_action_multiple(self):
|
|
575
|
+
response = self.get(params={"action": ["wagtail.edit", "wagtail.create"]})
|
|
430
576
|
self.assertEqual(response.status_code, 200)
|
|
431
577
|
self.assert_log_entries(
|
|
432
578
|
response,
|
|
433
579
|
[
|
|
434
580
|
self.create_log,
|
|
581
|
+
self.create_custom_log,
|
|
435
582
|
self.edit_log_1,
|
|
436
583
|
self.edit_log_2,
|
|
437
584
|
self.edit_log_3,
|
|
585
|
+
self.edit_custom_log,
|
|
586
|
+
],
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
self.login(user=self.editor)
|
|
590
|
+
response = self.get(params={"action": ["wagtail.edit", "wagtail.create"]})
|
|
591
|
+
self.assertEqual(response.status_code, 200)
|
|
592
|
+
self.assert_log_entries(
|
|
593
|
+
response,
|
|
594
|
+
[
|
|
595
|
+
self.create_log,
|
|
596
|
+
self.edit_log_1,
|
|
597
|
+
self.edit_log_2,
|
|
598
|
+
self.edit_log_3,
|
|
599
|
+
],
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
def test_filter_by_timestamp(self):
|
|
603
|
+
today = self.today.date()
|
|
604
|
+
response = self.get(
|
|
605
|
+
params={"timestamp_from": today - timezone.timedelta(days=3)}
|
|
606
|
+
)
|
|
607
|
+
self.assertEqual(response.status_code, 200)
|
|
608
|
+
self.assert_log_entries(
|
|
609
|
+
response,
|
|
610
|
+
[
|
|
611
|
+
# Doesn't contain self.create_log which was created 4 days ago
|
|
612
|
+
self.edit_log_1,
|
|
613
|
+
self.edit_log_2,
|
|
614
|
+
self.edit_log_3,
|
|
615
|
+
self.create_comment_log,
|
|
616
|
+
self.edit_comment_log,
|
|
617
|
+
self.create_reply_log,
|
|
618
|
+
self.create_custom_log,
|
|
619
|
+
self.edit_custom_log,
|
|
620
|
+
],
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
response = self.get(params={"timestamp_to": today - timezone.timedelta(days=2)})
|
|
624
|
+
self.assertEqual(response.status_code, 200)
|
|
625
|
+
self.assert_log_entries(
|
|
626
|
+
response,
|
|
627
|
+
[
|
|
628
|
+
# Doesn't contain self.edit_log_3 which was created 1 day ago,
|
|
629
|
+
# as well as self.create_comment_log, self.edit_comment_log,
|
|
630
|
+
# and self.create_reply_log which was created without an explicit
|
|
631
|
+
# timestamp (and thus defaults to the current time)
|
|
632
|
+
self.create_log,
|
|
633
|
+
self.edit_log_1,
|
|
634
|
+
self.edit_log_2,
|
|
635
|
+
self.create_custom_log,
|
|
636
|
+
self.edit_custom_log,
|
|
637
|
+
],
|
|
638
|
+
)
|
|
639
|
+
|
|
640
|
+
response = self.get(
|
|
641
|
+
params={
|
|
642
|
+
"timestamp_from": today - timezone.timedelta(days=3),
|
|
643
|
+
"timestamp_to": today - timezone.timedelta(days=2),
|
|
644
|
+
}
|
|
645
|
+
)
|
|
646
|
+
self.assertEqual(response.status_code, 200)
|
|
647
|
+
self.assert_log_entries(
|
|
648
|
+
response,
|
|
649
|
+
[
|
|
650
|
+
# Doesn't contain
|
|
651
|
+
# self.create_log which was created 4 days ago,
|
|
652
|
+
# self.edit_log_3 which was created 1 day ago,
|
|
653
|
+
# as well as self.create_comment_log, self.edit_comment_log,
|
|
654
|
+
# and self.create_reply_log which was created without an explicit
|
|
655
|
+
# timestamp (and thus defaults to the current time)
|
|
656
|
+
self.edit_log_1,
|
|
657
|
+
self.edit_log_2,
|
|
438
658
|
self.create_custom_log,
|
|
439
659
|
self.edit_custom_log,
|
|
440
660
|
],
|
|
441
661
|
)
|
|
442
662
|
|
|
663
|
+
def test_filter_by_user(self):
|
|
664
|
+
response = self.get(params={"user": self.editor.pk})
|
|
665
|
+
self.assertEqual(response.status_code, 200)
|
|
666
|
+
self.assert_log_entries(response, [self.edit_log_2])
|
|
667
|
+
|
|
668
|
+
response = self.get(params={"user": [self.user.pk, self.editor.pk]})
|
|
669
|
+
self.assertEqual(response.status_code, 200)
|
|
670
|
+
self.assert_log_entries(response, [self.create_log, self.edit_log_2])
|
|
671
|
+
|
|
672
|
+
def test_filter_by_label(self):
|
|
673
|
+
response = self.get(params={"label": "final cut"})
|
|
674
|
+
self.assertEqual(response.status_code, 200)
|
|
675
|
+
self.assert_log_entries(response, [self.edit_log_3, self.edit_custom_log])
|
|
676
|
+
|
|
677
|
+
def test_filter_by_object_type(self):
|
|
678
|
+
response = self.get(
|
|
679
|
+
params={"object_type": ContentType.objects.get_for_model(Page).pk}
|
|
680
|
+
)
|
|
681
|
+
self.assertEqual(response.status_code, 200)
|
|
682
|
+
self.assert_log_entries(
|
|
683
|
+
response,
|
|
684
|
+
[
|
|
685
|
+
self.create_log,
|
|
686
|
+
self.edit_log_1,
|
|
687
|
+
self.edit_log_2,
|
|
688
|
+
self.edit_log_3,
|
|
689
|
+
self.create_comment_log,
|
|
690
|
+
self.edit_comment_log,
|
|
691
|
+
self.create_reply_log,
|
|
692
|
+
],
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
response = self.get(
|
|
696
|
+
params={"object_type": ContentType.objects.get_for_model(Advert).pk}
|
|
697
|
+
)
|
|
698
|
+
self.assertEqual(response.status_code, 200)
|
|
699
|
+
self.assert_log_entries(
|
|
700
|
+
response,
|
|
701
|
+
[
|
|
702
|
+
self.create_custom_log,
|
|
703
|
+
self.edit_custom_log,
|
|
704
|
+
],
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
def test_is_commenting_action(self):
|
|
708
|
+
response = self.get(params={"is_commenting_action": "false"})
|
|
709
|
+
self.assertEqual(response.status_code, 200)
|
|
710
|
+
self.assert_log_entries(
|
|
711
|
+
response,
|
|
712
|
+
[
|
|
713
|
+
self.create_log,
|
|
714
|
+
self.edit_log_1,
|
|
715
|
+
self.edit_log_2,
|
|
716
|
+
self.edit_log_3,
|
|
717
|
+
self.create_custom_log,
|
|
718
|
+
self.edit_custom_log,
|
|
719
|
+
],
|
|
720
|
+
)
|
|
721
|
+
soup = self.get_soup(response.content)
|
|
722
|
+
self.assertActiveFilter(soup, "is_commenting_action", "false")
|
|
723
|
+
|
|
724
|
+
response = self.get(params={"is_commenting_action": "true"})
|
|
725
|
+
self.assertEqual(response.status_code, 200)
|
|
726
|
+
self.assert_log_entries(
|
|
727
|
+
response,
|
|
728
|
+
[
|
|
729
|
+
self.create_comment_log,
|
|
730
|
+
self.edit_comment_log,
|
|
731
|
+
self.create_reply_log,
|
|
732
|
+
],
|
|
733
|
+
)
|
|
734
|
+
soup = self.get_soup(response.content)
|
|
735
|
+
self.assertActiveFilter(soup, "is_commenting_action", "true")
|
|
736
|
+
|
|
443
737
|
self.login(user=self.editor)
|
|
444
|
-
response = self.get(params={"
|
|
738
|
+
response = self.get(params={"is_commenting_action": "false"})
|
|
445
739
|
self.assertEqual(response.status_code, 200)
|
|
446
740
|
self.assert_log_entries(
|
|
447
741
|
response,
|
|
@@ -452,6 +746,21 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
452
746
|
self.edit_log_3,
|
|
453
747
|
],
|
|
454
748
|
)
|
|
749
|
+
soup = self.get_soup(response.content)
|
|
750
|
+
self.assertActiveFilter(soup, "is_commenting_action", "false")
|
|
751
|
+
|
|
752
|
+
response = self.get(params={"is_commenting_action": "true"})
|
|
753
|
+
self.assertEqual(response.status_code, 200)
|
|
754
|
+
self.assert_log_entries(
|
|
755
|
+
response,
|
|
756
|
+
[
|
|
757
|
+
self.create_comment_log,
|
|
758
|
+
self.edit_comment_log,
|
|
759
|
+
self.create_reply_log,
|
|
760
|
+
],
|
|
761
|
+
)
|
|
762
|
+
soup = self.get_soup(response.content)
|
|
763
|
+
self.assertActiveFilter(soup, "is_commenting_action", "true")
|
|
455
764
|
|
|
456
765
|
def test_log_entry_with_stale_content_type(self):
|
|
457
766
|
stale_content_type = ContentType.objects.create(
|
|
@@ -499,6 +808,46 @@ class TestFilteredLogEntriesView(WagtailTestUtils, TestCase):
|
|
|
499
808
|
|
|
500
809
|
self.assertEqual(response.status_code, 200)
|
|
501
810
|
|
|
811
|
+
def test_deprecated_title_attribute(self):
|
|
812
|
+
# Remove this test when the deprecation ends
|
|
813
|
+
with mock.patch.object(
|
|
814
|
+
LogEntriesView,
|
|
815
|
+
"page_title",
|
|
816
|
+
return_value=None,
|
|
817
|
+
new_callable=mock.PropertyMock,
|
|
818
|
+
), mock.patch.object(
|
|
819
|
+
LogEntriesView,
|
|
820
|
+
"title",
|
|
821
|
+
return_value="Deprecated page title",
|
|
822
|
+
new_callable=mock.PropertyMock,
|
|
823
|
+
):
|
|
824
|
+
with self.assertWarnsMessage(
|
|
825
|
+
RemovedInWagtail70Warning,
|
|
826
|
+
"The `title` attribute in `LogEntriesView` (a `ReportView` subclass) is "
|
|
827
|
+
"deprecated. Use `page_title` instead.",
|
|
828
|
+
):
|
|
829
|
+
self.assertEqual(LogEntriesView.title, "Deprecated page title")
|
|
830
|
+
self.assertIsNone(LogEntriesView.page_title)
|
|
831
|
+
response = self.get()
|
|
832
|
+
self.assertEqual(response.status_code, 200)
|
|
833
|
+
self.assertPageTitle(
|
|
834
|
+
self.get_soup(response.content),
|
|
835
|
+
"Deprecated page title - Wagtail",
|
|
836
|
+
)
|
|
837
|
+
self.assertEqual(
|
|
838
|
+
response.context["page_title"],
|
|
839
|
+
"Deprecated page title",
|
|
840
|
+
)
|
|
841
|
+
self.assertEqual(
|
|
842
|
+
response.context["title"],
|
|
843
|
+
"Deprecated page title",
|
|
844
|
+
)
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
class TestFilteredLogEntriesResultsView(TestFilteredLogEntriesView):
|
|
848
|
+
url_name = "wagtailadmin_reports:site_history_results"
|
|
849
|
+
results_only = True
|
|
850
|
+
|
|
502
851
|
|
|
503
852
|
@override_settings(
|
|
504
853
|
USE_L10N=True,
|
|
@@ -523,22 +872,36 @@ class TestExcelDateFormatter(TestCase):
|
|
|
523
872
|
self.assertEqual(formatter.format("m/d/Y g:i A"), "mm/dd/yyyy h:mm AM/PM")
|
|
524
873
|
|
|
525
874
|
|
|
526
|
-
class TestAgingPagesView(
|
|
875
|
+
class TestAgingPagesView(BaseReportViewTestCase):
|
|
876
|
+
url_name = "wagtailadmin_reports:aging_pages"
|
|
877
|
+
|
|
527
878
|
def setUp(self):
|
|
528
879
|
self.user = self.login()
|
|
529
880
|
self.root = Page.objects.first()
|
|
530
881
|
self.home = Page.objects.get(slug="home")
|
|
531
882
|
|
|
532
|
-
def get(self, params={}):
|
|
533
|
-
return self.client.get(reverse("wagtailadmin_reports:aging_pages"), params)
|
|
534
|
-
|
|
535
883
|
def publish_home_page(self):
|
|
536
884
|
self.home.save_revision().publish(user=self.user)
|
|
537
885
|
|
|
538
886
|
def test_simple(self):
|
|
539
887
|
response = self.get()
|
|
540
888
|
self.assertEqual(response.status_code, 200)
|
|
541
|
-
self.
|
|
889
|
+
self.assertTemplateNotUsed(
|
|
890
|
+
response,
|
|
891
|
+
"wagtailadmin/reports/base_page_report.html",
|
|
892
|
+
)
|
|
893
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
894
|
+
self.assertTemplateUsed(
|
|
895
|
+
response,
|
|
896
|
+
"wagtailadmin/reports/aging_pages_results.html",
|
|
897
|
+
)
|
|
898
|
+
self.assertBreadcrumbs(
|
|
899
|
+
[{"url": "", "label": "Aging pages"}],
|
|
900
|
+
response.content,
|
|
901
|
+
)
|
|
902
|
+
soup = self.get_soup(response.content)
|
|
903
|
+
self.assertActiveFilterNotRendered(soup)
|
|
904
|
+
self.assertPageTitle(soup, "Aging pages - Wagtail")
|
|
542
905
|
|
|
543
906
|
def test_displays_only_published_pages(self):
|
|
544
907
|
response = self.get()
|
|
@@ -686,13 +1049,12 @@ class TestAgingPagesView(WagtailTestUtils, TestCase):
|
|
|
686
1049
|
self.assertContains(response, expected_deleted_string)
|
|
687
1050
|
|
|
688
1051
|
|
|
689
|
-
class TestAgingPagesViewPermissions(
|
|
1052
|
+
class TestAgingPagesViewPermissions(BaseReportViewTestCase):
|
|
1053
|
+
url_name = "wagtailadmin_reports:aging_pages"
|
|
1054
|
+
|
|
690
1055
|
def setUp(self):
|
|
691
1056
|
self.user = self.login()
|
|
692
1057
|
|
|
693
|
-
def get(self, params={}):
|
|
694
|
-
return self.client.get(reverse("wagtailadmin_reports:aging_pages"), params)
|
|
695
|
-
|
|
696
1058
|
def test_simple(self):
|
|
697
1059
|
response = self.get()
|
|
698
1060
|
self.assertEqual(response.status_code, 200)
|
|
@@ -734,17 +1096,15 @@ class TestAgingPagesViewPermissions(WagtailTestUtils, TestCase):
|
|
|
734
1096
|
self.assertEqual(response.status_code, 200)
|
|
735
1097
|
|
|
736
1098
|
|
|
737
|
-
class TestFilteredAgingPagesView(
|
|
1099
|
+
class TestFilteredAgingPagesView(BaseReportViewTestCase):
|
|
738
1100
|
fixtures = ["test.json"]
|
|
1101
|
+
url_name = "wagtailadmin_reports:aging_pages"
|
|
739
1102
|
|
|
740
1103
|
def setUp(self):
|
|
741
1104
|
self.user = self.login()
|
|
742
1105
|
self.home_page = Page.objects.get(slug="home")
|
|
743
1106
|
self.aboutus_page = Page.objects.get(slug="about-us")
|
|
744
1107
|
|
|
745
|
-
def get(self, params={}):
|
|
746
|
-
return self.client.get(reverse("wagtailadmin_reports:aging_pages"), params)
|
|
747
|
-
|
|
748
1108
|
def test_filter_by_live(self):
|
|
749
1109
|
response = self.get(params={"live": "true"})
|
|
750
1110
|
|
|
@@ -758,14 +1118,25 @@ class TestFilteredAgingPagesView(WagtailTestUtils, TestCase):
|
|
|
758
1118
|
self.assertNotContains(response, self.aboutus_page.title)
|
|
759
1119
|
|
|
760
1120
|
def test_filter_by_content_type(self):
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
)
|
|
1121
|
+
ct_pk = self.aboutus_page.specific.content_type.pk
|
|
1122
|
+
response = self.get(params={"content_type": ct_pk})
|
|
764
1123
|
|
|
765
1124
|
self.assertEqual(response.status_code, 200)
|
|
766
1125
|
self.assertContains(response, self.aboutus_page.title)
|
|
767
1126
|
self.assertNotContains(response, self.home_page.title)
|
|
768
1127
|
|
|
1128
|
+
soup = self.get_soup(response.content)
|
|
1129
|
+
self.assertActiveFilter(soup, "content_type", ct_pk)
|
|
1130
|
+
|
|
1131
|
+
# Should render the filter inside the drilldown component
|
|
1132
|
+
ct_select = soup.select_one(
|
|
1133
|
+
f"{self.drilldown_selector} select[name='content_type']"
|
|
1134
|
+
)
|
|
1135
|
+
self.assertIsNotNone(ct_select)
|
|
1136
|
+
selected_option = ct_select.select_one("option[selected]")
|
|
1137
|
+
self.assertIsNotNone(selected_option)
|
|
1138
|
+
self.assertEqual(selected_option.get("value"), str(ct_pk))
|
|
1139
|
+
|
|
769
1140
|
def test_filter_by_last_published_at(self):
|
|
770
1141
|
self.home_page.last_published_at = timezone.now()
|
|
771
1142
|
self.home_page.save()
|
|
@@ -776,15 +1147,18 @@ class TestFilteredAgingPagesView(WagtailTestUtils, TestCase):
|
|
|
776
1147
|
self.assertNotContains(response, self.home_page.title)
|
|
777
1148
|
|
|
778
1149
|
|
|
779
|
-
class
|
|
1150
|
+
class TestFilteredAgingPagesResultsView(TestFilteredAgingPagesView):
|
|
1151
|
+
url_name = "wagtailadmin_reports:aging_pages_results"
|
|
1152
|
+
results_only = True
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
class PageTypesUsageReportViewTest(BaseReportViewTestCase):
|
|
780
1156
|
fixtures = ["test.json"]
|
|
1157
|
+
url_name = "wagtailadmin_reports:page_types_usage"
|
|
781
1158
|
|
|
782
1159
|
def setUp(self):
|
|
783
1160
|
self.user = self.login()
|
|
784
1161
|
|
|
785
|
-
def get(self, params={}):
|
|
786
|
-
return self.client.get(reverse("wagtailadmin_reports:page_types_usage"), params)
|
|
787
|
-
|
|
788
1162
|
@staticmethod
|
|
789
1163
|
def display_name(content_type):
|
|
790
1164
|
return f"{content_type.app_label}.{content_type.model}"
|
|
@@ -792,7 +1166,18 @@ class PageTypesUsageReportViewTest(WagtailTestUtils, TestCase):
|
|
|
792
1166
|
def test_simple(self):
|
|
793
1167
|
response = self.get()
|
|
794
1168
|
self.assertEqual(response.status_code, 200)
|
|
795
|
-
self.assertTemplateUsed(response, "wagtailadmin/reports/
|
|
1169
|
+
self.assertTemplateUsed(response, "wagtailadmin/reports/base_report.html")
|
|
1170
|
+
self.assertTemplateUsed(
|
|
1171
|
+
response,
|
|
1172
|
+
"wagtailadmin/reports/page_types_usage_results.html",
|
|
1173
|
+
)
|
|
1174
|
+
self.assertBreadcrumbs(
|
|
1175
|
+
[{"url": "", "label": "Page types usage"}],
|
|
1176
|
+
response.content,
|
|
1177
|
+
)
|
|
1178
|
+
soup = self.get_soup(response.content)
|
|
1179
|
+
self.assertActiveFilterNotRendered(soup)
|
|
1180
|
+
self.assertPageTitle(soup, "Page types usage - Wagtail")
|
|
796
1181
|
|
|
797
1182
|
def test_displays_only_page_types(self):
|
|
798
1183
|
"""Asserts that the correct models are included in the queryset."""
|
|
@@ -904,15 +1289,14 @@ class PageTypesUsageReportViewQuerysetTests(WagtailTestUtils, TestCase):
|
|
|
904
1289
|
|
|
905
1290
|
|
|
906
1291
|
@override_settings(LANGUAGE_CODE="en", WAGTAIL_I18N_ENABLED=True)
|
|
907
|
-
class PageTypesReportFiltersTests(
|
|
1292
|
+
class PageTypesReportFiltersTests(BaseReportViewTestCase):
|
|
1293
|
+
url_name = "wagtailadmin_reports:page_types_usage"
|
|
1294
|
+
|
|
908
1295
|
def setUp(self):
|
|
909
1296
|
self.user = self.login()
|
|
910
1297
|
self.default_locale = Locale.get_default()
|
|
911
1298
|
self.fr_locale, _ = Locale.objects.get_or_create(language_code="fr")
|
|
912
1299
|
|
|
913
|
-
def get(self, params={}):
|
|
914
|
-
return self.client.get(reverse("wagtailadmin_reports:page_types_usage"), params)
|
|
915
|
-
|
|
916
1300
|
def test_locale_filtering(self):
|
|
917
1301
|
# Create pages in default locale
|
|
918
1302
|
event_page = EventPage(
|
|
@@ -973,6 +1357,16 @@ class PageTypesReportFiltersTests(WagtailTestUtils, TestCase):
|
|
|
973
1357
|
self.assertEqual(event_page_row.last_edited_page.locale, self.fr_locale)
|
|
974
1358
|
self.assertEqual(simple_page_row.last_edited_page.locale, self.fr_locale)
|
|
975
1359
|
|
|
1360
|
+
# Should render the filter inside the drilldown component
|
|
1361
|
+
soup = self.get_soup(response.content)
|
|
1362
|
+
locale_select = soup.select_one(
|
|
1363
|
+
f"{self.drilldown_selector} select[name='page_locale']"
|
|
1364
|
+
)
|
|
1365
|
+
self.assertIsNotNone(locale_select)
|
|
1366
|
+
selected_option = locale_select.select_one("option[selected]")
|
|
1367
|
+
self.assertIsNotNone(selected_option)
|
|
1368
|
+
self.assertEqual(selected_option.get("value"), "fr")
|
|
1369
|
+
|
|
976
1370
|
def test_site_filtering_with_single_site(self):
|
|
977
1371
|
"""Asserts that the site filter is not displayed when there is only one site."""
|
|
978
1372
|
sites = Site.objects.all()
|
|
@@ -1055,14 +1449,14 @@ class PageTypesReportFiltersTests(WagtailTestUtils, TestCase):
|
|
|
1055
1449
|
self.assertCountEqual(choices, expected_choices)
|
|
1056
1450
|
|
|
1057
1451
|
|
|
1058
|
-
class
|
|
1059
|
-
|
|
1452
|
+
class PageTypesReportFiltersResultsTests(PageTypesReportFiltersTests):
|
|
1453
|
+
url_name = "wagtailadmin_reports:page_types_usage_results"
|
|
1454
|
+
results_only = True
|
|
1060
1455
|
|
|
1061
|
-
def setUp(self):
|
|
1062
|
-
self.user = self.login()
|
|
1063
1456
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1457
|
+
class TestPageTypesUsageReportViewPermissions(BaseReportViewTestCase):
|
|
1458
|
+
fixtures = ["test.json"]
|
|
1459
|
+
url_name = "wagtailadmin_reports:page_types_usage"
|
|
1066
1460
|
|
|
1067
1461
|
def test_simple(self):
|
|
1068
1462
|
response = self.get()
|