misc: keep at most 5 drafts per form&user (#51726) #862

Merged
fpeters merged 1 commits from wip/51726-max-drafts into main 2023-11-24 09:13:42 +01:00
2 changed files with 47 additions and 0 deletions

View File

@ -1,3 +1,4 @@
import datetime
import hashlib
import json
import os
@ -4893,6 +4894,45 @@ def test_form_recall_draft(pub):
assert 'href="%s/"' % draft2.id in resp.text
def test_form_max_drafts(pub):
user = create_user(pub)
formdef = create_formdef()
formdef.fields = [fields.StringField(id='0', label='string')]
formdef.store()
formdef.data_class().wipe()
# create another draft, not linked to user, to check it's not deleted
another_draft = formdef.data_class()()
another_draft.status = 'draft'
another_draft.receipt_time = datetime.datetime(2023, 11, 23, 0, 0).timetuple()
another_draft.store()
drafts = []
for i in range(4):
draft = formdef.data_class()()
draft.user_id = user.id
draft.status = 'draft'
draft.receipt_time = datetime.datetime(2023, 11, 23, 0, i).timetuple()
draft.store()
drafts.append(draft)
app = login(get_app(pub), username='foo', password='foo')
resp = app.get('/test/')
assert resp.pyquery('.drafts-recall a').length == 4
resp.form['f0'] = 'hello'
resp = resp.form.submit('submit')
assert formdef.data_class().count([Equal('status', 'draft')]) == 6
resp = app.get('/test/')
assert resp.pyquery('.drafts-recall a').length == 5
resp.form['f0'] = 'hello2'
resp = resp.form.submit('submit')
assert formdef.data_class().count([Equal('status', 'draft')]) == 6
assert not formdef.data_class().has_key(drafts[0].id) # oldest draft was removed
def test_choice_button_ignore_form_errors(pub):
create_user(pub)

View File

@ -1683,6 +1683,13 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
if not filled.user_id:
if get_session().mark_anonymous_formdata(filled):
get_session().store()
elif new_draft:
# keep at most 5 drafts per user
data_class = self.formdef.data_class()
for id in data_class.get_sorted_ids(
'-last_update_time', [Equal('status', 'draft'), Equal('user_id', str(filled.user_id))]
)[5:]:
data_class.remove_object(id)
if new_draft:
data['draft_formdata_id'] = filled.id