From d457fda27b05814734cb0a8346c675b4c3480eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sun, 6 Aug 2023 15:53:05 +0200 Subject: [PATCH] misc: handle submission of form that is unexpectedly no longer valid (#67561) --- tests/form_pages/test_all.py | 27 +++++++++++++++++++++++++++ wcs/forms/root.py | 11 ++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/tests/form_pages/test_all.py b/tests/form_pages/test_all.py index ac6208734..8b7c25155 100644 --- a/tests/form_pages/test_all.py +++ b/tests/form_pages/test_all.py @@ -2559,6 +2559,33 @@ def test_form_tracking_code_as_variable(pub, nocache): assert '!%s!' % tracking_code in resp.text +def test_form_invalid_previous_data(pub): + create_user(pub) + formdef = create_formdef() + formdef.fields = [fields.DateField(id='0', label='date')] + formdef.enable_tracking_codes = True + formdef.store() + + resp = login(get_app(pub), username='foo', password='foo').get('/test/') + formdef.data_class().wipe() + tracking_code = get_displayed_tracking_code(resp) + assert tracking_code is not None + resp.forms[0]['f0'] = time.strftime('%Y-%m-%d', time.localtime()) + resp = resp.forms[0].submit('submit') # -> validation page + + formdef.fields[0].minimum_is_future = True + formdef.store() + + # load the formdata as a draft + resp = login(get_app(pub), username='foo', password='foo').get('/') + resp.forms[0]['code'] = tracking_code + resp = resp.forms[0].submit().follow().follow().follow() + assert resp.forms[1]['f0'].value == time.strftime('%Y-%m-%d', time.localtime()) + resp = resp.forms[1].submit('submit') # -> submit + assert 'This form has already been submitted.' not in resp.text + assert 'Unexpected field error' in resp.text + + def test_form_draft_with_file(pub): create_user(pub) formdef = create_formdef() diff --git a/wcs/forms/root.py b/wcs/forms/root.py index 83d21854a..07a3b27ba 100644 --- a/wcs/forms/root.py +++ b/wcs/forms/root.py @@ -1433,9 +1433,14 @@ class FormPage(FormdefDirectoryBase, FormTemplateMixin): return self.validating(form_data) if form.has_errors(): - # the only possible error here is a token error if the form is - # submitted a second time - return template.error_page(_('This form has already been submitted.')) + if form.get_widget(form.TOKEN_NAME).has_error(): + # Token error if the form is submitted a second time + return template.error_page(_('This form has already been submitted.')) + # Something else, typically this means a draft has been loaded and + # the field checks are no longer ok (for example a check on "date must be + # after today"). Push back user to the first page to correct the errors + get_session().message = ('error', _('Unexpected field error, please check.')) + return self.page(self.pages[0]) try: return self.submitted(form, existing_formdata) -- 2.39.2