diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 15e0333254..4936ec6640 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -46,6 +46,7 @@ Changelog * Fix: Page history now works correctly when it contains changes by a deleted user (Dan Braghis) * Fix: Add `gettext_lazy` to `ModelAdmin` built in view titles so that language settings are correctly used (Matt Westcott) * Fix: Tabbing and keyboard interaction on the Wagtail userbar now aligns with ARIA best practices (Storm Heg) + * Fix: Add full support for custom `edit_handler` usage by adding missing `bind_to` call to `PreviewOnEdit` view (Stefan Hammer) 2.14.1 (12.08.2021) diff --git a/docs/releases/2.15.rst b/docs/releases/2.15.rst index 1a7a8aaab6..6c4dfce58b 100644 --- a/docs/releases/2.15.rst +++ b/docs/releases/2.15.rst @@ -61,6 +61,7 @@ Bug fixes * Page history now works correctly when it contains changes by a deleted user (Dan Braghis) * Add ``gettext_lazy`` to ``ModelAdmin`` built in view titles so that language settings are correctly used (Matt Westcott) * Tabbing and keyboard interaction on the Wagtail userbar now aligns with ARIA best practices (Storm Heg) + * Add full support for custom ``edit_handler`` usage by adding missing ``bind_to`` call to ``PreviewOnEdit`` view (Stefan Hammer) Upgrade considerations ====================== diff --git a/wagtail/admin/tests/pages/test_preview.py b/wagtail/admin/tests/pages/test_preview.py index 2018df3ae5..cacaa05fa7 100644 --- a/wagtail/admin/tests/pages/test_preview.py +++ b/wagtail/admin/tests/pages/test_preview.py @@ -1,13 +1,17 @@ import datetime +from functools import wraps +from unittest import mock + from django.test import TestCase from django.urls import reverse from django.utils import timezone from freezegun import freeze_time +from wagtail.admin.edit_handlers import FieldPanel, ObjectList, TabbedInterface from wagtail.admin.views.pages.preview import PreviewOnEdit from wagtail.core.models import Page -from wagtail.tests.testapp.models import EventCategory, SimplePage, StreamPage +from wagtail.tests.testapp.models import EventCategory, EventPage, SimplePage, StreamPage from wagtail.tests.utils import WagtailTestUtils @@ -57,6 +61,21 @@ class TestIssue2599(TestCase, WagtailTestUtils): self.assertEqual(response.context['self'].get_parent(), homepage) +def clear_edit_handler(page_cls): + def decorator(fn): + @wraps(fn) + def decorated(*args, **kwargs): + # Clear any old EditHandlers generated + page_cls.get_edit_handler.cache_clear() + try: + fn(*args, **kwargs) + finally: + # Clear the bad EditHandler generated just now + page_cls.get_edit_handler.cache_clear() + return decorated + return decorator + + class TestPreview(TestCase, WagtailTestUtils): fixtures = ['test.json'] @@ -174,6 +193,83 @@ class TestPreview(TestCase, WagtailTestUtils): response = self.client.get(preview_url) self.assertEqual(response.status_code, 200) + @clear_edit_handler(EventPage) + def test_preview_with_custom_edit_handler(self): + """ + The test is based on TestPreview.test_preview_on_create_with_m2m_field, except that the "categories" + FieldPanel is only visible to superusers. Non-superusers should not be able to set "categories" for + the preview. + """ + + class SuperuserEventCategoriesObjectList(ObjectList): + def on_request_bound(self): + new_children = [] + for child in self.children: + # skip the "categories" FieldPanel for non-superusers + if isinstance(child, FieldPanel) and child.field_name == "categories" and not self.request.user.is_superuser: + continue + + new_child = child.bind_to( + model=self.model, + instance=self.instance, + request=self.request, + form=self.form, + ) + new_children.append(new_child) + self.children = new_children + + new_tabbed_interface = TabbedInterface([ + SuperuserEventCategoriesObjectList(EventPage.content_panels), + ObjectList(EventPage.promote_panels), + ]) + + with mock.patch.object(EventPage, 'edit_handler', new=new_tabbed_interface, create=True): + # Non-superusers should not see categories panel, so even though "post_data" contains "categories", + # it should not be considered for the preview request. + self.login(username='siteeditor', password='password') + + preview_url = reverse('wagtailadmin_pages:preview_on_add', + args=('tests', 'eventpage', self.home_page.id)) + response = self.client.post(preview_url, self.post_data) + + # Check the JSON response + self.assertEqual(response.status_code, 200) + self.assertJSONEqual(response.content.decode(), {'is_valid': True}) + + # Check the user can refresh the preview + preview_session_key = 'wagtail-preview-tests-eventpage-{}'.format(self.home_page.id) + self.assertTrue(preview_session_key in self.client.session) + + response = self.client.get(preview_url) + + # Check the HTML response + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'tests/event_page.html') + self.assertContains(response, "Beach party") + self.assertNotContains(response, "