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
|
@@ -208,22 +208,32 @@ class TestAccessibilityCheckerConfig(WagtailTestUtils, TestCase):
|
|
|
208
208
|
config = self.get_config()
|
|
209
209
|
self.assertIsInstance(config.get("messages"), dict)
|
|
210
210
|
self.assertEqual(
|
|
211
|
-
config["messages"]["empty-heading"],
|
|
212
|
-
"Empty heading found
|
|
211
|
+
config["messages"]["empty-heading"]["error_name"],
|
|
212
|
+
"Empty heading found",
|
|
213
|
+
)
|
|
214
|
+
self.assertEqual(
|
|
215
|
+
config["messages"]["empty-heading"]["help_text"],
|
|
216
|
+
"Use meaningful text for screen reader users",
|
|
213
217
|
)
|
|
214
218
|
|
|
215
219
|
def test_custom_message(self):
|
|
216
220
|
class CustomMessageAccessibilityItem(AccessibilityItem):
|
|
217
221
|
# Override via class attribute
|
|
218
222
|
axe_messages = {
|
|
219
|
-
"empty-heading":
|
|
223
|
+
"empty-heading": {
|
|
224
|
+
"error_name": "Headings should not be empty!",
|
|
225
|
+
"help_text": "Use meaningful text!",
|
|
226
|
+
},
|
|
220
227
|
}
|
|
221
228
|
|
|
222
229
|
# Override via method
|
|
223
230
|
def get_axe_messages(self, request):
|
|
224
231
|
return {
|
|
225
232
|
**super().get_axe_messages(request),
|
|
226
|
-
"color-contrast-enhanced":
|
|
233
|
+
"color-contrast-enhanced": {
|
|
234
|
+
"error_name": "Insufficient colour contrast!",
|
|
235
|
+
"help_text": "Ensure contrast ratio of at least 4.5:1",
|
|
236
|
+
},
|
|
227
237
|
}
|
|
228
238
|
|
|
229
239
|
with hooks.register_temporarily(
|
|
@@ -234,8 +244,14 @@ class TestAccessibilityCheckerConfig(WagtailTestUtils, TestCase):
|
|
|
234
244
|
self.assertEqual(
|
|
235
245
|
config["messages"],
|
|
236
246
|
{
|
|
237
|
-
"empty-heading":
|
|
238
|
-
|
|
247
|
+
"empty-heading": {
|
|
248
|
+
"error_name": "Headings should not be empty!",
|
|
249
|
+
"help_text": "Use meaningful text!",
|
|
250
|
+
},
|
|
251
|
+
"color-contrast-enhanced": {
|
|
252
|
+
"error_name": "Insufficient colour contrast!",
|
|
253
|
+
"help_text": "Ensure contrast ratio of at least 4.5:1",
|
|
254
|
+
},
|
|
239
255
|
},
|
|
240
256
|
)
|
|
241
257
|
|
|
@@ -341,6 +357,77 @@ class TestAccessibilityCheckerConfig(WagtailTestUtils, TestCase):
|
|
|
341
357
|
},
|
|
342
358
|
)
|
|
343
359
|
|
|
360
|
+
def test_custom_rules_and_checks(self):
|
|
361
|
+
class CustomRulesAndChecksAccessibilityItem(AccessibilityItem):
|
|
362
|
+
# Override via class attribute
|
|
363
|
+
axe_custom_checks = [
|
|
364
|
+
{
|
|
365
|
+
"id": "check-image-alt-text",
|
|
366
|
+
"options": {"pattern": "\\.[a-z]{1,4}$|_"},
|
|
367
|
+
},
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
# Add via method
|
|
371
|
+
def get_axe_custom_rules(self, request):
|
|
372
|
+
return super().get_axe_custom_rules(request) + [
|
|
373
|
+
{
|
|
374
|
+
"id": "link-text-quality",
|
|
375
|
+
"impact": "serious",
|
|
376
|
+
"selector": "a",
|
|
377
|
+
"tags": ["best-practice"],
|
|
378
|
+
"any": ["check-link-text"],
|
|
379
|
+
"enabled": True,
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
|
|
383
|
+
def get_axe_custom_checks(self, request):
|
|
384
|
+
return super().get_axe_custom_checks(request) + [
|
|
385
|
+
{
|
|
386
|
+
"id": "check-link-text",
|
|
387
|
+
"options": {"pattern": "learn more$"},
|
|
388
|
+
}
|
|
389
|
+
]
|
|
390
|
+
|
|
391
|
+
with hooks.register_temporarily(
|
|
392
|
+
"construct_wagtail_userbar",
|
|
393
|
+
self.get_hook(CustomRulesAndChecksAccessibilityItem),
|
|
394
|
+
):
|
|
395
|
+
self.maxDiff = None
|
|
396
|
+
config = self.get_config()
|
|
397
|
+
self.assertEqual(
|
|
398
|
+
config["spec"],
|
|
399
|
+
{
|
|
400
|
+
"rules": [
|
|
401
|
+
{
|
|
402
|
+
"id": "alt-text-quality",
|
|
403
|
+
"impact": "serious",
|
|
404
|
+
"selector": "img[alt]",
|
|
405
|
+
"tags": ["best-practice"],
|
|
406
|
+
"any": ["check-image-alt-text"],
|
|
407
|
+
"enabled": True,
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"id": "link-text-quality",
|
|
411
|
+
"impact": "serious",
|
|
412
|
+
"selector": "a",
|
|
413
|
+
"tags": ["best-practice"],
|
|
414
|
+
"any": ["check-link-text"],
|
|
415
|
+
"enabled": True,
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
"checks": [
|
|
419
|
+
{
|
|
420
|
+
"id": "check-image-alt-text",
|
|
421
|
+
"options": {"pattern": "\\.[a-z]{1,4}$|_"},
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
"id": "check-link-text",
|
|
425
|
+
"options": {"pattern": "learn more$"},
|
|
426
|
+
},
|
|
427
|
+
],
|
|
428
|
+
},
|
|
429
|
+
)
|
|
430
|
+
|
|
344
431
|
|
|
345
432
|
class TestUserbarInPageServe(WagtailTestUtils, TestCase):
|
|
346
433
|
def setUp(self):
|
|
@@ -20,6 +20,7 @@ from wagtail.admin.mail import (
|
|
|
20
20
|
WorkflowStateApprovalEmailNotifier,
|
|
21
21
|
WorkflowStateRejectionEmailNotifier,
|
|
22
22
|
)
|
|
23
|
+
from wagtail.admin.staticfiles import versioned_static
|
|
23
24
|
from wagtail.admin.utils import (
|
|
24
25
|
get_admin_base_url,
|
|
25
26
|
get_latest_str,
|
|
@@ -293,11 +294,13 @@ class TestWorkflowsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
|
|
|
293
294
|
|
|
294
295
|
|
|
295
296
|
class TestWorkflowPermissions(WagtailTestUtils, TestCase):
|
|
297
|
+
url_name = "wagtailadmin_reports:workflow"
|
|
298
|
+
|
|
296
299
|
def setUp(self):
|
|
297
300
|
self.user = self.login()
|
|
298
301
|
|
|
299
302
|
def get(self, params={}):
|
|
300
|
-
return self.client.get(reverse(
|
|
303
|
+
return self.client.get(reverse(self.url_name), params)
|
|
301
304
|
|
|
302
305
|
def test_simple(self):
|
|
303
306
|
response = self.get()
|
|
@@ -340,6 +343,10 @@ class TestWorkflowPermissions(WagtailTestUtils, TestCase):
|
|
|
340
343
|
self.assertEqual(response.status_code, 200)
|
|
341
344
|
|
|
342
345
|
|
|
346
|
+
class TestWorkflowTaskPermissions(TestWorkflowPermissions):
|
|
347
|
+
url_name = "wagtailadmin_reports:workflow_tasks"
|
|
348
|
+
|
|
349
|
+
|
|
343
350
|
class TestWorkflowsCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
344
351
|
def setUp(self):
|
|
345
352
|
delete_existing_workflows()
|
|
@@ -1493,7 +1500,7 @@ class TestEditTaskView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
|
1493
1500
|
self.assertEqual(moderator_url_finder.get_edit_url(self.task), expected_url)
|
|
1494
1501
|
|
|
1495
1502
|
|
|
1496
|
-
class BasePageWorkflowTests(WagtailTestUtils, TestCase):
|
|
1503
|
+
class BasePageWorkflowTests(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
1497
1504
|
model_name = "page"
|
|
1498
1505
|
|
|
1499
1506
|
def setUp(self):
|
|
@@ -2502,11 +2509,53 @@ class TestApproveRejectPageWorkflow(BasePageWorkflowTests):
|
|
|
2502
2509
|
def test_workflow_dashboard_panel(self):
|
|
2503
2510
|
response = self.client.get(reverse("wagtailadmin_home"))
|
|
2504
2511
|
self.assertContains(response, "Awaiting your review")
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2512
|
+
soup = self.get_soup(response.content)
|
|
2513
|
+
# check that the workflow-action script is present with the correct data-activate attribute
|
|
2514
|
+
workflow_action_js = versioned_static("wagtailadmin/js/workflow-action.js")
|
|
2515
|
+
scripts = soup.select(f"script[src='{workflow_action_js}']")
|
|
2516
|
+
self.assertEqual(len(scripts), 1)
|
|
2517
|
+
script = scripts[0]
|
|
2518
|
+
self.assertIsNotNone(script)
|
|
2519
|
+
self.assertEqual(script.get("data-activate"), "dashboard")
|
|
2520
|
+
# Should no longer contain inline JS for activating the workflow actions
|
|
2521
|
+
self.assertNotContains(response, "ActivateWorkflowActionsForDashboard")
|
|
2522
|
+
|
|
2523
|
+
def test_workflow_action_script_included(self):
|
|
2524
|
+
response = self.client.get(self.get_url("edit"))
|
|
2525
|
+
self.assertEqual(response.status_code, 200)
|
|
2526
|
+
soup = self.get_soup(response.content)
|
|
2527
|
+
# check that the workflow-action script is present with the correct
|
|
2528
|
+
# data-activate and data-confirm-cancellation-url attributes
|
|
2529
|
+
workflow_action_js = versioned_static("wagtailadmin/js/workflow-action.js")
|
|
2530
|
+
scripts = soup.select(f"script[src='{workflow_action_js}']")
|
|
2531
|
+
self.assertEqual(len(scripts), 1)
|
|
2532
|
+
script = scripts[0]
|
|
2533
|
+
self.assertIsNotNone(script)
|
|
2534
|
+
self.assertEqual(script.get("data-activate"), "editor")
|
|
2535
|
+
self.assertEqual(
|
|
2536
|
+
script.get("data-confirm-cancellation-url"),
|
|
2537
|
+
self.get_url("confirm_workflow_cancellation"),
|
|
2509
2538
|
)
|
|
2539
|
+
# Should no longer contain inline JS for activating the workflow actions
|
|
2540
|
+
self.assertNotContains(response, "ActivateWorkflowActionsForEditView")
|
|
2541
|
+
|
|
2542
|
+
@override_settings(WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH=False)
|
|
2543
|
+
def test_workflow_action_script_included_without_cancel_confirmation(self):
|
|
2544
|
+
response = self.client.get(self.get_url("edit"))
|
|
2545
|
+
self.assertEqual(response.status_code, 200)
|
|
2546
|
+
soup = self.get_soup(response.content)
|
|
2547
|
+
# check that the workflow-action script is present with the correct data-activate attribute
|
|
2548
|
+
workflow_action_js = versioned_static("wagtailadmin/js/workflow-action.js")
|
|
2549
|
+
scripts = soup.select(f"script[src='{workflow_action_js}']")
|
|
2550
|
+
self.assertEqual(len(scripts), 1)
|
|
2551
|
+
script = scripts[0]
|
|
2552
|
+
self.assertIsNotNone(script)
|
|
2553
|
+
self.assertEqual(script.get("data-activate"), "editor")
|
|
2554
|
+
# data-confirm-cancellation-url attribute should not be present as
|
|
2555
|
+
# WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH is set to False
|
|
2556
|
+
self.assertIsNone(script.get("data-confirm-cancellation-url"))
|
|
2557
|
+
# Should no longer contain inline JS for activating the workflow actions
|
|
2558
|
+
self.assertNotContains(response, "ActivateWorkflowActionsForEditView")
|
|
2510
2559
|
|
|
2511
2560
|
def test_workflow_action_get(self):
|
|
2512
2561
|
"""
|
|
@@ -2892,6 +2941,11 @@ class TestApproveRejectSnippetWorkflowNotLockable(TestApproveRejectSnippetWorkfl
|
|
|
2892
2941
|
@freeze_time("2020-03-31 12:00:00")
|
|
2893
2942
|
class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
2894
2943
|
export_formats = ["xlsx", "csv"]
|
|
2944
|
+
workflow_url_name = "wagtailadmin_reports:workflow"
|
|
2945
|
+
workflow_tasks_url_name = "wagtailadmin_reports:workflow_tasks"
|
|
2946
|
+
header_buttons_parent_selector = "#w-slim-header-buttons"
|
|
2947
|
+
drilldown_selector = ".w-drilldown"
|
|
2948
|
+
extra_params = ""
|
|
2895
2949
|
|
|
2896
2950
|
def setUp(self):
|
|
2897
2951
|
super().setUp()
|
|
@@ -2901,6 +2955,15 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
2901
2955
|
self.post("submit", follow=True)
|
|
2902
2956
|
self.login(user=self.moderator)
|
|
2903
2957
|
|
|
2958
|
+
def assertBreadcrumbs(self, breadcrumbs, html):
|
|
2959
|
+
self.assertBreadcrumbsItemsRendered(breadcrumbs, html)
|
|
2960
|
+
|
|
2961
|
+
def assertPageTitle(self, soup, title):
|
|
2962
|
+
self.assertEqual(soup.select_one("title").text.strip(), title)
|
|
2963
|
+
|
|
2964
|
+
def get(self, url, params=None):
|
|
2965
|
+
return self.client.get(url, params)
|
|
2966
|
+
|
|
2904
2967
|
def setup_workflow_and_tasks(self):
|
|
2905
2968
|
self.workflow = Workflow.objects.create(name="test_workflow")
|
|
2906
2969
|
self.task_1 = GroupApprovalTask.objects.create(name="test_task_1")
|
|
@@ -2921,46 +2984,136 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
2921
2984
|
return response.getvalue().decode()
|
|
2922
2985
|
|
|
2923
2986
|
def test_workflow_report(self):
|
|
2924
|
-
response = self.
|
|
2987
|
+
response = self.get(reverse(self.workflow_url_name))
|
|
2925
2988
|
self.assertEqual(response.status_code, 200)
|
|
2926
2989
|
self.assertContains(response, "Hello world!")
|
|
2927
2990
|
self.assertContains(response, "test_workflow")
|
|
2928
2991
|
self.assertContains(response, "Sebastian Mitter")
|
|
2929
2992
|
self.assertContains(response, "March 31, 2020")
|
|
2993
|
+
self.assertBreadcrumbs(
|
|
2994
|
+
[{"url": "", "label": "Workflows"}],
|
|
2995
|
+
response.content,
|
|
2996
|
+
)
|
|
2997
|
+
soup = self.get_soup(response.content)
|
|
2998
|
+
by_task_link = soup.select_one(
|
|
2999
|
+
f"{self.header_buttons_parent_selector} .w-header-button"
|
|
3000
|
+
)
|
|
3001
|
+
self.assertIsNotNone(by_task_link)
|
|
3002
|
+
self.assertEqual(
|
|
3003
|
+
by_task_link.get("href"),
|
|
3004
|
+
reverse("wagtailadmin_reports:workflow_tasks"),
|
|
3005
|
+
)
|
|
3006
|
+
self.assertEqual(list(by_task_link.children)[-1].strip(), "By task")
|
|
3007
|
+
self.assertIsNone(soup.select_one(".w-active-filters"))
|
|
3008
|
+
self.assertPageTitle(soup, "Workflows - Wagtail")
|
|
2930
3009
|
|
|
2931
|
-
response = self.
|
|
3010
|
+
response = self.get(reverse(self.workflow_tasks_url_name))
|
|
2932
3011
|
self.assertEqual(response.status_code, 200)
|
|
2933
3012
|
self.assertContains(response, "Hello world!")
|
|
3013
|
+
self.assertBreadcrumbs(
|
|
3014
|
+
[{"url": "", "label": "Workflow tasks"}],
|
|
3015
|
+
response.content,
|
|
3016
|
+
)
|
|
3017
|
+
soup = self.get_soup(response.content)
|
|
3018
|
+
by_task_link = soup.select_one(
|
|
3019
|
+
f"{self.header_buttons_parent_selector} .w-header-button"
|
|
3020
|
+
)
|
|
3021
|
+
self.assertIsNotNone(by_task_link)
|
|
3022
|
+
self.assertEqual(
|
|
3023
|
+
by_task_link.get("href"),
|
|
3024
|
+
reverse("wagtailadmin_reports:workflow"),
|
|
3025
|
+
)
|
|
3026
|
+
self.assertEqual(list(by_task_link.children)[-1].strip(), "By workflow")
|
|
3027
|
+
self.assertIsNone(soup.select_one(".w-active-filters"))
|
|
3028
|
+
self.assertPageTitle(soup, "Workflow tasks - Wagtail")
|
|
2934
3029
|
|
|
2935
3030
|
def test_workflow_report_filtered(self):
|
|
2936
3031
|
# the moderator can review the task, so the workflow state should show up even when reports are filtered by reviewable
|
|
2937
|
-
response = self.
|
|
2938
|
-
reverse("wagtailadmin_reports:workflow"), {"reviewable": "true"}
|
|
2939
|
-
)
|
|
3032
|
+
response = self.get(reverse(self.workflow_url_name), {"reviewable": "true"})
|
|
2940
3033
|
self.assertEqual(response.status_code, 200)
|
|
2941
3034
|
self.assertContains(response, "Hello world!")
|
|
2942
3035
|
self.assertContains(response, "test_workflow")
|
|
2943
3036
|
self.assertContains(response, "Sebastian Mitter")
|
|
2944
3037
|
self.assertContains(response, "March 31, 2020")
|
|
2945
3038
|
|
|
2946
|
-
|
|
2947
|
-
|
|
3039
|
+
# Should render the export buttons inside the header "more" dropdown
|
|
3040
|
+
# with the filtered URL
|
|
3041
|
+
soup = self.get_soup(response.content)
|
|
3042
|
+
links = soup.select(f"{self.header_buttons_parent_selector} .w-dropdown a")
|
|
3043
|
+
unfiltered_url = reverse(self.workflow_url_name)
|
|
3044
|
+
filtered_url = f"{unfiltered_url}?reviewable=true{self.extra_params}"
|
|
3045
|
+
self.assertEqual(len(links), 2)
|
|
3046
|
+
self.assertEqual(
|
|
3047
|
+
[link.get("href") for link in links],
|
|
3048
|
+
[f"{filtered_url}&export=xlsx", f"{filtered_url}&export=csv"],
|
|
3049
|
+
)
|
|
3050
|
+
|
|
3051
|
+
# Should render the active filter pill
|
|
3052
|
+
active_filter = soup.select_one(".w-active-filters .w-pill__content")
|
|
3053
|
+
clear_button = soup.select_one(".w-active-filters .w-pill__remove")
|
|
3054
|
+
self.assertIsNotNone(active_filter)
|
|
3055
|
+
self.assertIsNotNone(clear_button)
|
|
3056
|
+
self.assertNotIn("reviewable", clear_button.attrs.get("data-w-swap-src-value"))
|
|
3057
|
+
self.assertEqual(clear_button.attrs.get("data-w-swap-reflect-value"), "true")
|
|
3058
|
+
|
|
3059
|
+
# Should render the filter inside the drilldown component
|
|
3060
|
+
inputs = soup.select(
|
|
3061
|
+
f"{self.drilldown_selector} input[name='reviewable'][type='radio']"
|
|
3062
|
+
)
|
|
3063
|
+
self.assertEqual(len(inputs), 2)
|
|
3064
|
+
self.assertEqual(inputs[0].get("value"), "")
|
|
3065
|
+
self.assertIsNone(inputs[0].get("checked"))
|
|
3066
|
+
self.assertEqual(inputs[1].get("value"), "true")
|
|
3067
|
+
self.assertEqual(inputs[1].get("checked"), "")
|
|
3068
|
+
|
|
3069
|
+
response = self.get(
|
|
3070
|
+
reverse(self.workflow_tasks_url_name),
|
|
3071
|
+
{"reviewable": "true"},
|
|
2948
3072
|
)
|
|
2949
3073
|
self.assertEqual(response.status_code, 200)
|
|
2950
3074
|
self.assertContains(response, "Hello world!")
|
|
2951
3075
|
|
|
3076
|
+
# Should render the export buttons inside the header "more" dropdown
|
|
3077
|
+
# with the filtered URL
|
|
3078
|
+
soup = self.get_soup(response.content)
|
|
3079
|
+
links = soup.select(f"{self.header_buttons_parent_selector} .w-dropdown a")
|
|
3080
|
+
unfiltered_url = reverse(self.workflow_tasks_url_name)
|
|
3081
|
+
filtered_url = f"{unfiltered_url}?reviewable=true{self.extra_params}"
|
|
3082
|
+
self.assertEqual(len(links), 2)
|
|
3083
|
+
self.assertEqual(
|
|
3084
|
+
[link.get("href") for link in links],
|
|
3085
|
+
[f"{filtered_url}&export=xlsx", f"{filtered_url}&export=csv"],
|
|
3086
|
+
)
|
|
3087
|
+
|
|
3088
|
+
# Should render the active filter pill
|
|
3089
|
+
active_filter = soup.select_one(".w-active-filters .w-pill__content")
|
|
3090
|
+
clear_button = soup.select_one(".w-active-filters .w-pill__remove")
|
|
3091
|
+
self.assertIsNotNone(active_filter)
|
|
3092
|
+
self.assertIsNotNone(clear_button)
|
|
3093
|
+
self.assertNotIn("reviewable", clear_button.attrs.get("data-w-swap-src-value"))
|
|
3094
|
+
self.assertEqual(clear_button.attrs.get("data-w-swap-reflect-value"), "true")
|
|
3095
|
+
|
|
3096
|
+
# Should render the filter inside the drilldown component
|
|
3097
|
+
inputs = soup.select(
|
|
3098
|
+
f"{self.drilldown_selector} input[name='reviewable'][type='radio']"
|
|
3099
|
+
)
|
|
3100
|
+
self.assertEqual(len(inputs), 2)
|
|
3101
|
+
self.assertEqual(inputs[0].get("value"), "")
|
|
3102
|
+
self.assertIsNone(inputs[0].get("checked"))
|
|
3103
|
+
self.assertEqual(inputs[1].get("value"), "true")
|
|
3104
|
+
self.assertEqual(inputs[1].get("checked"), "")
|
|
3105
|
+
|
|
2952
3106
|
# the submitter cannot review the task, so the workflow state shouldn't show up when reports are filtered by reviewable
|
|
2953
3107
|
self.login(self.submitter)
|
|
2954
|
-
response = self.
|
|
2955
|
-
reverse("wagtailadmin_reports:workflow"), {"reviewable": "true"}
|
|
2956
|
-
)
|
|
3108
|
+
response = self.get(reverse(self.workflow_url_name), {"reviewable": "true"})
|
|
2957
3109
|
self.assertEqual(response.status_code, 200)
|
|
2958
3110
|
self.assertNotContains(response, "Hello world!")
|
|
2959
3111
|
self.assertNotContains(response, "Sebastian Mitter")
|
|
2960
3112
|
self.assertNotContains(response, "March 31, 2020")
|
|
2961
3113
|
|
|
2962
|
-
response = self.
|
|
2963
|
-
reverse(
|
|
3114
|
+
response = self.get(
|
|
3115
|
+
reverse(self.workflow_tasks_url_name),
|
|
3116
|
+
{"reviewable": "true"},
|
|
2964
3117
|
)
|
|
2965
3118
|
self.assertEqual(response.status_code, 200)
|
|
2966
3119
|
self.assertNotContains(response, "Hello world!")
|
|
@@ -2968,8 +3121,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
2968
3121
|
def test_workflow_report_export(self):
|
|
2969
3122
|
for export_format in self.export_formats:
|
|
2970
3123
|
with self.subTest(export_format=export_format):
|
|
2971
|
-
response = self.
|
|
2972
|
-
reverse(
|
|
3124
|
+
response = self.get(
|
|
3125
|
+
reverse(self.workflow_url_name),
|
|
2973
3126
|
{"export": export_format},
|
|
2974
3127
|
)
|
|
2975
3128
|
content = self.get_file_content(response, export_format)
|
|
@@ -2979,8 +3132,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
2979
3132
|
self.assertIn("submitter", content)
|
|
2980
3133
|
self.assertIn("2020-03-31", content)
|
|
2981
3134
|
|
|
2982
|
-
response = self.
|
|
2983
|
-
reverse(
|
|
3135
|
+
response = self.get(
|
|
3136
|
+
reverse(self.workflow_tasks_url_name),
|
|
2984
3137
|
{"export": export_format},
|
|
2985
3138
|
)
|
|
2986
3139
|
content = self.get_file_content(response, export_format)
|
|
@@ -2992,8 +3145,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
2992
3145
|
with self.subTest(export_format=export_format):
|
|
2993
3146
|
# the moderator can review the task, so the workflow state should show up even when reports are filtered by reviewable
|
|
2994
3147
|
self.login(self.moderator)
|
|
2995
|
-
response = self.
|
|
2996
|
-
reverse(
|
|
3148
|
+
response = self.get(
|
|
3149
|
+
reverse(self.workflow_url_name),
|
|
2997
3150
|
{"reviewable": "true", "export": export_format},
|
|
2998
3151
|
)
|
|
2999
3152
|
content = self.get_file_content(response, export_format)
|
|
@@ -3003,8 +3156,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
3003
3156
|
self.assertIn("submitter", content)
|
|
3004
3157
|
self.assertIn("2020-03-31", content)
|
|
3005
3158
|
|
|
3006
|
-
response = self.
|
|
3007
|
-
reverse(
|
|
3159
|
+
response = self.get(
|
|
3160
|
+
reverse(self.workflow_tasks_url_name),
|
|
3008
3161
|
{"reviewable": "true", "export": export_format},
|
|
3009
3162
|
)
|
|
3010
3163
|
content = self.get_file_content(response, export_format)
|
|
@@ -3013,8 +3166,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
3013
3166
|
|
|
3014
3167
|
# the submitter cannot review the task, so the workflow state shouldn't show up when reports are filtered by reviewable
|
|
3015
3168
|
self.login(self.submitter)
|
|
3016
|
-
response = self.
|
|
3017
|
-
reverse(
|
|
3169
|
+
response = self.get(
|
|
3170
|
+
reverse(self.workflow_url_name),
|
|
3018
3171
|
{"reviewable": "true", "export": export_format},
|
|
3019
3172
|
)
|
|
3020
3173
|
content = self.get_file_content(response, export_format)
|
|
@@ -3023,8 +3176,8 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
3023
3176
|
self.assertNotIn("submitter", content)
|
|
3024
3177
|
self.assertNotIn("2020-03-31", content)
|
|
3025
3178
|
|
|
3026
|
-
response = self.
|
|
3027
|
-
reverse(
|
|
3179
|
+
response = self.get(
|
|
3180
|
+
reverse(self.workflow_tasks_url_name),
|
|
3028
3181
|
{"reviewable": "true", "export": export_format},
|
|
3029
3182
|
)
|
|
3030
3183
|
content = self.get_file_content(response, export_format)
|
|
@@ -3033,7 +3186,7 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
3033
3186
|
|
|
3034
3187
|
def test_workflow_report_deleted(self):
|
|
3035
3188
|
self.object.delete()
|
|
3036
|
-
response = self.
|
|
3189
|
+
response = self.get(reverse(self.workflow_url_name))
|
|
3037
3190
|
self.assertEqual(response.status_code, 200)
|
|
3038
3191
|
self.assertNotContains(response, "Hello world!")
|
|
3039
3192
|
# test_workflow is only rendered in the filter, not the results
|
|
@@ -3041,15 +3194,46 @@ class TestPageWorkflowReport(BasePageWorkflowTests):
|
|
|
3041
3194
|
self.assertNotContains(response, "Sebastian Mitter")
|
|
3042
3195
|
self.assertNotContains(response, "March 31, 2020")
|
|
3043
3196
|
|
|
3044
|
-
response = self.
|
|
3197
|
+
response = self.get(reverse(self.workflow_tasks_url_name))
|
|
3045
3198
|
self.assertEqual(response.status_code, 200)
|
|
3046
3199
|
self.assertNotContains(response, "Hello world!")
|
|
3047
3200
|
|
|
3048
3201
|
|
|
3202
|
+
class TestPageWorkflowReportResults(TestPageWorkflowReport):
|
|
3203
|
+
workflow_url_name = "wagtailadmin_reports:workflow_results"
|
|
3204
|
+
workflow_tasks_url_name = "wagtailadmin_reports:workflow_tasks_results"
|
|
3205
|
+
header_buttons_parent_selector = (
|
|
3206
|
+
'[data-controller="w-teleport"]'
|
|
3207
|
+
'[data-w-teleport-target-value="#w-slim-header-buttons"]'
|
|
3208
|
+
)
|
|
3209
|
+
drilldown_selector = (
|
|
3210
|
+
'[data-controller="w-teleport"]'
|
|
3211
|
+
'[data-w-teleport-target-value="#filters-drilldown"]'
|
|
3212
|
+
)
|
|
3213
|
+
extra_params = "&_w_filter_fragment=true"
|
|
3214
|
+
|
|
3215
|
+
def assertBreadcrumbs(self, breadcrumbs, html):
|
|
3216
|
+
self.assertBreadcrumbsNotRendered(html)
|
|
3217
|
+
|
|
3218
|
+
def assertPageTitle(self, soup, title):
|
|
3219
|
+
self.assertIsNone(soup.select_one("title"))
|
|
3220
|
+
|
|
3221
|
+
def get(self, url, params=None):
|
|
3222
|
+
params = params or {}
|
|
3223
|
+
params["_w_filter_fragment"] = "true"
|
|
3224
|
+
return super().get(url, params)
|
|
3225
|
+
|
|
3226
|
+
|
|
3049
3227
|
class TestSnippetWorkflowReport(TestPageWorkflowReport, BaseSnippetWorkflowTests):
|
|
3050
3228
|
pass
|
|
3051
3229
|
|
|
3052
3230
|
|
|
3231
|
+
class TestSnippetWorkflowReportResults(
|
|
3232
|
+
TestPageWorkflowReportResults, BaseSnippetWorkflowTests
|
|
3233
|
+
):
|
|
3234
|
+
pass
|
|
3235
|
+
|
|
3236
|
+
|
|
3053
3237
|
class TestNonLockableSnippetWorkflowReport(
|
|
3054
3238
|
TestPageWorkflowReport, BaseSnippetWorkflowTests
|
|
3055
3239
|
):
|
|
@@ -3060,6 +3244,12 @@ class TestNonLockableSnippetWorkflowReport(
|
|
|
3060
3244
|
model = ModeratedModel
|
|
3061
3245
|
|
|
3062
3246
|
|
|
3247
|
+
class TestNonLockableSnippetWorkflowReportResults(
|
|
3248
|
+
TestPageWorkflowReportResults, BaseSnippetWorkflowTests
|
|
3249
|
+
):
|
|
3250
|
+
model = ModeratedModel
|
|
3251
|
+
|
|
3252
|
+
|
|
3063
3253
|
class TestPageNotificationPreferences(BasePageWorkflowTests):
|
|
3064
3254
|
def setUp(self):
|
|
3065
3255
|
super().setUp()
|
|
@@ -3325,7 +3515,7 @@ class TestSnippetNotificationPreferencesHTML(TestSnippetNotificationPreferences)
|
|
|
3325
3515
|
pass
|
|
3326
3516
|
|
|
3327
3517
|
|
|
3328
|
-
class TestDisableViews(
|
|
3518
|
+
class TestDisableViews(BasePageWorkflowTests):
|
|
3329
3519
|
def test_disable_workflow(self):
|
|
3330
3520
|
"""Test that deactivating a workflow sets it to inactive and cancels in progress states"""
|
|
3331
3521
|
self.login(self.submitter)
|