0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-29 17:36:49 +01:00

Make validation errors on formsets trigger the alwaysDirty flag

When the page edit form is redisplayed on validation errors, we set alwaysDirty on the
dirty form handler logic so that navigating away triggers the unsaved changes warning
even if no further changes are made. However, the old code tested `form.errors`, which
fails to catch validation errors originating from formsets.
This commit is contained in:
Matt Westcott 2016-06-30 20:16:39 +01:00 committed by Karl Hobley
parent c1a2646b10
commit aa9025c798
4 changed files with 66 additions and 2 deletions

View File

@ -83,7 +83,7 @@
{
confirmationMessage: '{{ confirmation_message|escapejs }}',
{% if form.errors %}
{% if has_unsaved_changes %}
alwaysDirty: true,
{% endif %}
}

View File

@ -117,7 +117,7 @@
{
confirmationMessage: '{{ confirmation_message|escapejs }}',
{% if form.errors %}
{% if has_unsaved_changes %}
alwaysDirty: true,
{% endif %}
}

View File

@ -555,6 +555,9 @@ class TestPageCreation(TestCase, WagtailTestUtils):
self.assertFormError(response, 'form', 'go_live_at', "Go live date/time must be before expiry date/time")
self.assertFormError(response, 'form', 'expire_at', "Go live date/time must be before expiry date/time")
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")
def test_create_simplepage_scheduled_expire_in_the_past(self):
post_data = {
'title': "New page!",
@ -571,6 +574,9 @@ class TestPageCreation(TestCase, WagtailTestUtils):
# Check that a form error was raised
self.assertFormError(response, 'form', 'expire_at', "Expiry date/time must be in the future")
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")
def test_create_simplepage_post_publish(self):
# Connect a mock signal handler to page_published signal
mock_handler = mock.MagicMock()
@ -698,6 +704,9 @@ class TestPageCreation(TestCase, WagtailTestUtils):
# Check that a form error was raised
self.assertFormError(response, 'form', 'slug', "This slug is already in use")
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")
def test_create_nonexistantparent(self):
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', 100000)))
self.assertEqual(response.status_code, 404)
@ -1043,6 +1052,9 @@ class TestPageEdit(TestCase, WagtailTestUtils):
self.assertFormError(response, 'form', 'go_live_at', "Go live date/time must be before expiry date/time")
self.assertFormError(response, 'form', 'expire_at', "Go live date/time must be before expiry date/time")
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")
def test_edit_scheduled_expire_in_the_past(self):
post_data = {
'title': "I've been edited!",
@ -1057,6 +1069,9 @@ class TestPageEdit(TestCase, WagtailTestUtils):
# Check that a form error was raised
self.assertFormError(response, 'form', 'expire_at', "Expiry date/time must be in the future")
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")
def test_page_edit_post_publish(self):
# Connect a mock signal handler to page_published signal
mock_handler = mock.MagicMock()
@ -2848,6 +2863,27 @@ class TestChildRelationsOnSuperclass(TestCase, WagtailTestUtils):
self.assertEqual(page.advert_placements.count(), 1)
self.assertEqual(page.advert_placements.first().advert.text, 'test_advert')
def test_post_create_form_with_validation_error_in_formset(self):
post_data = {
'title': "New index!",
'slug': 'new-index',
'advert_placements-TOTAL_FORMS': '1',
'advert_placements-INITIAL_FORMS': '0',
'advert_placements-MAX_NUM_FORMS': '1000',
'advert_placements-0-advert': '1',
'advert_placements-0-colour': '', # should fail as colour is a required field
'advert_placements-0-id': '',
}
response = self.client.post(
reverse('wagtailadmin_pages:add', args=('tests', 'standardindex', self.root_page.id)), post_data
)
# Should remain on the edit page with a validation error
self.assertEqual(response.status_code, 200)
self.assertContains(response, "This field is required.")
# form should be marked as having unsaved changes
self.assertContains(response, "alwaysDirty: true")
def test_get_edit_form(self):
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.index_page.id, )))
self.assertEqual(response.status_code, 200)
@ -2885,6 +2921,26 @@ class TestChildRelationsOnSuperclass(TestCase, WagtailTestUtils):
self.assertEqual(page.advert_placements.all()[0].advert.text, 'test_advert')
self.assertEqual(page.advert_placements.all()[1].advert.text, 'test_advert')
def test_post_edit_form_with_validation_error_in_formset(self):
post_data = {
'title': "My lovely index",
'slug': 'my-lovely-index',
'advert_placements-TOTAL_FORMS': '1',
'advert_placements-INITIAL_FORMS': '1',
'advert_placements-MAX_NUM_FORMS': '1000',
'advert_placements-0-advert': '1',
'advert_placements-0-colour': '',
'advert_placements-0-id': self.index_page.advert_placements.first().id,
'action-publish': "Publish",
}
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.index_page.id, )), post_data)
# Should remain on the edit page with a validation error
self.assertEqual(response.status_code, 200)
self.assertContains(response, "This field is required.")
# form should be marked as having unsaved changes
self.assertContains(response, "alwaysDirty: true")
class TestRevisions(TestCase, WagtailTestUtils):
fixtures = ['test.json']

View File

@ -254,10 +254,12 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
else:
messages.error(request, _("The page could not be created due to validation errors"))
edit_handler = edit_handler_class(instance=page, form=form)
has_unsaved_changes = True
else:
signals.init_new_page.send(sender=create, page=page, parent=parent_page)
form = form_class(instance=page)
edit_handler = edit_handler_class(instance=page, form=form)
has_unsaved_changes = False
return render(request, 'wagtailadmin/pages/create.html', {
'content_type': content_type,
@ -267,6 +269,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
'preview_modes': page.preview_modes,
'form': form,
'next': next_url,
'has_unsaved_changes': has_unsaved_changes,
})
@ -446,9 +449,11 @@ def edit(request, page_id):
if formset.errors
])
)
has_unsaved_changes = True
else:
form = form_class(instance=page)
edit_handler = edit_handler_class(instance=page, form=form)
has_unsaved_changes = False
# Check for revisions still undergoing moderation and warn
if latest_revision and latest_revision.submitted_for_moderation:
@ -462,6 +467,7 @@ def edit(request, page_id):
'preview_modes': page.preview_modes,
'form': form,
'next': next_url,
'has_unsaved_changes': has_unsaved_changes,
})
@ -528,6 +534,7 @@ def preview_on_edit(request, page_id):
'edit_handler': edit_handler,
'preview_modes': page.preview_modes,
'form': form,
'has_unsaved_changes': True,
})
response['X-Wagtail-Preview'] = 'error'
return response
@ -590,6 +597,7 @@ def preview_on_create(request, content_type_app_name, content_type_model_name, p
'edit_handler': edit_handler,
'preview_modes': page.preview_modes,
'form': form,
'has_unsaved_changes': True,
})
response['X-Wagtail-Preview'] = 'error'
return response