misc: store page id on drafts (#85091)

This commit is contained in:
Emmanuel Cazenave 2024-01-19 16:38:40 +01:00
parent 2f2b996066
commit a6c0e8aa59
3 changed files with 432 additions and 0 deletions

View File

@ -688,6 +688,163 @@ def test_backoffice_submission_remove_drafts(pub):
resp = app.get('/backoffice/submission/form-title/remove/%s' % formdata.id, status=403)
def test_backoffice_submission_drafts_store_page_id(pub, autosave):
user = create_user(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.PageField(id='0', label='1st page'),
fields.StringField(id='1', label='string 1'),
fields.PageField(id='2', label='2nd page'),
fields.StringField(id='3', label='string 2'),
fields.PageField(id='4', label='3rd page'),
fields.StringField(id='5', label='string 3'),
]
formdef.backoffice_submission_roles = user.roles[:]
formdef.workflow_roles = {'_receiver': 1}
formdef.enable_tracking_codes = True
formdef.store()
first_page_id = formdef.fields[0].id
second_page_id = formdef.fields[2].id
third_page_id = formdef.fields[4].id
data_class = formdef.data_class()
data_class.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/submission/')
resp = resp.click(formdef.name)
resp.form['f1'] = 'test'
app.post('/backoffice/submission/form-title/autosave', params=resp.form.submit_fields())
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == first_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# first page submitted, the draft in on the seconde page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp.form['f3'] = 'foo'
# autosave
app.post('/backoffice/submission/form-title/autosave', params=resp.form.submit_fields())
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# second page submitted, the draft in on the third page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp.form['f5'] = 'bar'
# autosave
app.post('/backoffice/submission/form-title/autosave', params=resp.form.submit_fields())
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
resp = resp.form.submit('submit')
# third page submitted, the draft in on the confirmation page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '3'
assert formdata.page_id == '_confirmation_page'
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
resp = resp.form.submit('previous')
# back to third page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
def test_backoffice_submission_drafts_store_page_id_when_no_page(pub, autosave):
user = create_user(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.StringField(id='1', label='string 1'),
fields.StringField(id='2', label='string 2'),
]
formdef.backoffice_submission_roles = user.roles[:]
formdef.workflow_roles = {'_receiver': 1}
formdef.enable_tracking_codes = True
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/submission/')
resp = resp.click(formdef.name)
resp.form['f1'] = 'test'
resp.form['f2'] = 'bar'
# autosave
app.post('/backoffice/submission/form-title/autosave', params=resp.form.submit_fields())
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == '_first_page'
assert formdata.data['1'] == 'test'
assert formdata.data['2'] == 'bar'
resp = resp.form.submit('submit')
# fields submitted, the draft in on the confirmation page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == '_confirmation_page'
assert formdata.data['1'] == 'test'
# back to first page
resp = resp.form.submit('previous')
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == '_first_page'
assert formdata.data['1'] == 'test'
def test_backoffice_submission_live_condition(pub):
user = create_user(pub)

View File

@ -549,3 +549,266 @@ def test_nothing_to_update_add_row(pub):
sql_data_store.side_effect = NothingToUpdate
resp = resp.form.submit('f2$add_element').follow()
assert 'Technical error saving draft, please try again.' in resp.text
def test_draft_store_page_id(pub):
formdef = create_formdef()
formdef.enable_tracking_codes = True
formdef.fields = [
fields.PageField(id='0', label='1st page'),
fields.StringField(id='1', label='string 1'),
fields.PageField(id='2', label='2nd page'),
fields.StringField(id='3', label='string 2'),
fields.PageField(id='4', label='3rd page'),
fields.StringField(id='5', label='string 3'),
]
formdef.store()
first_page_id = formdef.fields[0].id
second_page_id = formdef.fields[2].id
third_page_id = formdef.fields[4].id
formdef.data_class().wipe()
app = get_app(pub)
resp = app.get('/test/')
resp.form['f1'] = 'test'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == first_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# first page submitted, the draft in on the seconde page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp.form['f3'] = 'foo'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# second page submitted, the draft in on the third page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp.form['f5'] = 'bar'
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
resp = resp.form.submit('submit')
# third page submitted, the draft in on the confirmation page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '3'
assert formdata.page_id == '_confirmation_page'
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
resp = resp.form.submit('previous')
# back to third page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
def test_draft_store_page_id_no_confirmation(pub):
formdef = create_formdef()
formdef.enable_tracking_codes = True
formdef.fields = [
fields.PageField(id='0', label='1st page'),
fields.StringField(id='1', label='string 1'),
fields.PageField(id='2', label='2nd page'),
fields.StringField(id='3', label='string 2'),
fields.PageField(id='4', label='3rd page'),
fields.StringField(id='5', label='string 3'),
]
formdef.confirmation = False
formdef.store()
first_page_id = formdef.fields[0].id
second_page_id = formdef.fields[2].id
third_page_id = formdef.fields[4].id
formdef.data_class().wipe()
app = get_app(pub)
resp = app.get('/test/')
resp.form['f1'] = 'test'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == first_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# first page submitted, the draft in on the seconde page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] is None
assert formdata.data['5'] is None
resp.form['f3'] = 'foo'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == second_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp = resp.form.submit('submit')
# second page submitted, the draft in on the third page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] is None
resp.form['f5'] = 'bar'
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '2'
assert formdata.page_id == third_page_id
assert formdata.data['1'] == 'test'
assert formdata.data['3'] == 'foo'
assert formdata.data['5'] == 'bar'
resp = resp.form.submit('submit')
# third page submitted, no more draft
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'wf-new'
def test_draft_store_page_id_when_no_page(pub):
formdef = create_formdef()
formdef.enable_tracking_codes = True
formdef.fields = [
fields.StringField(id='1', label='string 1'),
fields.StringField(id='2', label='string 2'),
]
formdef.store()
formdef.data_class().wipe()
app = get_app(pub)
resp = app.get('/test/')
resp.form['f1'] = 'test'
resp.form['f2'] = 'bar'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == '_first_page'
assert formdata.data['1'] == 'test'
assert formdata.data['2'] == 'bar'
resp = resp.form.submit('submit')
# fields submitted, the draft in on the confirmation page
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '1'
assert formdata.page_id == '_confirmation_page'
assert formdata.data['1'] == 'test'
# back to first page
resp = resp.form.submit('previous')
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == '_first_page'
assert formdata.data['1'] == 'test'
def test_draft_store_page_id_when_no_page_and_no_confirmation(pub):
formdef = create_formdef()
formdef.enable_tracking_codes = True
formdef.fields = [
fields.StringField(id='1', label='string 1'),
fields.StringField(id='2', label='string 2'),
]
formdef.confirmation = False
formdef.store()
formdef.data_class().wipe()
app = get_app(pub)
resp = app.get('/test/')
resp.form['f1'] = 'test'
resp.form['f2'] = 'bar'
# autosave
assert app.post('/test/autosave', params=resp.form.submit_fields()).json == {'result': 'success'}
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'draft'
assert formdata.page_no == '0'
assert formdata.page_id == '_first_page'
assert formdata.data['1'] == 'test'
assert formdata.data['2'] == 'bar'
resp = resp.form.submit('submit')
# fields submitted, no more draft
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
assert formdata.status == 'wf-new'

View File

@ -1598,6 +1598,16 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
return redirect(self.formdef.get_submission_url(backoffice=get_request().is_in_backoffice()))
return self.page(previous_page, page_change=True)
def get_page_id(self, page_no):
if page_no < len(self.pages):
if self.pages == [None]:
# form without pages
return '_first_page'
return self.pages[page_no].id
if self.has_confirmation_page():
return '_confirmation_page'
return None
def removedraft(self):
magictoken = get_request().form.get('magictoken')
if magictoken:
@ -1616,6 +1626,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
raise SubmittedDraftException()
formdata.page_no = page_no
formdata.page_id = self.get_page_id(page_no)
formdata.data = form_data
formdata.receipt_time = time.localtime()
if not get_request().is_in_backoffice():
@ -1703,6 +1714,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
filled.status = 'draft'
if page_no is not None:
filled.page_no = page_no
filled.page_id = self.get_page_id(page_no)
filled.receipt_time = time.localtime()
where = [Equal('status', 'draft')] + (where or [])
if get_request().is_in_backoffice():