From 213b769d991dd28c4fe0c645262e5847f0370895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= Date: Fri, 16 Oct 2020 11:11:23 +0200 Subject: [PATCH] cards: check on form import if carddef custom view exists (#47780) --- tests/test_formdef_import.py | 24 ++++++++++++++++++++++++ wcs/formdef.py | 27 ++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/tests/test_formdef_import.py b/tests/test_formdef_import.py index 7a1d355a3..b10465e0b 100644 --- a/tests/test_formdef_import.py +++ b/tests/test_formdef_import.py @@ -378,6 +378,7 @@ def test_unknown_data_source(): with pytest.raises(FormdefImportError, match='Unknown datasources'): FormDef.import_from_xml(BytesIO(export)) + # carddef as datasource carddef = CardDef() carddef.name = 'foo' carddef.fields = [ @@ -398,6 +399,29 @@ def test_unknown_data_source(): with pytest.raises(FormdefImportError): FormDef.import_from_xml(BytesIO(export)) + # carddef custom view as datasource + pub.custom_view_class.wipe() + custom_view = pub.custom_view_class() + custom_view.title = 'card view' + custom_view.formdef = carddef + custom_view.columns = {'list': [{'id': 'id'}]} + custom_view.filters = {} + custom_view.visibility = 'datasource' + custom_view.store() + + formdef.fields = [fields.StringField( + id='1', type='string', + data_source={'type': 'carddef:foo:card-view'})] + export = ET.tostring(export_to_indented_xml(formdef)) + FormDef.import_from_xml(BytesIO(export)) + + formdef.fields = [fields.StringField( + id='1', type='string', + data_source={'type': 'carddef:foo:unknown'})] + export = ET.tostring(export_to_indented_xml(formdef)) + with pytest.raises(FormdefImportError): + FormDef.import_from_xml(BytesIO(export)) + def test_duplicated_field_ids(): formdef = FormDef() diff --git a/wcs/formdef.py b/wcs/formdef.py index e8972acfc..1807e9e70 100644 --- a/wcs/formdef.py +++ b/wcs/formdef.py @@ -33,7 +33,7 @@ from quixote import get_request, get_publisher from quixote.http_request import Upload from .qommon import _, N_, force_str, PICKLE_KWARGS -from .qommon.storage import StorableObject, fix_key +from .qommon.storage import StorableObject, fix_key, Equal from .qommon.cron import CronJob from .qommon.form import * from .qommon.misc import simplify, get_as_datetime, xml_node_text @@ -1044,19 +1044,36 @@ class FormDef(StorableObject): for field in formdef.fields: data_source = getattr(field, 'data_source', None) if data_source: + data_source_id = data_source.get('type') if isinstance(data_sources.get_object(data_source), data_sources.StubNamedDataSource): - unknown_datasources.add(data_source.get('type')) - elif data_source.get('type') and data_source.get('type').startswith('carddef:'): + unknown_datasources.add(data_source_id) + elif data_source_id and data_source_id.startswith('carddef:'): + parts = data_source_id.split(':') # check if carddef exists - url_name = data_source['type'][8:] + url_name = parts[1] if formdef.xml_root_node == 'carddef' and formdef.url_name == url_name: # reference to itself, it's ok continue try: CardDef.get_by_urlname(url_name) except KeyError: - unknown_datasources.add(data_source.get('type')) + unknown_datasources.add(data_source_id) + continue + + if len(parts) == 2: + continue + + lookup_criterias = [ + Equal('formdef_type', 'carddef'), + Equal('visibility', 'datasource'), + Equal('slug', parts[2]), + ] + try: + get_publisher().custom_view_class.select(lookup_criterias)[0] + except IndexError: + unknown_datasources.add(data_source_id) + if unknown_datasources: raise FormdefImportError(N_('Unknown datasources'), details=', '.join(sorted(unknown_datasources)))