cards: check on form import if carddef custom view exists (#47780)

This commit is contained in:
Lauréline Guérin 2020-10-16 11:11:23 +02:00
parent 3f4d868db2
commit 213b769d99
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 46 additions and 5 deletions

View File

@ -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()

View File

@ -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)))