diff --git a/tests/form_pages/test_all.py b/tests/form_pages/test_all.py index 7e2a3c547..248a3c372 100644 --- a/tests/form_pages/test_all.py +++ b/tests/form_pages/test_all.py @@ -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) diff --git a/wcs/forms/root.py b/wcs/forms/root.py index 2a1e105bb..5a0578c10 100644 --- a/wcs/forms/root.py +++ b/wcs/forms/root.py @@ -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