wagtail 7.2.1__py3-none-any.whl → 7.3rc1__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 +4 -2
- wagtail/admin/action_menu.py +4 -1
- wagtail/admin/api/actions/convert_alias.py +2 -2
- wagtail/admin/api/actions/copy.py +2 -2
- wagtail/admin/api/actions/copy_for_translation.py +2 -2
- wagtail/admin/api/actions/create_alias.py +2 -2
- wagtail/admin/api/actions/delete.py +1 -1
- wagtail/admin/api/actions/move.py +1 -1
- wagtail/admin/api/actions/publish.py +2 -2
- wagtail/admin/api/actions/revert_to_page_revision.py +2 -2
- wagtail/admin/api/actions/unpublish.py +1 -1
- wagtail/admin/api/filters.py +2 -2
- wagtail/admin/compare.py +22 -0
- wagtail/admin/forms/account.py +52 -1
- wagtail/admin/forms/comments.py +53 -0
- wagtail/admin/forms/models.py +36 -0
- wagtail/admin/forms/pages.py +7 -0
- wagtail/admin/forms/workflows.py +5 -2
- wagtail/admin/icons.py +4 -3
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +35 -0
- wagtail/admin/locale/en/LC_MESSAGES/django.po +262 -234
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +72 -43
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +566 -6
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +40 -2
- wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/django.po +2 -2
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +330 -15
- wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +3 -2
- wagtail/admin/panels/comment_panel.py +1 -51
- wagtail/admin/panels/title_field_panel.py +3 -1
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.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/core.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.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/wagtailadmin.js +1 -1
- wagtail/admin/templates/wagtailadmin/base.html +1 -1
- wagtail/admin/templates/wagtailadmin/generic/edit_partials.html +100 -0
- wagtail/admin/templates/wagtailadmin/generic/form.html +26 -5
- wagtail/admin/templates/wagtailadmin/generic/includes/_loaded_revision_inputs.html +3 -0
- wagtail/admin/templates/wagtailadmin/generic/listing_results.html +1 -17
- wagtail/admin/templates/wagtailadmin/pages/create.html +14 -4
- wagtail/admin/templates/wagtailadmin/pages/edit.html +16 -3
- wagtail/admin/templates/wagtailadmin/pages/edit_partials.html +31 -0
- wagtail/admin/templates/wagtailadmin/pages/index_results.html +1 -9
- wagtail/admin/templates/wagtailadmin/shared/autosave/indicator.html +36 -0
- wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +19 -3
- wagtail/admin/templates/wagtailadmin/shared/headers/_actions.html +5 -0
- wagtail/admin/templates/wagtailadmin/shared/headers/_history_icon_link.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +8 -9
- wagtail/admin/templates/wagtailadmin/shared/listing/filter_partials.html +19 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +3 -3
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/side_panel.html +3 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +18 -6
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +11 -4
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/workflow.html +22 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panels.html +1 -2
- wagtail/admin/templates/wagtailadmin/shared/unsaved_changes_warning.html +20 -20
- wagtail/admin/templates/wagtailadmin/userbar/base.html +2 -0
- wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +1 -1
- wagtail/admin/templatetags/wagtailadmin_tags.py +6 -14
- wagtail/admin/tests/pages/test_create_page.py +298 -1
- wagtail/admin/tests/pages/test_custom_listing.py +48 -2
- wagtail/admin/tests/pages/test_edit_page.py +721 -7
- wagtail/admin/tests/pages/test_explorer_view.py +9 -5
- wagtail/admin/tests/pages/test_page_search.py +15 -0
- wagtail/admin/tests/pages/test_revisions.py +4 -0
- wagtail/admin/tests/test_account_management.py +88 -2
- wagtail/admin/tests/test_collections_views.py +15 -15
- wagtail/admin/tests/test_compare.py +34 -0
- wagtail/admin/tests/test_editing_sessions.py +230 -8
- wagtail/admin/tests/test_forms.py +192 -1
- wagtail/admin/tests/test_icon_sprite.py +22 -2
- wagtail/admin/tests/test_page_chooser.py +13 -13
- wagtail/admin/tests/test_reports_views.py +4 -1
- wagtail/admin/tests/test_userbar.py +69 -5
- wagtail/admin/tests/test_views_generic.py +5 -5
- wagtail/admin/tests/test_workflows.py +14 -12
- wagtail/admin/tests/viewsets/test_model_viewset.py +13 -0
- wagtail/admin/ui/autosave.py +5 -0
- wagtail/admin/ui/editing_sessions.py +3 -0
- wagtail/admin/ui/side_panels.py +19 -20
- wagtail/admin/userbar.py +48 -27
- wagtail/admin/views/bulk_action/dispatcher.py +2 -2
- wagtail/admin/views/chooser.py +6 -6
- wagtail/admin/views/editing_sessions.py +20 -7
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/chooser.py +5 -5
- wagtail/admin/views/generic/mixins.py +143 -26
- wagtail/admin/views/generic/models.py +157 -27
- wagtail/admin/views/generic/ordering.py +1 -1
- wagtail/admin/views/generic/preview.py +4 -4
- wagtail/admin/views/home.py +3 -1
- wagtail/admin/views/pages/create.py +77 -29
- wagtail/admin/views/pages/edit.py +160 -34
- wagtail/admin/views/pages/preview.py +4 -4
- wagtail/admin/views/pages/revisions.py +3 -0
- wagtail/admin/views/pages/search.py +4 -4
- wagtail/admin/views/pages/usage.py +2 -2
- wagtail/admin/views/tags.py +2 -2
- wagtail/admin/views/workflows.py +73 -54
- wagtail/admin/viewsets/model.py +34 -8
- wagtail/admin/widgets/button.py +11 -4
- wagtail/admin/widgets/chooser.py +6 -4
- wagtail/admin/widgets/slug.py +1 -1
- wagtail/api/v2/filters.py +27 -21
- wagtail/api/v2/pagination.py +4 -4
- wagtail/api/v2/views.py +7 -7
- wagtail/blocks/list_block.py +0 -8
- wagtail/blocks/migrations/migrate_operation.py +8 -1
- wagtail/blocks/stream_block.py +2 -10
- wagtail/blocks/struct_block.py +192 -12
- wagtail/compat.py +2 -2
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +40 -2
- wagtail/contrib/frontend_cache/backends/azure.py +6 -6
- wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
- wagtail/contrib/frontend_cache/utils.py +1 -1
- wagtail/contrib/redirects/forms.py +1 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +14 -14
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +15 -2
- wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +16 -3
- wagtail/contrib/redirects/middleware.py +11 -7
- wagtail/contrib/redirects/models.py +17 -1
- wagtail/contrib/redirects/tests/test_import_admin_views.py +3 -3
- wagtail/contrib/redirects/tests/test_redirects.py +56 -8
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +6 -6
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +43 -2
- wagtail/contrib/search_promotions/tests.py +1 -1
- wagtail/contrib/search_promotions/views/settings.py +24 -25
- wagtail/contrib/settings/jinja2tags.py +2 -2
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/settings/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/it/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.po +3 -2
- wagtail/contrib/settings/tests/generic/test_admin.py +118 -2
- wagtail/contrib/settings/tests/site_specific/test_admin.py +78 -15
- wagtail/contrib/settings/tests/site_specific/test_model.py +2 -2
- wagtail/contrib/settings/views.py +7 -0
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.po +5 -2
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/styleguide/tests.py +2 -0
- wagtail/contrib/styleguide/views.py +4 -5
- wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +5 -2
- wagtail/contrib/typed_table_block/blocks.py +37 -0
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.po +4 -3
- wagtail/contrib/typed_table_block/tests.py +108 -0
- wagtail/coreutils.py +4 -4
- wagtail/documents/__init__.py +4 -4
- wagtail/documents/locale/en/LC_MESSAGES/django.po +15 -15
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +32 -2
- wagtail/documents/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sv/LC_MESSAGES/django.po +32 -4
- wagtail/documents/models.py +1 -1
- wagtail/documents/tests/test_admin_views.py +19 -4
- wagtail/documents/tests/test_search.py +0 -2
- wagtail/documents/tests/test_views.py +6 -4
- wagtail/documents/views/bulk_actions/add_tags.py +1 -1
- wagtail/embeds/finders/facebook.py +3 -3
- wagtail/embeds/finders/instagram.py +3 -3
- wagtail/embeds/finders/oembed.py +7 -2
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/oembed_providers.py +8 -0
- wagtail/embeds/tests/test_embeds.py +35 -0
- wagtail/images/__init__.py +4 -4
- wagtail/images/admin_urls.py +3 -3
- wagtail/images/blocks.py +1 -1
- wagtail/images/formats.py +2 -2
- wagtail/images/image_operations.py +2 -2
- wagtail/images/locale/en/LC_MESSAGES/django.po +44 -40
- wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/it/LC_MESSAGES/django.po +50 -4
- wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nl/LC_MESSAGES/django.po +3 -3
- wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sv/LC_MESSAGES/django.po +49 -6
- wagtail/images/models.py +11 -10
- wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
- wagtail/images/templates/wagtailimages/images/url_generator.html +17 -38
- wagtail/images/templates/wagtailimages/images/url_generator_output.html +28 -0
- wagtail/images/templatetags/wagtailimages_tags.py +4 -4
- wagtail/images/tests/test_admin_views.py +432 -59
- wagtail/images/tests/test_image_operations.py +2 -2
- wagtail/images/tests/test_models.py +0 -2
- wagtail/images/views/bulk_actions/add_tags.py +1 -1
- wagtail/images/views/images.py +72 -39
- wagtail/locale/en/LC_MESSAGES/django.po +103 -105
- wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/it/LC_MESSAGES/django.po +105 -2
- wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sv/LC_MESSAGES/django.po +95 -12
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/it/LC_MESSAGES/django.po +13 -2
- wagtail/locales/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/sv/LC_MESSAGES/django.po +4 -3
- wagtail/locales/tests.py +5 -5
- wagtail/models/i18n.py +4 -6
- wagtail/models/media.py +18 -0
- wagtail/models/pages.py +65 -11
- wagtail/models/reference_index.py +15 -0
- wagtail/models/revisions.py +40 -12
- wagtail/models/workflows.py +0 -3
- wagtail/permission_policies/base.py +2 -2
- wagtail/permission_policies/collections.py +2 -2
- wagtail/project_template/requirements.txt +2 -2
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/signal_handlers.py +1 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/sv/LC_MESSAGES/django.po +3 -2
- wagtail/sites/tests.py +7 -7
- wagtail/snippets/action_menu.py +2 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +23 -13
- wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/sv/LC_MESSAGES/django.po +12 -1
- wagtail/snippets/tests/test_chooser_block.py +197 -0
- wagtail/snippets/tests/test_chooser_panel.py +149 -0
- wagtail/snippets/tests/test_chooser_views.py +375 -0
- wagtail/snippets/tests/test_chooser_widget.py +22 -0
- wagtail/snippets/tests/test_compare_revisions_view.py +167 -0
- wagtail/snippets/tests/test_copy_view.py +38 -0
- wagtail/snippets/tests/test_create_view.py +1159 -0
- wagtail/snippets/tests/test_delete_view.py +225 -0
- wagtail/snippets/tests/test_edit_view.py +2882 -0
- wagtail/snippets/tests/test_history_view.py +182 -0
- wagtail/snippets/tests/test_index_view.py +105 -0
- wagtail/snippets/tests/test_list_view.py +786 -0
- wagtail/snippets/tests/test_locking.py +28 -0
- wagtail/snippets/tests/test_permissions.py +167 -0
- wagtail/snippets/tests/test_preview.py +3 -3
- wagtail/snippets/tests/test_revert_view.py +343 -0
- wagtail/snippets/tests/test_snippet_models.py +112 -0
- wagtail/snippets/tests/test_unpublish_view.py +228 -0
- wagtail/snippets/tests/test_unschedule_view.py +151 -0
- wagtail/snippets/tests/test_viewset.py +38 -5
- wagtail/snippets/views/snippets.py +78 -30
- wagtail/snippets/widgets.py +2 -2
- wagtail/templatetags/wagtailcore_tags.py +2 -2
- wagtail/test/dummy_external_storage.py +1 -1
- wagtail/test/testapp/fixtures/test.json +22 -0
- wagtail/test/testapp/fixtures/test_empty.json +2 -0
- wagtail/test/testapp/fixtures/test_explorable_pages.json +10 -0
- wagtail/test/testapp/fixtures/test_specific.json +9 -0
- wagtail/test/testapp/migrations/0059_nopromotepage.py +25 -0
- wagtail/test/testapp/models.py +7 -0
- wagtail/test/testapp/views.py +5 -0
- wagtail/test/utils/page_tests.py +7 -7
- wagtail/test/utils/wagtail_factories/builder.py +2 -2
- wagtail/tests/streamfield_migrations/test_migrations.py +35 -0
- wagtail/tests/test_blocks.py +321 -61
- wagtail/tests/test_collection_model.py +12 -0
- wagtail/tests/test_page_model.py +190 -1
- wagtail/tests/test_page_privacy.py +5 -0
- wagtail/tests/test_reference_index.py +42 -0
- wagtail/tests/test_revision_model.py +118 -1
- wagtail/tests/test_utils.py +2 -2
- wagtail/users/locale/en/LC_MESSAGES/django.po +14 -14
- wagtail/users/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/id_ID/LC_MESSAGES/django.po +6 -2
- wagtail/users/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/it/LC_MESSAGES/django.po +14 -2
- wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/sv/LC_MESSAGES/django.po +48 -17
- wagtail/users/tests/test_admin_views.py +39 -25
- wagtail/users/utils.py +4 -1
- wagtail/users/views/groups.py +19 -5
- wagtail/users/wagtail_hooks.py +1 -1
- wagtail/utils/loading.py +2 -2
- wagtail-7.3rc1.data/data/AGENTS.md +21 -0
- wagtail-7.3rc1.data/data/CHANGELOG.txt +4941 -0
- wagtail-7.3rc1.data/data/CODE_OF_CONDUCT.md +71 -0
- wagtail-7.3rc1.data/data/CONTRIBUTORS.md +999 -0
- wagtail-7.3rc1.data/data/SPONSORS.md +55 -0
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/METADATA +6 -6
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/RECORD +310 -280
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/WHEEL +1 -1
- wagtail/images/static/wagtailimages/js/image-url-generator.js +0 -1
- wagtail/snippets/tests/test_snippets.py +0 -6377
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/licenses/LICENSE +0 -0
- {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/top_level.txt +0 -0
wagtail/test/utils/page_tests.py
CHANGED
|
@@ -200,7 +200,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
200
200
|
page, args, kwargs = site.root_page.localized.specific.route(
|
|
201
201
|
self.dummy_request, path_components
|
|
202
202
|
)
|
|
203
|
-
except Http404:
|
|
203
|
+
except Http404 as e:
|
|
204
204
|
msg = self._formatMessage(
|
|
205
205
|
msg,
|
|
206
206
|
'Failed to route to "%(route_path)s" for %(page_type)s "%(page)s". A Http404 was raised for path: "%(full_path)s".'
|
|
@@ -211,7 +211,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
211
211
|
"full_path": path,
|
|
212
212
|
},
|
|
213
213
|
)
|
|
214
|
-
raise self.failureException(msg)
|
|
214
|
+
raise self.failureException(msg) from e
|
|
215
215
|
|
|
216
216
|
def assertPageIsRenderable(
|
|
217
217
|
self,
|
|
@@ -268,7 +268,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
268
268
|
"exc": e,
|
|
269
269
|
},
|
|
270
270
|
)
|
|
271
|
-
raise self.failureException(msg)
|
|
271
|
+
raise self.failureException(msg) from e
|
|
272
272
|
finally:
|
|
273
273
|
if user:
|
|
274
274
|
self.client.logout()
|
|
@@ -340,7 +340,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
340
340
|
'Failed to load edit view via GET for %(page_type)s "%(page)s":\n%(exc)s'
|
|
341
341
|
% {"page_type": type(page).__name__, "page": page, "exc": e},
|
|
342
342
|
)
|
|
343
|
-
raise self.failureException(msg)
|
|
343
|
+
raise self.failureException(msg) from e
|
|
344
344
|
if response.status_code != 200:
|
|
345
345
|
self.client.logout()
|
|
346
346
|
msg = self._formatMessage(
|
|
@@ -370,7 +370,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
370
370
|
'Failed to load edit view via POST for %(page_type)s "%(page)s":\n%(exc)s'
|
|
371
371
|
% {"page_type": type(page).__name__, "page": page, "exc": e},
|
|
372
372
|
)
|
|
373
|
-
raise self.failureException(msg)
|
|
373
|
+
raise self.failureException(msg) from e
|
|
374
374
|
finally:
|
|
375
375
|
page.save() # undo any changes to page
|
|
376
376
|
self.client.logout()
|
|
@@ -431,7 +431,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
431
431
|
"exc": e,
|
|
432
432
|
},
|
|
433
433
|
)
|
|
434
|
-
raise self.failureException(msg)
|
|
434
|
+
raise self.failureException(msg) from e
|
|
435
435
|
|
|
436
436
|
try:
|
|
437
437
|
self.client.get(preview_path, data={"mode": mode})
|
|
@@ -446,7 +446,7 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
446
446
|
"exc": e,
|
|
447
447
|
},
|
|
448
448
|
)
|
|
449
|
-
raise self.failureException(msg)
|
|
449
|
+
raise self.failureException(msg) from e
|
|
450
450
|
finally:
|
|
451
451
|
self.client.logout()
|
|
452
452
|
|
|
@@ -78,12 +78,12 @@ class StreamBlockStepBuilder(BaseBlockStepBuilder):
|
|
|
78
78
|
try:
|
|
79
79
|
i, name, *params = k.split("__", maxsplit=2)
|
|
80
80
|
key = int(i)
|
|
81
|
-
except (ValueError, TypeError):
|
|
81
|
+
except (ValueError, TypeError) as e:
|
|
82
82
|
raise InvalidDeclaration(
|
|
83
83
|
"StreamFieldFactory declarations must be of the form "
|
|
84
84
|
"<index>=<block_name>, <index>__<block_name>=value or "
|
|
85
85
|
f"<index>__<block_name>__<param>=value, got: {k}"
|
|
86
|
-
)
|
|
86
|
+
) from e
|
|
87
87
|
if key in indexed_block_names and indexed_block_names[key] != name:
|
|
88
88
|
raise DuplicateDeclaration(
|
|
89
89
|
f"Multiple declarations for index {key} at this level of nesting "
|
|
@@ -295,3 +295,38 @@ class StreamChildrenToListBlockOperationTestCase(BaseMigrationTest):
|
|
|
295
295
|
self.assertEqual(len(new_block["value"]), 1)
|
|
296
296
|
self.assertEqual(new_block["value"][0]["type"], "item")
|
|
297
297
|
self.assertEqual(new_block["value"][0]["value"], "Char Block 1")
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class TestRevisionHandling(BaseMigrationTest):
|
|
301
|
+
"""
|
|
302
|
+
Test the handling of revisions in StreamField data migrations.
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
model = models.SamplePage
|
|
306
|
+
factory = factories.SamplePageFactory
|
|
307
|
+
has_revisions = False # We'll create them manually.
|
|
308
|
+
app_name = "streamfield_migration_tests"
|
|
309
|
+
|
|
310
|
+
def _get_test_instances(self):
|
|
311
|
+
return self.factory()
|
|
312
|
+
|
|
313
|
+
def setUp(self):
|
|
314
|
+
self.instance = self._get_test_instances()
|
|
315
|
+
|
|
316
|
+
def test_undefined_field_handled(self):
|
|
317
|
+
"""
|
|
318
|
+
Revisions not having the targeted field are handled.
|
|
319
|
+
|
|
320
|
+
See https://github.com/wagtail/wagtail/issues/12408.
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
# Create a revision
|
|
324
|
+
revision = self.instance.save_revision()
|
|
325
|
+
|
|
326
|
+
# Delete the `content' field from the revision content, to simulate a revision
|
|
327
|
+
# created before the creation of the field.
|
|
328
|
+
del revision.content["content"]
|
|
329
|
+
revision.save()
|
|
330
|
+
|
|
331
|
+
# Should not throw a KeyError.
|
|
332
|
+
self.apply_migration()
|
wagtail/tests/test_blocks.py
CHANGED
|
@@ -17,13 +17,18 @@ from django.utils.safestring import SafeData, mark_safe
|
|
|
17
17
|
from django.utils.translation import gettext_lazy as _
|
|
18
18
|
|
|
19
19
|
from wagtail import blocks
|
|
20
|
+
from wagtail.admin.telepath import registry
|
|
20
21
|
from wagtail.blocks.base import get_error_json_data
|
|
21
22
|
from wagtail.blocks.definition_lookup import BlockDefinitionLookup
|
|
22
23
|
from wagtail.blocks.field_block import FieldBlockAdapter
|
|
23
24
|
from wagtail.blocks.list_block import ListBlockAdapter, ListBlockValidationError
|
|
24
25
|
from wagtail.blocks.static_block import StaticBlockAdapter
|
|
25
26
|
from wagtail.blocks.stream_block import StreamBlockAdapter, StreamBlockValidationError
|
|
26
|
-
from wagtail.blocks.struct_block import
|
|
27
|
+
from wagtail.blocks.struct_block import (
|
|
28
|
+
BlockGroup,
|
|
29
|
+
StructBlockAdapter,
|
|
30
|
+
StructBlockValidationError,
|
|
31
|
+
)
|
|
27
32
|
from wagtail.models import Page
|
|
28
33
|
from wagtail.rich_text import RichText
|
|
29
34
|
from wagtail.test.testapp.blocks import LinkBlock as CustomLinkBlock
|
|
@@ -1924,6 +1929,82 @@ class TestMeta(unittest.TestCase):
|
|
|
1924
1929
|
self.assertEqual(block.meta.label, "Child block")
|
|
1925
1930
|
|
|
1926
1931
|
|
|
1932
|
+
class TestBlockGroup(SimpleTestCase):
|
|
1933
|
+
@classmethod
|
|
1934
|
+
def setUpClass(cls):
|
|
1935
|
+
cls.adapter = registry.find_adapter(BlockGroup)
|
|
1936
|
+
|
|
1937
|
+
def test_adapt(self):
|
|
1938
|
+
group = BlockGroup(
|
|
1939
|
+
children=["title", "body"],
|
|
1940
|
+
settings=["theme"],
|
|
1941
|
+
heading="Content",
|
|
1942
|
+
classname="custom-class",
|
|
1943
|
+
help_text="Some help text",
|
|
1944
|
+
icon="folder",
|
|
1945
|
+
attrs={"data-example": "value"},
|
|
1946
|
+
label_format="Title: {title}, Theme: {theme}",
|
|
1947
|
+
)
|
|
1948
|
+
result = self.adapter.pack(group, None)
|
|
1949
|
+
self.assertEqual(result[0], "wagtail.blocks.BlockGroup")
|
|
1950
|
+
self.assertEqual(
|
|
1951
|
+
result[1],
|
|
1952
|
+
[
|
|
1953
|
+
{
|
|
1954
|
+
"children": [("title", "title"), ("body", "body")],
|
|
1955
|
+
"settings": [("theme", "theme")],
|
|
1956
|
+
"heading": "Content",
|
|
1957
|
+
"cleanName": "content",
|
|
1958
|
+
"classname": "custom-class",
|
|
1959
|
+
"helpText": "Some help text",
|
|
1960
|
+
"icon": "folder",
|
|
1961
|
+
"attrs": {"data-example": "value"},
|
|
1962
|
+
"labelFormat": "Title: {title}, Theme: {theme}",
|
|
1963
|
+
}
|
|
1964
|
+
],
|
|
1965
|
+
)
|
|
1966
|
+
|
|
1967
|
+
def test_adapt_adjacent_block_groups_with_same_headings(self):
|
|
1968
|
+
form_layout = BlockGroup(
|
|
1969
|
+
children=[
|
|
1970
|
+
BlockGroup(children=["title", "body"], heading="Some heading"),
|
|
1971
|
+
BlockGroup(children=["image"], heading="Some heading"),
|
|
1972
|
+
"non_nested_block",
|
|
1973
|
+
# These will have default heading "Group"
|
|
1974
|
+
BlockGroup(children=["foo"]),
|
|
1975
|
+
BlockGroup(children=["bar"]),
|
|
1976
|
+
],
|
|
1977
|
+
settings=[BlockGroup(children=["theme"], heading="Some heading")],
|
|
1978
|
+
)
|
|
1979
|
+
result = self.adapter.pack(form_layout, None)
|
|
1980
|
+
self.assertEqual(result[0], "wagtail.blocks.BlockGroup")
|
|
1981
|
+
self.assertEqual(
|
|
1982
|
+
result[1],
|
|
1983
|
+
[
|
|
1984
|
+
{
|
|
1985
|
+
# Children and settings are list of (child, unique_name) tuples
|
|
1986
|
+
# to ensure unique names of adjacent groups with same headings
|
|
1987
|
+
# for the purpose of generating collapsible panel element IDs
|
|
1988
|
+
"children": [
|
|
1989
|
+
(form_layout.children[0], "some_heading"),
|
|
1990
|
+
(form_layout.children[1], "some_heading1"),
|
|
1991
|
+
("non_nested_block", "non_nested_block"),
|
|
1992
|
+
(form_layout.children[3], "group"),
|
|
1993
|
+
(form_layout.children[4], "group1"),
|
|
1994
|
+
],
|
|
1995
|
+
"settings": [(form_layout.settings[0], "some_heading2")],
|
|
1996
|
+
"heading": "Group",
|
|
1997
|
+
"cleanName": "group",
|
|
1998
|
+
"classname": "",
|
|
1999
|
+
"helpText": "",
|
|
2000
|
+
"icon": "placeholder",
|
|
2001
|
+
"attrs": {},
|
|
2002
|
+
"labelFormat": None,
|
|
2003
|
+
}
|
|
2004
|
+
],
|
|
2005
|
+
)
|
|
2006
|
+
|
|
2007
|
+
|
|
1927
2008
|
class TestStructBlock(SimpleTestCase):
|
|
1928
2009
|
def test_initialisation(self):
|
|
1929
2010
|
block = blocks.StructBlock(
|
|
@@ -2121,6 +2202,72 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2121
2202
|
self.assertEqual(context["block_definition"], block)
|
|
2122
2203
|
self.assertEqual(context["prefix"], "mylink")
|
|
2123
2204
|
|
|
2205
|
+
def test_get_form_context_with_settings(self):
|
|
2206
|
+
class LinkBlock(blocks.StructBlock):
|
|
2207
|
+
title = blocks.CharBlock()
|
|
2208
|
+
link = blocks.URLBlock()
|
|
2209
|
+
open_in_new_tab = blocks.BooleanBlock(required=False, default=False)
|
|
2210
|
+
|
|
2211
|
+
class Meta:
|
|
2212
|
+
form_layout = BlockGroup(
|
|
2213
|
+
children=["link", "title"],
|
|
2214
|
+
settings=["open_in_new_tab"],
|
|
2215
|
+
)
|
|
2216
|
+
|
|
2217
|
+
block = LinkBlock()
|
|
2218
|
+
context = block.get_form_context(
|
|
2219
|
+
block.to_python(
|
|
2220
|
+
{
|
|
2221
|
+
"title": "Django",
|
|
2222
|
+
"link": "http://djangoproject.com",
|
|
2223
|
+
"open_in_new_tab": True,
|
|
2224
|
+
}
|
|
2225
|
+
),
|
|
2226
|
+
prefix="mylink",
|
|
2227
|
+
)
|
|
2228
|
+
|
|
2229
|
+
# The context separates children and settings according to the form layout
|
|
2230
|
+
children = context["children"]
|
|
2231
|
+
self.assertIsInstance(children, collections.OrderedDict)
|
|
2232
|
+
self.assertEqual(len(children), 2)
|
|
2233
|
+
self.assertIsInstance(children["title"], blocks.BoundBlock)
|
|
2234
|
+
self.assertIsInstance(children["link"], blocks.BoundBlock)
|
|
2235
|
+
# Should respect the order defined in the form layout
|
|
2236
|
+
self.assertEqual(
|
|
2237
|
+
[child.value for child in children.values()],
|
|
2238
|
+
["http://djangoproject.com", "Django"],
|
|
2239
|
+
)
|
|
2240
|
+
|
|
2241
|
+
settings = context["settings"]
|
|
2242
|
+
self.assertIsInstance(settings, collections.OrderedDict)
|
|
2243
|
+
self.assertEqual(len(settings), 1)
|
|
2244
|
+
self.assertIsInstance(settings["open_in_new_tab"], blocks.BoundBlock)
|
|
2245
|
+
|
|
2246
|
+
def test_check_form_template_with_nested_block_groups(self):
|
|
2247
|
+
class LinkBlock(blocks.StructBlock):
|
|
2248
|
+
title = blocks.CharBlock()
|
|
2249
|
+
link = blocks.URLBlock()
|
|
2250
|
+
open_in_new_tab = blocks.BooleanBlock(required=False, default=False)
|
|
2251
|
+
|
|
2252
|
+
class Meta:
|
|
2253
|
+
form_layout = BlockGroup(
|
|
2254
|
+
children=[BlockGroup(children=["title", "link"])],
|
|
2255
|
+
settings=["open_in_new_tab"],
|
|
2256
|
+
)
|
|
2257
|
+
form_template = "tests/block_forms/struct_block_form_template.html"
|
|
2258
|
+
|
|
2259
|
+
block = LinkBlock()
|
|
2260
|
+
results = block.check()
|
|
2261
|
+
|
|
2262
|
+
self.assertEqual(len(results), 1)
|
|
2263
|
+
self.assertEqual(results[0].id, "wagtailcore.E007")
|
|
2264
|
+
self.assertEqual(results[0].obj, block)
|
|
2265
|
+
self.assertEqual(
|
|
2266
|
+
results[0].msg,
|
|
2267
|
+
"LinkBlock.Meta.form_layout cannot have nested BlockGroups "
|
|
2268
|
+
"when using a custom form_template.",
|
|
2269
|
+
)
|
|
2270
|
+
|
|
2124
2271
|
def test_adapt(self):
|
|
2125
2272
|
class LinkBlock(blocks.StructBlock):
|
|
2126
2273
|
title = blocks.CharBlock(required=False)
|
|
@@ -2144,6 +2291,7 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2144
2291
|
"classname": "struct-block",
|
|
2145
2292
|
"collapsed": False,
|
|
2146
2293
|
"attrs": {},
|
|
2294
|
+
"formLayout": block.meta.form_layout,
|
|
2147
2295
|
},
|
|
2148
2296
|
)
|
|
2149
2297
|
|
|
@@ -2153,6 +2301,9 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2153
2301
|
self.assertEqual(title_field, block.child_blocks["title"])
|
|
2154
2302
|
self.assertEqual(link_field, block.child_blocks["link"])
|
|
2155
2303
|
|
|
2304
|
+
# The default form layout lists the field names in order as children
|
|
2305
|
+
self.assertEqual(js_args[2]["formLayout"].children, ["title", "link"])
|
|
2306
|
+
|
|
2156
2307
|
def test_adapt_with_form_template(self):
|
|
2157
2308
|
class LinkBlock(blocks.StructBlock):
|
|
2158
2309
|
title = blocks.CharBlock(required=False)
|
|
@@ -2178,6 +2329,7 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2178
2329
|
"classname": "struct-block",
|
|
2179
2330
|
"collapsed": False,
|
|
2180
2331
|
"attrs": {},
|
|
2332
|
+
"formLayout": block.meta.form_layout,
|
|
2181
2333
|
"formTemplate": "<div>Hello</div>",
|
|
2182
2334
|
},
|
|
2183
2335
|
)
|
|
@@ -2256,6 +2408,7 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2256
2408
|
"classname": "struct-block",
|
|
2257
2409
|
"collapsed": False,
|
|
2258
2410
|
"attrs": {},
|
|
2411
|
+
"formLayout": block.meta.form_layout,
|
|
2259
2412
|
"formTemplate": "<div>Hello</div>",
|
|
2260
2413
|
},
|
|
2261
2414
|
)
|
|
@@ -2313,6 +2466,7 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2313
2466
|
"classname": "struct-block",
|
|
2314
2467
|
"collapsed": False,
|
|
2315
2468
|
"attrs": {},
|
|
2469
|
+
"formLayout": block.meta.form_layout,
|
|
2316
2470
|
"helpIcon": (
|
|
2317
2471
|
'<svg class="icon icon-help default" aria-hidden="true">'
|
|
2318
2472
|
'<use href="#icon-help"></use></svg>'
|
|
@@ -2343,6 +2497,7 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2343
2497
|
"classname": "struct-block",
|
|
2344
2498
|
"collapsed": False,
|
|
2345
2499
|
"attrs": {},
|
|
2500
|
+
"formLayout": block.meta.form_layout,
|
|
2346
2501
|
"helpIcon": (
|
|
2347
2502
|
'<svg class="icon icon-help default" aria-hidden="true">'
|
|
2348
2503
|
'<use href="#icon-help"></use></svg>'
|
|
@@ -2366,6 +2521,167 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2366
2521
|
|
|
2367
2522
|
self.assertIs(js_args[2]["collapsed"], case)
|
|
2368
2523
|
|
|
2524
|
+
def test_adapt_with_list_form_layout(self):
|
|
2525
|
+
class LinkBlock(blocks.StructBlock):
|
|
2526
|
+
title = blocks.CharBlock()
|
|
2527
|
+
link = blocks.URLBlock()
|
|
2528
|
+
|
|
2529
|
+
class Meta:
|
|
2530
|
+
form_layout = ["link", "title"]
|
|
2531
|
+
|
|
2532
|
+
block = LinkBlock()
|
|
2533
|
+
|
|
2534
|
+
block.set_name("test_structblock")
|
|
2535
|
+
js_args = StructBlockAdapter().js_args(block)
|
|
2536
|
+
|
|
2537
|
+
# Should be converted to a BlockGroup instance,
|
|
2538
|
+
# which will be adapted on its own
|
|
2539
|
+
form_layout = js_args[2]["formLayout"]
|
|
2540
|
+
self.assertIsInstance(form_layout, BlockGroup)
|
|
2541
|
+
self.assertEqual(form_layout, block.meta.form_layout)
|
|
2542
|
+
self.assertEqual(form_layout.children, ["link", "title"])
|
|
2543
|
+
|
|
2544
|
+
def test_adapt_with_settings_blocks(self):
|
|
2545
|
+
class LinkBlock(blocks.StructBlock):
|
|
2546
|
+
title = blocks.CharBlock()
|
|
2547
|
+
link = blocks.URLBlock()
|
|
2548
|
+
|
|
2549
|
+
class Meta:
|
|
2550
|
+
form_layout = BlockGroup(
|
|
2551
|
+
children=["title"],
|
|
2552
|
+
settings=["link"],
|
|
2553
|
+
)
|
|
2554
|
+
|
|
2555
|
+
block = LinkBlock()
|
|
2556
|
+
|
|
2557
|
+
block.set_name("test_structblock")
|
|
2558
|
+
js_args = StructBlockAdapter().js_args(block)
|
|
2559
|
+
|
|
2560
|
+
# The form_layout is still a BlockGroup instance,
|
|
2561
|
+
# which will be adapted on its own
|
|
2562
|
+
form_layout = js_args[2]["formLayout"]
|
|
2563
|
+
self.assertIsInstance(form_layout, BlockGroup)
|
|
2564
|
+
self.assertEqual(form_layout, block.meta.form_layout)
|
|
2565
|
+
self.assertEqual(form_layout.children, ["title"])
|
|
2566
|
+
self.assertEqual(form_layout.settings, ["link"])
|
|
2567
|
+
|
|
2568
|
+
def test_with_nested_blockgroups_in_form_layout(self):
|
|
2569
|
+
class LinkBlock(blocks.StructBlock):
|
|
2570
|
+
title = blocks.CharBlock()
|
|
2571
|
+
link = blocks.URLBlock()
|
|
2572
|
+
description = blocks.TextBlock()
|
|
2573
|
+
|
|
2574
|
+
class Meta:
|
|
2575
|
+
form_layout = BlockGroup(
|
|
2576
|
+
children=[
|
|
2577
|
+
"link",
|
|
2578
|
+
BlockGroup(
|
|
2579
|
+
children=["title", "description"],
|
|
2580
|
+
heading="Details",
|
|
2581
|
+
),
|
|
2582
|
+
]
|
|
2583
|
+
)
|
|
2584
|
+
|
|
2585
|
+
block = LinkBlock()
|
|
2586
|
+
|
|
2587
|
+
block.set_name("test_structblock")
|
|
2588
|
+
js_args = StructBlockAdapter().js_args(block)
|
|
2589
|
+
|
|
2590
|
+
# The form_layout is still a BlockGroup instance,
|
|
2591
|
+
# which will be adapted on its own
|
|
2592
|
+
form_layout = js_args[2]["formLayout"]
|
|
2593
|
+
self.assertIsInstance(form_layout, BlockGroup)
|
|
2594
|
+
self.assertEqual(form_layout, block.meta.form_layout)
|
|
2595
|
+
self.assertEqual(form_layout.children[0], "link")
|
|
2596
|
+
self.assertIsInstance(form_layout.children[1], BlockGroup)
|
|
2597
|
+
self.assertEqual(form_layout.children[1].children, ["title", "description"])
|
|
2598
|
+
|
|
2599
|
+
def test_with_missing_blocks_in_form_layout(self):
|
|
2600
|
+
class LinkBlock(blocks.StructBlock):
|
|
2601
|
+
title = blocks.CharBlock()
|
|
2602
|
+
link = blocks.URLBlock()
|
|
2603
|
+
description = blocks.TextBlock()
|
|
2604
|
+
|
|
2605
|
+
class Meta:
|
|
2606
|
+
form_layout = BlockGroup(
|
|
2607
|
+
children=["link"],
|
|
2608
|
+
settings=["title"],
|
|
2609
|
+
)
|
|
2610
|
+
|
|
2611
|
+
block = LinkBlock()
|
|
2612
|
+
|
|
2613
|
+
block.set_name("test_structblock")
|
|
2614
|
+
js_args = StructBlockAdapter().js_args(block)
|
|
2615
|
+
|
|
2616
|
+
form_layout = js_args[2]["formLayout"]
|
|
2617
|
+
self.assertIsInstance(form_layout, BlockGroup)
|
|
2618
|
+
|
|
2619
|
+
# The form_layout remains as defined, even if some fields are missing
|
|
2620
|
+
self.assertEqual(form_layout, block.meta.form_layout)
|
|
2621
|
+
self.assertEqual(form_layout.children, ["link"])
|
|
2622
|
+
self.assertEqual(form_layout.settings, ["title"])
|
|
2623
|
+
|
|
2624
|
+
# However, it's still in block.child_blocks, appended to the end. This
|
|
2625
|
+
# ensures any code that relies on block.child_blocks to find all blocks
|
|
2626
|
+
# still works, even if the form_layout isn't configured properly.
|
|
2627
|
+
self.assertEqual(
|
|
2628
|
+
list(block.child_blocks.keys()),
|
|
2629
|
+
["link", "title", "description"],
|
|
2630
|
+
)
|
|
2631
|
+
self.assertIsInstance(block.child_blocks["description"], blocks.TextBlock)
|
|
2632
|
+
|
|
2633
|
+
def test_adapt_with_get_form_layout(self):
|
|
2634
|
+
class LinkBlock(blocks.StructBlock):
|
|
2635
|
+
title = blocks.CharBlock()
|
|
2636
|
+
link = blocks.URLBlock()
|
|
2637
|
+
|
|
2638
|
+
class Meta:
|
|
2639
|
+
form_layout = BlockGroup(
|
|
2640
|
+
children=[
|
|
2641
|
+
"link",
|
|
2642
|
+
BlockGroup(
|
|
2643
|
+
children=["title"],
|
|
2644
|
+
heading="Details",
|
|
2645
|
+
),
|
|
2646
|
+
]
|
|
2647
|
+
)
|
|
2648
|
+
|
|
2649
|
+
class LinkBlockWithDescription(LinkBlock):
|
|
2650
|
+
description = blocks.TextBlock()
|
|
2651
|
+
|
|
2652
|
+
def get_form_layout(self):
|
|
2653
|
+
# Create a deep copy of the parent's form layout to include the
|
|
2654
|
+
# new 'description' field without mutating the parent's form layout
|
|
2655
|
+
form_layout = copy.deepcopy(super().get_form_layout())
|
|
2656
|
+
form_layout.children[1].children.append("description")
|
|
2657
|
+
return form_layout
|
|
2658
|
+
|
|
2659
|
+
block = LinkBlock()
|
|
2660
|
+
sub_block = LinkBlockWithDescription()
|
|
2661
|
+
|
|
2662
|
+
block.set_name("test_structblock")
|
|
2663
|
+
sub_block.set_name("test_structblockwithdescription")
|
|
2664
|
+
js_args = StructBlockAdapter().js_args(block)
|
|
2665
|
+
sub_js_args = StructBlockAdapter().js_args(sub_block)
|
|
2666
|
+
|
|
2667
|
+
form_layout = js_args[2]["formLayout"]
|
|
2668
|
+
self.assertIsInstance(form_layout, BlockGroup)
|
|
2669
|
+
self.assertEqual(form_layout, block.meta.form_layout)
|
|
2670
|
+
self.assertEqual(form_layout.children[0], "link")
|
|
2671
|
+
self.assertIsInstance(form_layout.children[1], BlockGroup)
|
|
2672
|
+
self.assertEqual(form_layout.children[1].children, ["title"])
|
|
2673
|
+
|
|
2674
|
+
# Different instances (including nested BlockGroups), to allow subclassing
|
|
2675
|
+
# without mutating parent class's form layout
|
|
2676
|
+
sub_form_layout = sub_js_args[2]["formLayout"]
|
|
2677
|
+
self.assertIsInstance(sub_form_layout, BlockGroup)
|
|
2678
|
+
self.assertNotEqual(form_layout, sub_form_layout)
|
|
2679
|
+
self.assertEqual(sub_form_layout, sub_block.meta.form_layout)
|
|
2680
|
+
self.assertEqual(sub_form_layout.children[0], "link")
|
|
2681
|
+
self.assertIsInstance(sub_form_layout.children[1], BlockGroup)
|
|
2682
|
+
self.assertNotEqual(form_layout.children[1], sub_form_layout.children[1])
|
|
2683
|
+
self.assertEqual(sub_form_layout.children[1].children, ["title", "description"])
|
|
2684
|
+
|
|
2369
2685
|
def test_adapt_label_format(self):
|
|
2370
2686
|
class LinkBlock(blocks.StructBlock):
|
|
2371
2687
|
title = blocks.CharBlock()
|
|
@@ -3006,14 +3322,6 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3006
3322
|
"classname": None,
|
|
3007
3323
|
"attrs": {},
|
|
3008
3324
|
"collapsed": False,
|
|
3009
|
-
"strings": {
|
|
3010
|
-
"DELETE": "Delete",
|
|
3011
|
-
"DUPLICATE": "Duplicate",
|
|
3012
|
-
"MOVE_DOWN": "Move down",
|
|
3013
|
-
"MOVE_UP": "Move up",
|
|
3014
|
-
"DRAG": "Drag",
|
|
3015
|
-
"ADD": "Add",
|
|
3016
|
-
},
|
|
3017
3325
|
},
|
|
3018
3326
|
)
|
|
3019
3327
|
|
|
@@ -3043,14 +3351,6 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3043
3351
|
"collapsed": False,
|
|
3044
3352
|
"minNum": 2,
|
|
3045
3353
|
"maxNum": 5,
|
|
3046
|
-
"strings": {
|
|
3047
|
-
"DELETE": "Delete",
|
|
3048
|
-
"DUPLICATE": "Duplicate",
|
|
3049
|
-
"MOVE_DOWN": "Move down",
|
|
3050
|
-
"MOVE_UP": "Move up",
|
|
3051
|
-
"DRAG": "Drag",
|
|
3052
|
-
"ADD": "Add",
|
|
3053
|
-
},
|
|
3054
3354
|
},
|
|
3055
3355
|
)
|
|
3056
3356
|
|
|
@@ -3228,14 +3528,6 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3228
3528
|
"classname": "special-list-class",
|
|
3229
3529
|
"attrs": {},
|
|
3230
3530
|
"collapsed": False,
|
|
3231
|
-
"strings": {
|
|
3232
|
-
"DELETE": "Delete",
|
|
3233
|
-
"DUPLICATE": "Duplicate",
|
|
3234
|
-
"MOVE_DOWN": "Move down",
|
|
3235
|
-
"MOVE_UP": "Move up",
|
|
3236
|
-
"DRAG": "Drag",
|
|
3237
|
-
"ADD": "Add",
|
|
3238
|
-
},
|
|
3239
3531
|
},
|
|
3240
3532
|
)
|
|
3241
3533
|
|
|
@@ -3266,14 +3558,6 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3266
3558
|
"classname": "custom-list-class",
|
|
3267
3559
|
"attrs": {},
|
|
3268
3560
|
"collapsed": False,
|
|
3269
|
-
"strings": {
|
|
3270
|
-
"DELETE": "Delete",
|
|
3271
|
-
"DUPLICATE": "Duplicate",
|
|
3272
|
-
"MOVE_DOWN": "Move down",
|
|
3273
|
-
"MOVE_UP": "Move up",
|
|
3274
|
-
"DRAG": "Drag",
|
|
3275
|
-
"ADD": "Add",
|
|
3276
|
-
},
|
|
3277
3561
|
},
|
|
3278
3562
|
)
|
|
3279
3563
|
|
|
@@ -3689,10 +3973,10 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3689
3973
|
value = block.to_python([{"type": "paragraph", "value": "Hello"}])
|
|
3690
3974
|
try:
|
|
3691
3975
|
block.clean(value)
|
|
3692
|
-
except blocks.StreamBlockValidationError:
|
|
3976
|
+
except blocks.StreamBlockValidationError as e:
|
|
3693
3977
|
raise self.failureException(
|
|
3694
3978
|
"%s was raised" % blocks.StreamBlockValidationError
|
|
3695
|
-
)
|
|
3979
|
+
) from e
|
|
3696
3980
|
|
|
3697
3981
|
def test_not_required_does_not_raise_an_exception_if_empty(self):
|
|
3698
3982
|
block = blocks.StreamBlock([("paragraph", blocks.CharBlock())], required=False)
|
|
@@ -3700,10 +3984,10 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3700
3984
|
|
|
3701
3985
|
try:
|
|
3702
3986
|
block.clean(value)
|
|
3703
|
-
except blocks.StreamBlockValidationError:
|
|
3987
|
+
except blocks.StreamBlockValidationError as e:
|
|
3704
3988
|
raise self.failureException(
|
|
3705
3989
|
"%s was raised" % blocks.StreamBlockValidationError
|
|
3706
|
-
)
|
|
3990
|
+
) from e
|
|
3707
3991
|
|
|
3708
3992
|
def test_required_by_default(self):
|
|
3709
3993
|
block = blocks.StreamBlock([("paragraph", blocks.CharBlock())])
|
|
@@ -3939,14 +4223,6 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
3939
4223
|
"minNum": None,
|
|
3940
4224
|
"blockCounts": {},
|
|
3941
4225
|
"required": True,
|
|
3942
|
-
"strings": {
|
|
3943
|
-
"DELETE": "Delete",
|
|
3944
|
-
"DUPLICATE": "Duplicate",
|
|
3945
|
-
"MOVE_DOWN": "Move down",
|
|
3946
|
-
"MOVE_UP": "Move up",
|
|
3947
|
-
"DRAG": "Drag",
|
|
3948
|
-
"ADD": "Add",
|
|
3949
|
-
},
|
|
3950
4226
|
},
|
|
3951
4227
|
)
|
|
3952
4228
|
|
|
@@ -4716,14 +4992,6 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4716
4992
|
"required": True,
|
|
4717
4993
|
"classname": "rocket-section",
|
|
4718
4994
|
"attrs": {},
|
|
4719
|
-
"strings": {
|
|
4720
|
-
"DELETE": "Delete",
|
|
4721
|
-
"DUPLICATE": "Duplicate",
|
|
4722
|
-
"MOVE_DOWN": "Move down",
|
|
4723
|
-
"MOVE_UP": "Move up",
|
|
4724
|
-
"DRAG": "Drag",
|
|
4725
|
-
"ADD": "Add",
|
|
4726
|
-
},
|
|
4727
4995
|
},
|
|
4728
4996
|
)
|
|
4729
4997
|
|
|
@@ -4823,14 +5091,6 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4823
5091
|
"required": True,
|
|
4824
5092
|
"classname": "profile-block-large",
|
|
4825
5093
|
"attrs": {},
|
|
4826
|
-
"strings": {
|
|
4827
|
-
"DELETE": "Delete",
|
|
4828
|
-
"DUPLICATE": "Duplicate",
|
|
4829
|
-
"MOVE_DOWN": "Move down",
|
|
4830
|
-
"MOVE_UP": "Move up",
|
|
4831
|
-
"DRAG": "Drag",
|
|
4832
|
-
"ADD": "Add",
|
|
4833
|
-
},
|
|
4834
5094
|
},
|
|
4835
5095
|
)
|
|
4836
5096
|
|
|
@@ -109,3 +109,15 @@ class TestCollectionTreeOperations(TestCase):
|
|
|
109
109
|
),
|
|
110
110
|
[self.evil_plans_collection],
|
|
111
111
|
)
|
|
112
|
+
|
|
113
|
+
def test_collection_natural_key(self):
|
|
114
|
+
"""Test Collection and natural key implementation"""
|
|
115
|
+
|
|
116
|
+
natural_key = self.holiday_photos_collection.natural_key()
|
|
117
|
+
expected_path = (self.root_collection.name, "Holiday photos")
|
|
118
|
+
self.assertEqual(natural_key, expected_path)
|
|
119
|
+
|
|
120
|
+
retrieved_collection = Collection.objects.get_by_natural_key(
|
|
121
|
+
self.root_collection.name, "Holiday photos"
|
|
122
|
+
)
|
|
123
|
+
self.assertEqual(retrieved_collection, self.holiday_photos_collection)
|