From af3649dd27a6a0ef811c427feacb8ae2c1ecfd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 19 Oct 2018 16:03:16 +0200 Subject: [PATCH 1/2] forms: always enable drafts (#27476) --- tests/test_form_pages.py | 18 ++++----- wcs/api.py | 2 +- wcs/forms/root.py | 79 +++++++++++++++++++++++----------------- wcs/qommon/sessions.py | 6 +++ 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index 24aae2eca..838c95cf3 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -1694,12 +1694,6 @@ def test_form_direct_draft_access(pub): formdata.store() resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403) - formdata.user_id = user.id - formdata.store() - formdef.enable_tracking_codes = False - formdef.store() - resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403) - def form_password_field_submit(pub, password): password = unicode(password).encode(pub.site_charset) formdef = create_formdef() @@ -1938,7 +1932,7 @@ def test_preview_form(pub): next_page = next_page.forms[0].submit('submit') assert next_page.status_int == 302 assert next_page.location == 'http://example.net/preview/test/' - assert formdef.data_class().count() == 0 + assert len([x for x in formdef.data_class().select() if not x.is_draft()]) == 0 def test_form_item_data_source_field_submit(pub): def submit_item_data_source_field(ds): @@ -4395,8 +4389,9 @@ def test_form_page_profile_verified_prefill(pub): resp.form['f0'].value = 'Hello' # try again changing the value resp = resp.form.submit('submit') - assert formdef.data_class().count() == 1 - assert formdef.data_class().select()[0].data['0'] == 'foo@localhost' + formdatas = [x for x in formdef.data_class().select() if not x.is_draft()] + assert len(formdatas) == 1 + assert formdatas[0].data['0'] == 'foo@localhost' resp = login(get_app(pub), username='foo', password='foo').get('/test/') assert resp.form['f0'].value == 'foo@localhost' @@ -4451,8 +4446,9 @@ def test_form_page_profile_verified_date_prefill(pub): resp.form['f0'].value = '2018-09-24' # try again changing the value resp = resp.form.submit('submit') - assert formdef.data_class().count() == 1 - assert time.strftime('%Y-%m-%d', formdef.data_class().select()[0].data['0']) == '2018-09-27' + formdatas = [x for x in formdef.data_class().select() if not x.is_draft()] + assert len(formdatas) == 1 + assert time.strftime('%Y-%m-%d', formdatas[0].data['0']) == '2018-09-27' def test_form_page_profile_verified_radio_item_prefill(pub): user = create_user(pub) diff --git a/wcs/api.py b/wcs/api.py index d0a55afdb..7cc12f1e4 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -585,7 +585,7 @@ class ApiUserDirectory(Directory): if form.is_draft(): if not include_drafts: continue - if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes: + if form.formdef.is_disabled(): # the form or its draft support has been disabled continue elif not include_non_drafts: diff --git a/wcs/forms/root.py b/wcs/forms/root.py index 4d3c4f991..a21866e47 100644 --- a/wcs/forms/root.py +++ b/wcs/forms/root.py @@ -232,6 +232,14 @@ class FormPage(Directory, FormTemplateMixin): return True return False + def has_draft_support(self): + if self.edit_mode: + return False + if self.formdef.enable_tracking_codes: + return True + session = get_session() + return session.has_user() + def step(self, step_no, current_page): get_logger().info('form %s - step %s' % (self.formdef.name, step_no)) @@ -284,7 +292,7 @@ class FormPage(Directory, FormTemplateMixin): magictoken = get_request().form.get('magictoken') if magictoken: form_data = session.get_by_magictoken(magictoken, {}) - if self.formdef.enable_tracking_codes and not self.edit_mode: + if self.has_draft_support(): form.attrs['data-has-draft'] = 'yes' else: form_data = {} @@ -398,7 +406,7 @@ class FormPage(Directory, FormTemplateMixin): form.add_hidden('page_id', page.id) form.add_submit('cancel', _('Cancel'), css_class = 'cancel') - if self.formdef.enable_tracking_codes and not self.edit_mode: + if self.has_draft_support(): form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft', attrs={'style': 'display: none'}) @@ -408,7 +416,7 @@ class FormPage(Directory, FormTemplateMixin): 'form_side': lambda: self.form_side(0, page, data=data, magictoken=magictoken), 'steps': lambda: self.step(0, page), } - if self.formdef.enable_tracking_codes and data: + if self.has_draft_support() and data: context['tracking_code_box'] = lambda: self.tracking_code_box(data, magictoken) return template.QommonTemplateResponse( @@ -420,7 +428,7 @@ class FormPage(Directory, FormTemplateMixin): (tracking code and steps).''' r = TemplateIO(html=True) r += htmltext('
') - if self.formdef.enable_tracking_codes and data: + if self.has_draft_support() and data: # display tracking code box if they are enabled and there's some # data (e.g. the user is not on a insufficient authenticiation # context page) @@ -431,25 +439,28 @@ class FormPage(Directory, FormTemplateMixin): def tracking_code_box(self, data, magictoken): '''Create the tracking code box, it displays the current tracking code - and a 'remove draft' button if the current form is a draft that has - been recalled.''' + if enabled, and a 'remove draft' button if the current form is a draft + that has been recalled.''' r = TemplateIO(html=True) r += htmltext('
') - r += htmltext('

%s

') % _('Tracking code') + if self.formdef.enable_tracking_codes: + r += htmltext('
') + r += htmltext('

%s

') % _('Tracking code') - tracking_code = None - draft_formdata_id = data.get('draft_formdata_id') - if draft_formdata_id: - formdata = self.formdef.data_class().get(draft_formdata_id) - tracking_code = formdata.tracking_code - else: - tracking_code = data.get('future_tracking_code') + tracking_code = None + draft_formdata_id = data.get('draft_formdata_id') + if draft_formdata_id: + formdata = self.formdef.data_class().get(draft_formdata_id) + tracking_code = formdata.tracking_code + else: + tracking_code = data.get('future_tracking_code') - if tracking_code: - get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js']) - r += htmltext('%s') % ( - 'code/%s/' % tracking_code, tracking_code) - r += TextsDirectory.get_html_text('tracking-code-short-text') + if tracking_code: + get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js']) + r += htmltext('%s') % ( + 'code/%s/' % tracking_code, tracking_code) + r += TextsDirectory.get_html_text('tracking-code-short-text') + r += htmltext('
') # if data.get('is_recalled_draft'): r += htmltext('
') @@ -557,7 +568,7 @@ class FormPage(Directory, FormTemplateMixin): # [session_var_id] is available on the first page. session.force() - if self.formdef.enable_tracking_codes: + if self.has_draft_support(): if get_request().form.get('_ajax_form_token'): # _ajax_form_token is immediately removed, this prevents # late autosave() to overwrite data after the user went to a @@ -590,7 +601,7 @@ class FormPage(Directory, FormTemplateMixin): # first hit on first page, if tracking code are enabled and we # are not editing an existing formdata, generate a new tracking # code. - if not self.edit_mode and self.formdef.enable_tracking_codes and not get_request().form.has_key('mt'): + if not self.edit_mode and self.has_draft_support() and not get_request().form.has_key('mt'): tracking_code = get_publisher().tracking_code_class() tracking_code.store() token = randbytes(8) @@ -620,7 +631,7 @@ class FormPage(Directory, FormTemplateMixin): form.add_hidden('magictoken', '-1') form.add_submit('cancel') - if self.formdef.enable_tracking_codes: + if self.has_draft_support(): form.add_submit('removedraft') form.add_submit('savedraft') @@ -721,21 +732,21 @@ class FormPage(Directory, FormTemplateMixin): displayed_fields=submitted_fields, transient_formdata=transient_formdata) form.add_submit('previous') - if self.formdef.enable_tracking_codes: + if self.has_draft_support(): form.add_submit('removedraft') form.add_submit('savedraft') form.add_submit('submit') if page_no > 0 and form.get_submit() == 'previous': return self.previous_page(page_no, magictoken) - if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft': + if self.has_draft_support() and form.get_submit() == 'removedraft': return self.removedraft() form_data = session.get_by_magictoken(magictoken, {}) data = self.formdef.get_data(form) form_data.update(data) - if self.formdef.enable_tracking_codes and form.get_submit() == 'savedraft': + if self.has_draft_support() and form.get_submit() == 'savedraft': filled = self.save_draft(form_data, page_no) return redirect(filled.get_url().rstrip('/')) @@ -794,8 +805,8 @@ class FormPage(Directory, FormTemplateMixin): get_session().message = ('error', _('This form has already been submitted.')) return redirect(get_publisher().get_backoffice_url() + '/submission/') return template.error_page(_('This form has already been submitted.')) - elif self.formdef.enable_tracking_codes and not self.edit_mode: - # if there's no draft yet and tracking codes are enabled, create one + elif self.has_draft_support(): + # if there's no draft yet and drafts are supported, create one filled = self.save_draft(form_data, page_no) # the page has been successfully submitted, maybe new pages @@ -826,7 +837,7 @@ class FormPage(Directory, FormTemplateMixin): form.add_hidden('page', '-1') form.add_hidden('magictoken', '-1') form.add_submit('cancel') - if self.formdef.enable_tracking_codes: + if self.has_draft_support(): form.add_submit('removedraft') form.add_submit('savedraft') @@ -861,10 +872,10 @@ class FormPage(Directory, FormTemplateMixin): if form.get_submit() == 'previous': return self.previous_page(len(self.pages), magictoken) - if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft': + if self.has_draft_support() and form.get_submit() == 'removedraft': return self.removedraft() - if self.formdef.enable_tracking_codes and form.get_submit() == 'savedraft': + if self.has_draft_support() and form.get_submit() == 'savedraft': filled = self.save_draft(form_data, page_no = -1) return redirect(filled.get_url().rstrip('/')) @@ -1110,7 +1121,7 @@ class FormPage(Directory, FormTemplateMixin): return redirect(url) def set_tracking_code(self, formdata, magictoken_data=None): - if not self.formdef.enable_tracking_codes: + if not self.has_draft_support(): return if formdata.tracking_code: return @@ -1181,7 +1192,7 @@ class FormPage(Directory, FormTemplateMixin): form.add_submit('previous', _('Previous')) form.add_submit('cancel', _('Cancel'), css_class = 'cancel') session = get_session() - if self.formdef.enable_tracking_codes: + if self.has_draft_support(): form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft', attrs={'style': 'display: none'}) form.add_hidden('step', '2') @@ -1195,7 +1206,7 @@ class FormPage(Directory, FormTemplateMixin): magictoken=magictoken), 'steps': lambda: self.step(1, None), } - if self.formdef.enable_tracking_codes and data: + if self.has_draft_support() and data: context['tracking_code_box'] = lambda: self.tracking_code_box(data, magictoken) return template.QommonTemplateResponse( @@ -1230,7 +1241,7 @@ class FormPage(Directory, FormTemplateMixin): return redirect(get_publisher().get_backoffice_url() + '/submission/') return PublicFormStatusPage(self.formdef, filled) - if not (get_request().is_in_backoffice() or filled.formdef.enable_tracking_codes): + if not (get_request().is_in_backoffice() or self.has_draft_support()): # don't allow restoring drafts if drafts are no longer enabled for # this form. raise errors.AccessForbiddenError() diff --git a/wcs/qommon/sessions.py b/wcs/qommon/sessions.py index 2b2d7f2ae..bb09edc38 100644 --- a/wcs/qommon/sessions.py +++ b/wcs/qommon/sessions.py @@ -195,6 +195,12 @@ class Session(QommonSession, CaptchaSession, StorableObject): except OSError: pass + def has_user(self): + user_id = QuixoteSession.get_user(self) + if user_id and not str(user_id).startswith('anonymous-'): + return True + return False + def get_user(self): user_id = QuixoteSession.get_user(self) if user_id: -- 2.19.1