diff --git a/coderedcms/models/page_models.py b/coderedcms/models/page_models.py index 33194bee..07aecf9f 100755 --- a/coderedcms/models/page_models.py +++ b/coderedcms/models/page_models.py @@ -60,6 +60,7 @@ from wagtail.admin.panels import ObjectList from wagtail.admin.panels import TabbedInterface from wagtail.contrib.forms.forms import WagtailAdminFormPageForm +from wagtail.contrib.forms.models import FormMixin from wagtail.contrib.forms.models import FormSubmission from wagtail.contrib.forms.panels import FormSubmissionsPanel from wagtail.coreutils import resolve_model_string @@ -1710,10 +1711,18 @@ def get_preview_context(self, request, *args, **kwargs): return ctx -class CoderedFormPage(CoderedFormMixin, CoderedWebPage): +class CoderedFormPage(CoderedFormMixin, CoderedWebPage, FormMixin): """ This is basically a clone of wagtail.contrib.forms.models.AbstractForm with changes in functionality and extending CoderedWebPage vs wagtailcore.Page. + + Wagtail's ``FormMixin`` is inherited last so this page satisfies the + ``isinstance(page, FormMixin)`` guard Wagtail 7.x added to its admin + submissions view, and gains the ``get_submissions()`` / + ``get_submissions_list_view_class()`` API that view now relies on. Being + last in the MRO, it only fills methods CodeRed does not already define, so + existing behavior is unchanged. + See https://github.com/coderedcorp/coderedcms/issues/710 """ class Meta: @@ -1828,8 +1837,12 @@ def get_session_submission_class(): class CoderedStreamFormPage( - CoderedFormMixin, CoderedStreamFormMixin, CoderedWebPage + CoderedFormMixin, CoderedStreamFormMixin, CoderedWebPage, FormMixin ): + # ``FormMixin`` is inherited last (after ``StreamFormMixin``) so it only + # satisfies Wagtail 7.x's ``isinstance`` guard and supplies + # ``get_submissions()`` without shadowing the StreamForm field/handling + # methods. See https://github.com/coderedcorp/coderedcms/issues/710 class Meta: verbose_name = _("CodeRed Advanced Form Page") abstract = True diff --git a/coderedcms/tests/test_forms.py b/coderedcms/tests/test_forms.py new file mode 100644 index 00000000..5d0b9cdc --- /dev/null +++ b/coderedcms/tests/test_forms.py @@ -0,0 +1,66 @@ +import unittest + +import pytest +from django.contrib.auth import get_user_model +from django.test import Client +from django.urls import reverse +from wagtail.models import Page + +from coderedcms.tests.testapp.models import FormPage +from coderedcms.tests.testapp.models import FormPageField +from coderedcms.tests.testapp.models import StreamFormPage + + +@pytest.mark.django_db +class TestFormSubmissionsAdmin(unittest.TestCase): + """The Wagtail admin "Forms" area must list and show submissions for + CodeRed form pages. + + Regression test for the 404 introduced when Wagtail 7.x began guarding its + admin submissions view with ``isinstance(page, FormMixin)`` (and calling + ``page.get_submissions()``), which CodeRed form pages did not satisfy. + See https://github.com/coderedcorp/coderedcms/issues/710 + """ + + def setUp(self): + self.client = Client() + self.user = get_user_model().objects.create_superuser( + username="admin", + email="admin@example.com", + password="password", + ) + self.client.force_login(self.user) + self.root_page = Page.get_root_nodes()[0] + + def _make_form_page(self): + form_page = FormPage(title="Contact", slug="contact") + self.root_page.add_child(instance=form_page) + FormPageField.objects.create( + page=form_page, + sort_order=0, + label="Your name", + field_type="singleline", + required=True, + ) + return form_page + + def test_form_index_lists_codered_form(self): + self._make_form_page() + response = self.client.get(reverse("wagtailforms:index")) + self.assertEqual(response.status_code, 200) + self.assertIn(b"Contact", response.content) + + def test_codered_form_submissions_view(self): + form_page = self._make_form_page() + response = self.client.get( + reverse("wagtailforms:list_submissions", args=[form_page.pk]) + ) + self.assertEqual(response.status_code, 200) + + def test_codered_stream_form_submissions_view(self): + stream_page = StreamFormPage(title="Survey", slug="survey") + self.root_page.add_child(instance=stream_page) + response = self.client.get( + reverse("wagtailforms:list_submissions", args=[stream_page.pk]) + ) + self.assertEqual(response.status_code, 200) diff --git a/docs/getting_started/tutorial05.rst b/docs/getting_started/tutorial05.rst index 83c4a128..95ecd248 100644 --- a/docs/getting_started/tutorial05.rst +++ b/docs/getting_started/tutorial05.rst @@ -103,7 +103,7 @@ Publish and see what happens! The published Blog landing page. Whoa! The blog posts are already showing up! What is this magic? Well, remember that this is a parent page type -and the blog posts were children of this page. The option to "show children" is already pre-selected in the edit mode +and the blog posts were children of this page. The option to "show children" is already preselected in the edit mode for landing pages. Let's look at that now. Ways to display sub-pages on a landing page diff --git a/docs/releases/index.rst b/docs/releases/index.rst index ad0f78b6..d2914dcd 100644 --- a/docs/releases/index.rst +++ b/docs/releases/index.rst @@ -35,6 +35,7 @@ Supported Versions: .. toctree:: :maxdepth: 1 + v6.0.1 v6.0.0 v5.0.2 v5.0.1 diff --git a/docs/releases/v6.0.1.rst b/docs/releases/v6.0.1.rst new file mode 100644 index 00000000..60080b5a --- /dev/null +++ b/docs/releases/v6.0.1.rst @@ -0,0 +1,21 @@ +v6.0.1 release notes +==================== + + +Bug fixes +--------- + +* Fixed a 404 error when viewing form submissions in the Wagtail admin. Wagtail + 7.x guards its admin submissions view with ``isinstance(page, FormMixin)`` and + now calls ``page.get_submissions()``, which CodeRed form pages did not + satisfy. ``CoderedFormPage`` and ``CoderedStreamFormPage`` now inherit + Wagtail's ``FormMixin`` (last in the MRO, so existing behavior is unchanged), + restoring the submissions view for both standard and advanced form pages. + (`#710 `_) + + +Thank you! +---------- + +Thanks to everyone who contributed to `6.0.1 on GitHub +`_.