wagtail 6.3.2__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/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/tests/test_models.py +7 -5
- wagtail/contrib/forms/tests/test_views.py +75 -0
- wagtail/contrib/frontend_cache/tasks.py +83 -0
- wagtail/contrib/frontend_cache/tests.py +47 -32
- 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 +6 -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 +3 -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/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/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.2.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/RECORD +289 -276
- 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.2.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
wagtail/tests/test_blocks.py
CHANGED
|
@@ -3,6 +3,7 @@ import collections
|
|
|
3
3
|
import copy
|
|
4
4
|
import json
|
|
5
5
|
import unittest
|
|
6
|
+
import unittest.mock
|
|
6
7
|
from decimal import Decimal
|
|
7
8
|
|
|
8
9
|
# non-standard import name for gettext_lazy, to prevent strings from being picked up for translation
|
|
@@ -57,6 +58,89 @@ class TestBlock(SimpleTestCase):
|
|
|
57
58
|
obj = object()
|
|
58
59
|
self.assertIs(blocks.Block().normalize(obj), obj)
|
|
59
60
|
|
|
61
|
+
def test_block_definition_registry(self):
|
|
62
|
+
"""Instantiating a Block should register it in the definition registry"""
|
|
63
|
+
block = blocks.Block()
|
|
64
|
+
self.assertIs(blocks.Block.definition_registry[block.definition_prefix], block)
|
|
65
|
+
|
|
66
|
+
def test_block_is_previewable(self):
|
|
67
|
+
class CustomContextBlock(blocks.Block):
|
|
68
|
+
def get_preview_context(self, value, parent_context=None):
|
|
69
|
+
return {"value": value, "foo": "bar"}
|
|
70
|
+
|
|
71
|
+
class CustomTemplateBlock(blocks.Block):
|
|
72
|
+
def get_preview_template(self, value=None, context=None):
|
|
73
|
+
return "foo.html"
|
|
74
|
+
|
|
75
|
+
class CustomValueBlock(blocks.Block):
|
|
76
|
+
def get_preview_value(self):
|
|
77
|
+
return "foo"
|
|
78
|
+
|
|
79
|
+
variants = {
|
|
80
|
+
"no_config": [
|
|
81
|
+
blocks.Block(),
|
|
82
|
+
],
|
|
83
|
+
"specific_template": [
|
|
84
|
+
blocks.Block(preview_template="foo.html"),
|
|
85
|
+
CustomTemplateBlock(),
|
|
86
|
+
],
|
|
87
|
+
"custom_value": [
|
|
88
|
+
blocks.Block(preview_value="foo"),
|
|
89
|
+
blocks.Block(default="bar"),
|
|
90
|
+
CustomContextBlock(),
|
|
91
|
+
CustomValueBlock(),
|
|
92
|
+
],
|
|
93
|
+
"specific_template_and_custom_value": [
|
|
94
|
+
blocks.Block(preview_template="foo.html", preview_value="bar"),
|
|
95
|
+
],
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# Test without a global template override
|
|
99
|
+
cases = [
|
|
100
|
+
# Unconfigured block should not be previewable
|
|
101
|
+
("no_config", False),
|
|
102
|
+
# Providing a specific preview template should make the block
|
|
103
|
+
# previewable even without a custom preview value, as the content
|
|
104
|
+
# may be hardcoded in the template
|
|
105
|
+
("specific_template", True),
|
|
106
|
+
# Providing a preview value without a custom template should not
|
|
107
|
+
# make the block previewable, as it may be missing the static assets
|
|
108
|
+
("custom_value", False),
|
|
109
|
+
# Providing both a preview template and value also makes the block
|
|
110
|
+
# previewable, this is the same as providing a custom template only
|
|
111
|
+
("specific_template_and_custom_value", True),
|
|
112
|
+
]
|
|
113
|
+
for variant, is_previewable in cases:
|
|
114
|
+
with self.subTest(variant=variant, custom_global_template=False):
|
|
115
|
+
for block in variants[variant]:
|
|
116
|
+
self.assertIs(block.is_previewable, is_previewable)
|
|
117
|
+
|
|
118
|
+
# Test with a global template override
|
|
119
|
+
with unittest.mock.patch(
|
|
120
|
+
"wagtail.blocks.base.template_is_overridden",
|
|
121
|
+
return_value=True,
|
|
122
|
+
):
|
|
123
|
+
cases = [
|
|
124
|
+
# Global template override + no preview value = not previewable,
|
|
125
|
+
# since it's unlikely the global template alone will provide a
|
|
126
|
+
# useful preview
|
|
127
|
+
("no_config", False),
|
|
128
|
+
# Unchanged – specific template always makes the block previewable
|
|
129
|
+
("specific_template", True),
|
|
130
|
+
# Global template override + custom preview value = previewable.
|
|
131
|
+
# We assume the global template will provide the static assets,
|
|
132
|
+
# and the custom value (and the block's real template via
|
|
133
|
+
# {% include_block %}) will provide the content.
|
|
134
|
+
("custom_value", True),
|
|
135
|
+
# Unchanged – providing both also makes the block previewable
|
|
136
|
+
("specific_template_and_custom_value", True),
|
|
137
|
+
]
|
|
138
|
+
for variant, is_previewable in cases:
|
|
139
|
+
with self.subTest(variant=variant, custom_global_template=True):
|
|
140
|
+
for block in variants[variant]:
|
|
141
|
+
del block.is_previewable # Clear cached_property
|
|
142
|
+
self.assertIs(block.is_previewable, is_previewable)
|
|
143
|
+
|
|
60
144
|
|
|
61
145
|
class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
62
146
|
def test_charfield_render(self):
|
|
@@ -65,6 +149,13 @@ class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
65
149
|
|
|
66
150
|
self.assertEqual(html, "Hello world!")
|
|
67
151
|
|
|
152
|
+
def test_block_definition_registry(self):
|
|
153
|
+
block = blocks.CharBlock(label="Test block")
|
|
154
|
+
registered_block = blocks.Block.definition_registry[block.definition_prefix]
|
|
155
|
+
self.assertIsInstance(registered_block, blocks.CharBlock)
|
|
156
|
+
self.assertEqual(registered_block.meta.label, "Test block")
|
|
157
|
+
self.assertIs(registered_block, block)
|
|
158
|
+
|
|
68
159
|
def test_charfield_render_with_template(self):
|
|
69
160
|
block = blocks.CharBlock(template="tests/blocks/heading_block.html")
|
|
70
161
|
html = block.render("Hello world!")
|
|
@@ -83,9 +174,12 @@ class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
83
174
|
js_args[2],
|
|
84
175
|
{
|
|
85
176
|
"label": "Test block",
|
|
177
|
+
"description": "Some helpful text",
|
|
86
178
|
"helpText": "Some helpful text",
|
|
87
179
|
"required": True,
|
|
88
180
|
"icon": "placeholder",
|
|
181
|
+
"blockDefId": block.definition_prefix,
|
|
182
|
+
"isPreviewable": block.is_previewable,
|
|
89
183
|
"classname": "w-field w-field--char_field w-field--text_input",
|
|
90
184
|
"showAddCommentButton": True,
|
|
91
185
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -172,7 +266,7 @@ class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
172
266
|
)
|
|
173
267
|
)
|
|
174
268
|
|
|
175
|
-
block = ChoiceBlock()
|
|
269
|
+
block = ChoiceBlock(description="A selection of two choices")
|
|
176
270
|
|
|
177
271
|
block.set_name("test_choiceblock")
|
|
178
272
|
js_args = FieldBlockAdapter().js_args(block)
|
|
@@ -190,8 +284,11 @@ class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
190
284
|
js_args[2],
|
|
191
285
|
{
|
|
192
286
|
"label": "Test choiceblock",
|
|
287
|
+
"description": "A selection of two choices",
|
|
193
288
|
"required": True,
|
|
194
289
|
"icon": "placeholder",
|
|
290
|
+
"blockDefId": block.definition_prefix,
|
|
291
|
+
"isPreviewable": block.is_previewable,
|
|
195
292
|
"classname": "w-field w-field--choice_field w-field--select",
|
|
196
293
|
"showAddCommentButton": True,
|
|
197
294
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -601,6 +698,9 @@ class TestRichTextBlock(TestCase):
|
|
|
601
698
|
"classname": "w-field w-field--char_field w-field--custom_rich_text_area",
|
|
602
699
|
"icon": "pilcrow",
|
|
603
700
|
"label": "Test richtextblock",
|
|
701
|
+
"description": "",
|
|
702
|
+
"blockDefId": block.definition_prefix,
|
|
703
|
+
"isPreviewable": block.is_previewable,
|
|
604
704
|
"required": True,
|
|
605
705
|
"showAddCommentButton": True,
|
|
606
706
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -621,8 +721,11 @@ class TestRichTextBlock(TestCase):
|
|
|
621
721
|
js_args[2],
|
|
622
722
|
{
|
|
623
723
|
"label": "Test richtextblock",
|
|
724
|
+
"description": "",
|
|
624
725
|
"required": True,
|
|
625
726
|
"icon": "pilcrow",
|
|
727
|
+
"blockDefId": block.definition_prefix,
|
|
728
|
+
"isPreviewable": block.is_previewable,
|
|
626
729
|
"classname": "w-field w-field--char_field w-field--draftail_rich_text_area",
|
|
627
730
|
"showAddCommentButton": False, # Draftail manages its own comments
|
|
628
731
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -643,8 +746,11 @@ class TestRichTextBlock(TestCase):
|
|
|
643
746
|
js_args[2],
|
|
644
747
|
{
|
|
645
748
|
"label": "Test richtextblock",
|
|
749
|
+
"description": "",
|
|
646
750
|
"required": True,
|
|
647
751
|
"icon": "pilcrow",
|
|
752
|
+
"blockDefId": block.definition_prefix,
|
|
753
|
+
"isPreviewable": block.is_previewable,
|
|
648
754
|
"classname": "w-field w-field--char_field w-field--draftail_rich_text_area",
|
|
649
755
|
"showAddCommentButton": False, # Draftail manages its own comments
|
|
650
756
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -758,8 +864,11 @@ class TestChoiceBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
758
864
|
js_args[2],
|
|
759
865
|
{
|
|
760
866
|
"label": "Test choiceblock",
|
|
867
|
+
"description": "",
|
|
761
868
|
"required": True,
|
|
762
869
|
"icon": "placeholder",
|
|
870
|
+
"blockDefId": block.definition_prefix,
|
|
871
|
+
"isPreviewable": block.is_previewable,
|
|
763
872
|
"classname": "w-field w-field--choice_field w-field--select",
|
|
764
873
|
"showAddCommentButton": True,
|
|
765
874
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -1159,8 +1268,11 @@ class TestMultipleChoiceBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
1159
1268
|
js_args[2],
|
|
1160
1269
|
{
|
|
1161
1270
|
"label": "Test choiceblock",
|
|
1271
|
+
"description": "",
|
|
1162
1272
|
"required": True,
|
|
1163
1273
|
"icon": "placeholder",
|
|
1274
|
+
"blockDefId": block.definition_prefix,
|
|
1275
|
+
"isPreviewable": block.is_previewable,
|
|
1164
1276
|
"classname": "w-field w-field--multiple_choice_field w-field--select_multiple",
|
|
1165
1277
|
"showAddCommentButton": True,
|
|
1166
1278
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -1595,8 +1707,11 @@ class TestRawHTMLBlock(unittest.TestCase):
|
|
|
1595
1707
|
js_args[2],
|
|
1596
1708
|
{
|
|
1597
1709
|
"label": "Test rawhtmlblock",
|
|
1710
|
+
"description": "",
|
|
1598
1711
|
"required": True,
|
|
1599
1712
|
"icon": "code",
|
|
1713
|
+
"blockDefId": block.definition_prefix,
|
|
1714
|
+
"isPreviewable": block.is_previewable,
|
|
1600
1715
|
"classname": "w-field w-field--char_field w-field--textarea",
|
|
1601
1716
|
"showAddCommentButton": True,
|
|
1602
1717
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -1937,8 +2052,11 @@ class TestStructBlock(SimpleTestCase):
|
|
|
1937
2052
|
js_args[2],
|
|
1938
2053
|
{
|
|
1939
2054
|
"label": "Test structblock",
|
|
2055
|
+
"description": "",
|
|
1940
2056
|
"required": False,
|
|
1941
2057
|
"icon": "placeholder",
|
|
2058
|
+
"blockDefId": block.definition_prefix,
|
|
2059
|
+
"isPreviewable": block.is_previewable,
|
|
1942
2060
|
"classname": "struct-block",
|
|
1943
2061
|
},
|
|
1944
2062
|
)
|
|
@@ -1966,8 +2084,11 @@ class TestStructBlock(SimpleTestCase):
|
|
|
1966
2084
|
js_args[2],
|
|
1967
2085
|
{
|
|
1968
2086
|
"label": "Test structblock",
|
|
2087
|
+
"description": "",
|
|
1969
2088
|
"required": False,
|
|
1970
2089
|
"icon": "placeholder",
|
|
2090
|
+
"blockDefId": block.definition_prefix,
|
|
2091
|
+
"isPreviewable": block.is_previewable,
|
|
1971
2092
|
"classname": "struct-block",
|
|
1972
2093
|
"formTemplate": "<div>Hello</div>",
|
|
1973
2094
|
},
|
|
@@ -1990,8 +2111,11 @@ class TestStructBlock(SimpleTestCase):
|
|
|
1990
2111
|
js_args[2],
|
|
1991
2112
|
{
|
|
1992
2113
|
"label": "Test structblock",
|
|
2114
|
+
"description": "",
|
|
1993
2115
|
"required": False,
|
|
1994
2116
|
"icon": "placeholder",
|
|
2117
|
+
"blockDefId": block.definition_prefix,
|
|
2118
|
+
"isPreviewable": block.is_previewable,
|
|
1995
2119
|
"classname": "struct-block",
|
|
1996
2120
|
"formTemplate": "<div>Hello</div>",
|
|
1997
2121
|
},
|
|
@@ -2023,8 +2147,11 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2023
2147
|
js_args[2],
|
|
2024
2148
|
{
|
|
2025
2149
|
"label": "Test structblock",
|
|
2150
|
+
"description": "Self-promotion is encouraged",
|
|
2026
2151
|
"required": False,
|
|
2027
2152
|
"icon": "placeholder",
|
|
2153
|
+
"blockDefId": block.definition_prefix,
|
|
2154
|
+
"isPreviewable": block.is_previewable,
|
|
2028
2155
|
"classname": "struct-block",
|
|
2029
2156
|
"helpIcon": (
|
|
2030
2157
|
'<svg class="icon icon-help default" aria-hidden="true">'
|
|
@@ -2048,8 +2175,11 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2048
2175
|
js_args[2],
|
|
2049
2176
|
{
|
|
2050
2177
|
"label": "Test structblock",
|
|
2178
|
+
"description": "Self-promotion is encouraged",
|
|
2051
2179
|
"required": False,
|
|
2052
2180
|
"icon": "placeholder",
|
|
2181
|
+
"blockDefId": block.definition_prefix,
|
|
2182
|
+
"isPreviewable": block.is_previewable,
|
|
2053
2183
|
"classname": "struct-block",
|
|
2054
2184
|
"helpIcon": (
|
|
2055
2185
|
'<svg class="icon icon-help default" aria-hidden="true">'
|
|
@@ -2677,7 +2807,10 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2677
2807
|
js_args[3],
|
|
2678
2808
|
{
|
|
2679
2809
|
"label": "Test listblock",
|
|
2810
|
+
"description": "",
|
|
2680
2811
|
"icon": "placeholder",
|
|
2812
|
+
"blockDefId": block.definition_prefix,
|
|
2813
|
+
"isPreviewable": block.is_previewable,
|
|
2681
2814
|
"classname": None,
|
|
2682
2815
|
"collapsed": False,
|
|
2683
2816
|
"strings": {
|
|
@@ -2685,6 +2818,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2685
2818
|
"DUPLICATE": "Duplicate",
|
|
2686
2819
|
"MOVE_DOWN": "Move down",
|
|
2687
2820
|
"MOVE_UP": "Move up",
|
|
2821
|
+
"DRAG": "Drag",
|
|
2688
2822
|
"ADD": "Add",
|
|
2689
2823
|
},
|
|
2690
2824
|
},
|
|
@@ -2707,7 +2841,10 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2707
2841
|
js_args[3],
|
|
2708
2842
|
{
|
|
2709
2843
|
"label": "Test listblock",
|
|
2844
|
+
"description": "",
|
|
2710
2845
|
"icon": "placeholder",
|
|
2846
|
+
"blockDefId": block.definition_prefix,
|
|
2847
|
+
"isPreviewable": block.is_previewable,
|
|
2711
2848
|
"classname": None,
|
|
2712
2849
|
"collapsed": False,
|
|
2713
2850
|
"minNum": 2,
|
|
@@ -2717,6 +2854,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2717
2854
|
"DUPLICATE": "Duplicate",
|
|
2718
2855
|
"MOVE_DOWN": "Move down",
|
|
2719
2856
|
"MOVE_UP": "Move up",
|
|
2857
|
+
"DRAG": "Drag",
|
|
2720
2858
|
"ADD": "Add",
|
|
2721
2859
|
},
|
|
2722
2860
|
},
|
|
@@ -2881,7 +3019,10 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2881
3019
|
js_args[3],
|
|
2882
3020
|
{
|
|
2883
3021
|
"label": "Test listblock",
|
|
3022
|
+
"description": "",
|
|
2884
3023
|
"icon": "placeholder",
|
|
3024
|
+
"blockDefId": block.definition_prefix,
|
|
3025
|
+
"isPreviewable": block.is_previewable,
|
|
2885
3026
|
"classname": "special-list-class",
|
|
2886
3027
|
"collapsed": False,
|
|
2887
3028
|
"strings": {
|
|
@@ -2889,6 +3030,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2889
3030
|
"DUPLICATE": "Duplicate",
|
|
2890
3031
|
"MOVE_DOWN": "Move down",
|
|
2891
3032
|
"MOVE_UP": "Move up",
|
|
3033
|
+
"DRAG": "Drag",
|
|
2892
3034
|
"ADD": "Add",
|
|
2893
3035
|
},
|
|
2894
3036
|
},
|
|
@@ -2914,7 +3056,10 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2914
3056
|
js_args[3],
|
|
2915
3057
|
{
|
|
2916
3058
|
"label": "Test listblock",
|
|
3059
|
+
"description": "",
|
|
2917
3060
|
"icon": "placeholder",
|
|
3061
|
+
"blockDefId": block.definition_prefix,
|
|
3062
|
+
"isPreviewable": block.is_previewable,
|
|
2918
3063
|
"classname": "custom-list-class",
|
|
2919
3064
|
"collapsed": False,
|
|
2920
3065
|
"strings": {
|
|
@@ -2922,6 +3067,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2922
3067
|
"DUPLICATE": "Duplicate",
|
|
2923
3068
|
"MOVE_DOWN": "Move down",
|
|
2924
3069
|
"MOVE_UP": "Move up",
|
|
3070
|
+
"DRAG": "Drag",
|
|
2925
3071
|
"ADD": "Add",
|
|
2926
3072
|
},
|
|
2927
3073
|
},
|
|
@@ -3551,7 +3697,10 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3551
3697
|
js_args[3],
|
|
3552
3698
|
{
|
|
3553
3699
|
"label": "Test streamblock",
|
|
3700
|
+
"description": "",
|
|
3554
3701
|
"icon": "placeholder",
|
|
3702
|
+
"blockDefId": block.definition_prefix,
|
|
3703
|
+
"isPreviewable": block.is_previewable,
|
|
3555
3704
|
"classname": None,
|
|
3556
3705
|
"collapsed": False,
|
|
3557
3706
|
"maxNum": None,
|
|
@@ -3563,6 +3712,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3563
3712
|
"DUPLICATE": "Duplicate",
|
|
3564
3713
|
"MOVE_DOWN": "Move down",
|
|
3565
3714
|
"MOVE_UP": "Move up",
|
|
3715
|
+
"DRAG": "Drag",
|
|
3566
3716
|
"ADD": "Add",
|
|
3567
3717
|
},
|
|
3568
3718
|
},
|
|
@@ -4277,7 +4427,10 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4277
4427
|
js_args[3],
|
|
4278
4428
|
{
|
|
4279
4429
|
"label": "Test streamblock",
|
|
4430
|
+
"description": "",
|
|
4280
4431
|
"icon": "placeholder",
|
|
4432
|
+
"blockDefId": block.definition_prefix,
|
|
4433
|
+
"isPreviewable": block.is_previewable,
|
|
4281
4434
|
"minNum": None,
|
|
4282
4435
|
"maxNum": None,
|
|
4283
4436
|
"blockCounts": {},
|
|
@@ -4289,6 +4442,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4289
4442
|
"DUPLICATE": "Duplicate",
|
|
4290
4443
|
"MOVE_DOWN": "Move down",
|
|
4291
4444
|
"MOVE_UP": "Move up",
|
|
4445
|
+
"DRAG": "Drag",
|
|
4292
4446
|
"ADD": "Add",
|
|
4293
4447
|
},
|
|
4294
4448
|
},
|
|
@@ -4379,7 +4533,10 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4379
4533
|
js_args[3],
|
|
4380
4534
|
{
|
|
4381
4535
|
"label": "Test streamblock",
|
|
4536
|
+
"description": "",
|
|
4382
4537
|
"icon": "placeholder",
|
|
4538
|
+
"blockDefId": block.definition_prefix,
|
|
4539
|
+
"isPreviewable": block.is_previewable,
|
|
4383
4540
|
"minNum": None,
|
|
4384
4541
|
"maxNum": None,
|
|
4385
4542
|
"blockCounts": {},
|
|
@@ -4391,6 +4548,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4391
4548
|
"DUPLICATE": "Duplicate",
|
|
4392
4549
|
"MOVE_DOWN": "Move down",
|
|
4393
4550
|
"MOVE_UP": "Move up",
|
|
4551
|
+
"DRAG": "Drag",
|
|
4394
4552
|
"ADD": "Add",
|
|
4395
4553
|
},
|
|
4396
4554
|
},
|
|
@@ -4710,7 +4868,9 @@ class TestPageChooserBlock(TestCase):
|
|
|
4710
4868
|
def test_adapt(self):
|
|
4711
4869
|
from wagtail.admin.widgets.chooser import AdminPageChooser
|
|
4712
4870
|
|
|
4713
|
-
block = blocks.PageChooserBlock(
|
|
4871
|
+
block = blocks.PageChooserBlock(
|
|
4872
|
+
help_text="pick a page, any page", description="A featured page"
|
|
4873
|
+
)
|
|
4714
4874
|
|
|
4715
4875
|
block.set_name("test_pagechooserblock")
|
|
4716
4876
|
js_args = FieldBlockAdapter().js_args(block)
|
|
@@ -4723,8 +4883,11 @@ class TestPageChooserBlock(TestCase):
|
|
|
4723
4883
|
js_args[2],
|
|
4724
4884
|
{
|
|
4725
4885
|
"label": "Test pagechooserblock",
|
|
4886
|
+
"description": "A featured page",
|
|
4726
4887
|
"required": True,
|
|
4727
4888
|
"icon": "doc-empty-inverse",
|
|
4889
|
+
"blockDefId": block.definition_prefix,
|
|
4890
|
+
"isPreviewable": block.is_previewable,
|
|
4728
4891
|
"helpText": "pick a page, any page",
|
|
4729
4892
|
"classname": "w-field w-field--model_choice_field w-field--admin_page_chooser",
|
|
4730
4893
|
"showAddCommentButton": True,
|
|
@@ -4928,7 +5091,10 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
4928
5091
|
{
|
|
4929
5092
|
"text": "Latest posts - This block doesn't need to be configured, it will be displayed automatically",
|
|
4930
5093
|
"icon": "placeholder",
|
|
5094
|
+
"blockDefId": block.definition_prefix,
|
|
5095
|
+
"isPreviewable": block.is_previewable,
|
|
4931
5096
|
"label": "Posts static block",
|
|
5097
|
+
"description": "",
|
|
4932
5098
|
},
|
|
4933
5099
|
)
|
|
4934
5100
|
|
|
@@ -4949,7 +5115,10 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
4949
5115
|
{
|
|
4950
5116
|
"text": "Latest posts - This block doesn't need to be configured, it will be displayed automatically",
|
|
4951
5117
|
"icon": "placeholder",
|
|
5118
|
+
"blockDefId": block.definition_prefix,
|
|
5119
|
+
"isPreviewable": block.is_previewable,
|
|
4952
5120
|
"label": "Posts static block",
|
|
5121
|
+
"description": "",
|
|
4953
5122
|
},
|
|
4954
5123
|
)
|
|
4955
5124
|
|
|
@@ -4969,7 +5138,10 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
4969
5138
|
{
|
|
4970
5139
|
"text": "Latest posts: this block has no options.",
|
|
4971
5140
|
"icon": "placeholder",
|
|
5141
|
+
"blockDefId": block.definition_prefix,
|
|
5142
|
+
"isPreviewable": block.is_previewable,
|
|
4972
5143
|
"label": "Latest posts",
|
|
5144
|
+
"description": "",
|
|
4973
5145
|
},
|
|
4974
5146
|
)
|
|
4975
5147
|
|
|
@@ -4990,7 +5162,10 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
4990
5162
|
{
|
|
4991
5163
|
"text": "Posts static block: this block has no options.",
|
|
4992
5164
|
"icon": "placeholder",
|
|
5165
|
+
"blockDefId": block.definition_prefix,
|
|
5166
|
+
"isPreviewable": block.is_previewable,
|
|
4993
5167
|
"label": "Posts static block",
|
|
5168
|
+
"description": "",
|
|
4994
5169
|
},
|
|
4995
5170
|
)
|
|
4996
5171
|
|
|
@@ -5011,7 +5186,10 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
5011
5186
|
{
|
|
5012
5187
|
"html": "<b>Latest posts</b> - This block doesn't need to be configured, it will be displayed automatically",
|
|
5013
5188
|
"icon": "placeholder",
|
|
5189
|
+
"blockDefId": block.definition_prefix,
|
|
5190
|
+
"isPreviewable": block.is_previewable,
|
|
5014
5191
|
"label": "Posts static block",
|
|
5192
|
+
"description": "",
|
|
5015
5193
|
},
|
|
5016
5194
|
)
|
|
5017
5195
|
|
|
@@ -5063,8 +5241,11 @@ class TestDateBlock(TestCase):
|
|
|
5063
5241
|
js_args[2],
|
|
5064
5242
|
{
|
|
5065
5243
|
"label": "Test dateblock",
|
|
5244
|
+
"description": "",
|
|
5066
5245
|
"required": True,
|
|
5067
5246
|
"icon": "date",
|
|
5247
|
+
"blockDefId": block.definition_prefix,
|
|
5248
|
+
"isPreviewable": block.is_previewable,
|
|
5068
5249
|
"classname": "w-field w-field--date_field w-field--admin_date_input",
|
|
5069
5250
|
"showAddCommentButton": True,
|
|
5070
5251
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -5096,8 +5277,11 @@ class TestTimeBlock(TestCase):
|
|
|
5096
5277
|
js_args[2],
|
|
5097
5278
|
{
|
|
5098
5279
|
"label": "Test timeblock",
|
|
5280
|
+
"description": "",
|
|
5099
5281
|
"required": True,
|
|
5100
5282
|
"icon": "time",
|
|
5283
|
+
"blockDefId": block.definition_prefix,
|
|
5284
|
+
"isPreviewable": block.is_previewable,
|
|
5101
5285
|
"classname": "w-field w-field--time_field w-field--admin_time_input",
|
|
5102
5286
|
"showAddCommentButton": True,
|
|
5103
5287
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
|
@@ -5129,8 +5313,11 @@ class TestDateTimeBlock(TestCase):
|
|
|
5129
5313
|
js_args[2],
|
|
5130
5314
|
{
|
|
5131
5315
|
"label": "Test datetimeblock",
|
|
5316
|
+
"description": "",
|
|
5132
5317
|
"required": True,
|
|
5133
5318
|
"icon": "date",
|
|
5319
|
+
"blockDefId": block.definition_prefix,
|
|
5320
|
+
"isPreviewable": block.is_previewable,
|
|
5134
5321
|
"classname": "w-field w-field--date_time_field w-field--admin_date_time_input",
|
|
5135
5322
|
"showAddCommentButton": True,
|
|
5136
5323
|
"strings": {"ADD_COMMENT": "Add Comment"},
|
wagtail/tests/test_hooks.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
from
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
3
|
+
from django.contrib.sessions.middleware import SessionMiddleware
|
|
4
|
+
from django.http import HttpResponse
|
|
5
|
+
from django.test import RequestFactory, TestCase
|
|
2
6
|
|
|
3
7
|
from wagtail import hooks
|
|
8
|
+
from wagtail.models import Page, PageViewRestriction
|
|
4
9
|
from wagtail.test.utils import WagtailTestUtils
|
|
10
|
+
from wagtail.views import serve, serve_chain
|
|
11
|
+
from wagtail.wagtail_hooks import check_view_restrictions
|
|
5
12
|
|
|
6
13
|
|
|
7
14
|
def test_hook():
|
|
@@ -34,3 +41,161 @@ class TestLoginView(WagtailTestUtils, TestCase):
|
|
|
34
41
|
with self.register_hook("test_hook_name", after_hook, order=1):
|
|
35
42
|
hook_fns = hooks.get_hooks("test_hook_name")
|
|
36
43
|
self.assertEqual(hook_fns, [test_hook, after_hook])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TestServeHooks(WagtailTestUtils, TestCase):
|
|
47
|
+
fixtures = ["test.json"]
|
|
48
|
+
|
|
49
|
+
def setUp(self):
|
|
50
|
+
self.page = Page.objects.get(id=2)
|
|
51
|
+
self.request = RequestFactory().get("/test/")
|
|
52
|
+
middleware = SessionMiddleware(lambda x: None)
|
|
53
|
+
middleware.process_request(self.request)
|
|
54
|
+
self.request.session.save()
|
|
55
|
+
|
|
56
|
+
def test_serve_chain_order(self):
|
|
57
|
+
order_calls = []
|
|
58
|
+
|
|
59
|
+
def hook_1(next_fn):
|
|
60
|
+
def wrapper(page, request, *args, **kwargs):
|
|
61
|
+
order_calls.append(1)
|
|
62
|
+
return next_fn(page, request, *args, **kwargs)
|
|
63
|
+
|
|
64
|
+
return wrapper
|
|
65
|
+
|
|
66
|
+
def hook_2(next_fn):
|
|
67
|
+
def wrapper(page, request, *args, **kwargs):
|
|
68
|
+
order_calls.append(2)
|
|
69
|
+
return next_fn(page, request, *args, **kwargs)
|
|
70
|
+
|
|
71
|
+
return wrapper
|
|
72
|
+
|
|
73
|
+
def hook_3(next_fn):
|
|
74
|
+
def wrapper(page, request, *args, **kwargs):
|
|
75
|
+
order_calls.append(3)
|
|
76
|
+
return next_fn(page, request, *args, **kwargs)
|
|
77
|
+
|
|
78
|
+
return wrapper
|
|
79
|
+
|
|
80
|
+
with self.register_hook("on_serve_page", hook_1):
|
|
81
|
+
with self.register_hook("on_serve_page", hook_2):
|
|
82
|
+
with self.register_hook("on_serve_page", hook_3):
|
|
83
|
+
serve(self.request, self.page.url)
|
|
84
|
+
|
|
85
|
+
self.assertEqual(order_calls, [1, 2, 3])
|
|
86
|
+
|
|
87
|
+
def test_serve_chain_modification(self):
|
|
88
|
+
def hook_modifier(next_fn):
|
|
89
|
+
def wrapper(page, request, *args, **kwargs):
|
|
90
|
+
response = next_fn(page, request, *args, **kwargs)
|
|
91
|
+
response.content = b"Modified content"
|
|
92
|
+
return response
|
|
93
|
+
|
|
94
|
+
return wrapper
|
|
95
|
+
|
|
96
|
+
with self.register_hook("on_serve_page", hook_modifier):
|
|
97
|
+
response = serve(self.request, self.page.url)
|
|
98
|
+
self.assertEqual(response.content, b"Modified content")
|
|
99
|
+
|
|
100
|
+
def test_serve_chain_halt_execution(self):
|
|
101
|
+
def hook_halt(next_fn):
|
|
102
|
+
def wrapper(page, request, *args, **kwargs):
|
|
103
|
+
return HttpResponse("Halted")
|
|
104
|
+
|
|
105
|
+
return wrapper
|
|
106
|
+
|
|
107
|
+
with self.register_hook("on_serve_page", hook_halt):
|
|
108
|
+
response = serve(self.request, self.page.url)
|
|
109
|
+
self.assertEqual(response.content, b"Halted")
|
|
110
|
+
|
|
111
|
+
def test_serve_chain_view_restriction(self):
|
|
112
|
+
restriction = PageViewRestriction.objects.create(
|
|
113
|
+
page=self.page,
|
|
114
|
+
restriction_type=PageViewRestriction.PASSWORD,
|
|
115
|
+
password="password",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
with self.register_hook("on_serve_page", check_view_restrictions):
|
|
119
|
+
response = self.client.get(self.page.url)
|
|
120
|
+
self.assertEqual(response.status_code, 200)
|
|
121
|
+
self.assertTemplateUsed(response, "wagtailcore/password_required.html")
|
|
122
|
+
|
|
123
|
+
restriction.delete()
|
|
124
|
+
|
|
125
|
+
def test_serve_always_called_last(self):
|
|
126
|
+
hook_calls = []
|
|
127
|
+
serve_called = []
|
|
128
|
+
|
|
129
|
+
def hook_1(next_fn):
|
|
130
|
+
def wrapper(page, request, *args, **kwargs):
|
|
131
|
+
hook_calls.append(1)
|
|
132
|
+
return next_fn(page, request, *args, **kwargs)
|
|
133
|
+
|
|
134
|
+
return wrapper
|
|
135
|
+
|
|
136
|
+
def hook_2(next_fn):
|
|
137
|
+
def wrapper(page, request, *args, **kwargs):
|
|
138
|
+
hook_calls.append(2)
|
|
139
|
+
return next_fn(page, request, *args, **kwargs)
|
|
140
|
+
|
|
141
|
+
return wrapper
|
|
142
|
+
|
|
143
|
+
def hook_3(next_fn):
|
|
144
|
+
def wrapper(page, request, *args, **kwargs):
|
|
145
|
+
hook_calls.append(3)
|
|
146
|
+
return next_fn(page, request, *args, **kwargs)
|
|
147
|
+
|
|
148
|
+
return wrapper
|
|
149
|
+
|
|
150
|
+
original_serve_chain = serve_chain
|
|
151
|
+
|
|
152
|
+
def mock_serve_chain(page, request, *args, **kwargs):
|
|
153
|
+
serve_called.append(True)
|
|
154
|
+
return original_serve_chain(page, request, *args, **kwargs)
|
|
155
|
+
|
|
156
|
+
with mock.patch("wagtail.views.serve_chain", mock_serve_chain):
|
|
157
|
+
with self.register_hook("on_serve_page", hook_1):
|
|
158
|
+
with self.register_hook("on_serve_page", hook_2):
|
|
159
|
+
with self.register_hook("on_serve_page", hook_3):
|
|
160
|
+
serve(self.request, self.page.url)
|
|
161
|
+
|
|
162
|
+
self.assertEqual(hook_calls, [1, 2, 3])
|
|
163
|
+
self.assertEqual(len(serve_called), 1)
|
|
164
|
+
self.assertTrue(serve_called[0])
|
|
165
|
+
|
|
166
|
+
def test_check_view_restrictions_receives_correct_parameters(self):
|
|
167
|
+
received_params = []
|
|
168
|
+
|
|
169
|
+
def hook_spy(next_fn):
|
|
170
|
+
def wrapper(page, request, *args, **kwargs):
|
|
171
|
+
received_params.append(
|
|
172
|
+
{"page": page, "request": request, "args": args, "kwargs": kwargs}
|
|
173
|
+
)
|
|
174
|
+
return next_fn(page, request, *args, **kwargs)
|
|
175
|
+
|
|
176
|
+
return wrapper
|
|
177
|
+
|
|
178
|
+
self.assertIsNotNone(self.page, "Test page should not be None")
|
|
179
|
+
self.assertIsNotNone(self.request, "Test request should not be None")
|
|
180
|
+
|
|
181
|
+
with self.register_hook("on_serve_page", hook_spy):
|
|
182
|
+
route_result = Page.route_for_request(self.request, self.page.url)
|
|
183
|
+
|
|
184
|
+
self.assertIsNotNone(route_result, "route_result should not be None")
|
|
185
|
+
|
|
186
|
+
if route_result:
|
|
187
|
+
page, args, kwargs = route_result
|
|
188
|
+
serve(self.request, self.page.url)
|
|
189
|
+
|
|
190
|
+
self.assertEqual(len(received_params), 1)
|
|
191
|
+
|
|
192
|
+
params = received_params[0]
|
|
193
|
+
|
|
194
|
+
self.assertIsNotNone(params["page"], "Hook received None as page")
|
|
195
|
+
self.assertIsNotNone(params["request"], "Hook received None as request")
|
|
196
|
+
|
|
197
|
+
self.assertEqual(params["page"], self.page)
|
|
198
|
+
self.assertEqual(params["request"], self.request)
|
|
199
|
+
|
|
200
|
+
self.assertEqual(params["args"], ([], {}))
|
|
201
|
+
self.assertEqual(params["kwargs"], {})
|