From 31ff9f2f9ac07664086ca5c911c436fc42e638ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Mon, 24 Aug 2020 13:33:43 +0200 Subject: [PATCH] api: include first value for a repeated varname (#42468) --- tests/test_api.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++ wcs/formdata.py | 7 +++++ 2 files changed, 72 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 8e1dd3cb8..d53e37883 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1259,6 +1259,71 @@ def test_formdata_backoffice_fields(pub, local_user): assert resp.json['workflow']['fields']['backoffice_blah'] == 'Hello world' +def test_formdata_duplicated_varnames(pub, local_user): + Role.wipe() + role = Role(name='test') + role.id = '123' + role.store() + another_role = Role(name='another') + another_role.id = '321' + another_role.store() + FormDef.wipe() + formdef = FormDef() + formdef.geolocations = {'base': 'blah'} + formdef.name = 'test' + formdef.fields = [ + fields.StringField(id='0', label='foobar', varname='foobar'), + fields.StringField(id='1', label='foobar2', varname='foobar'), + ] + workflow = Workflow.get_default_workflow() + workflow.roles['_foobar'] = 'Foobar' + workflow.id = '2' + workflow.store() + formdef.workflow_id = workflow.id + formdef.workflow_roles = {'_receiver': role.id, + '_foobar': another_role.id} + formdef.store() + + formdef.data_class().wipe() + formdata = formdef.data_class()() + formdata.data = { + '0': 'foo', + '1': 'bar', + } + formdata.user_id = local_user.id + formdata.just_created() + formdata.status = 'wf-new' + formdata.evolution[-1].status = 'wf-new' + formdata.store() + + local_user.roles = [role.id] + local_user.store() + resp = get_app(pub).get( + sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user), + status=200) + assert resp.json['fields'] == {'foobar': 'foo'} + + formdata.data = { + '0': 'foo', + '1': '', + } + formdata.store() + resp = get_app(pub).get( + sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user), + status=200) + assert resp.json['fields'] == {'foobar': 'foo'} + + formdata.data = { + '0': '', + '1': 'foo', + } + formdata.store() + resp = get_app(pub).get( + sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user), + status=200) + assert resp.json['fields'] == {'foobar': 'foo'} + + def test_formdata_edit(pub, local_user): test_formdata(pub, local_user) formdef = FormDef.select()[0] diff --git a/wcs/formdata.py b/wcs/formdata.py index 17c35d341..f240af288 100644 --- a/wcs/formdata.py +++ b/wcs/formdata.py @@ -1025,17 +1025,24 @@ class FormData(StorableObject): def get_json_dict(self, fields, include_files=True, anonymise=False): new_data = {} + seen = set() for field in fields: if anonymise and field.anonymise: continue if not field.varname: # exports only named fields continue + if field.varname in seen: + # skip fields with a varname that is used by another non-empty + # field. + continue if self.data is not None: value = self.data.get(field.id) if value and hasattr(field, 'get_json_value'): value = field.get_json_value(value, formdata=self, include_file_content=include_files) else: value = None + if value: + seen.add(field.varname) if field.store_display_value: new_data[field.varname + '_raw'] = value new_data[field.varname] = self.data.get('%s_display' % field.id)