107 lines
3.4 KiB
Python
107 lines
3.4 KiB
Python
# passerelle - uniform access to multiple data sources and services
|
|
# Copyright (C) 2019 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import xml.etree.ElementTree as ET
|
|
from collections import OrderedDict
|
|
from decimal import Decimal
|
|
|
|
import jsonschema
|
|
import xmlschema
|
|
|
|
from passerelle.utils.json import flatten, flatten_json_schema, unflatten
|
|
from passerelle.utils.xml import JSONSchemaFromXMLSchema, text_content, to_json
|
|
|
|
|
|
def test_text_content():
|
|
root = ET.fromstring('<root>aa<b>bb</b>cc</root>')
|
|
assert text_content(root) == 'aabbcc'
|
|
|
|
|
|
def test_to_json():
|
|
root = ET.fromstring(
|
|
'''<root>
|
|
<text1>1</text1>
|
|
<text2>2</text2>
|
|
<enfants>
|
|
<enfant>
|
|
<text3>3</text3>
|
|
</enfant>
|
|
<enfant>
|
|
<text3>4</text3>
|
|
</enfant>
|
|
<zob/>
|
|
</enfants>
|
|
<zob/>
|
|
</root>'''
|
|
)
|
|
assert to_json(root) == {
|
|
'text1': '1',
|
|
'text2': '2',
|
|
'enfants': [
|
|
{'text3': '3'},
|
|
{'text3': '4'},
|
|
],
|
|
}
|
|
|
|
|
|
def test_xmlschema_to_jsonschema():
|
|
schema_path = 'tests/exemple.xsd'
|
|
|
|
# go from XML to JSON,
|
|
# convert XMLSchema to JSONSchema
|
|
# validate jsonschema, on converted data,
|
|
# flatten the JSON schema,
|
|
# flatten the data,
|
|
# validate flattened data with flatenned JSON schema
|
|
# unflatten data
|
|
# convert unflattened data to XML
|
|
# convert XML to JSON
|
|
# then compare to initially converted JSON data
|
|
schema = xmlschema.XMLSchema(schema_path, converter=xmlschema.UnorderedConverter)
|
|
json_schema = JSONSchemaFromXMLSchema(schema, 'PACS')
|
|
d = schema.elements['PACS'].decode(ET.parse('tests/data/pacs-doc.xml').getroot())
|
|
d = {'PACS': d}
|
|
json_schema.validate(d)
|
|
flattened_json_schema = flatten_json_schema(json_schema.json_schema)
|
|
flattened_d = flatten(d)
|
|
jsonschema.validate(instance=flattened_d, schema=flattened_json_schema)
|
|
d2 = unflatten(d)
|
|
json_schema.validate(d2)
|
|
|
|
tree = schema.elements['PACS'].encode(d2['PACS'], converter=xmlschema.UnorderedConverter)
|
|
d3 = schema.elements['PACS'].decode(tree)
|
|
assert d == {'PACS': d3}
|
|
|
|
assert json_schema.json_schema['properties']['PACS']['properties']['testSimpleContent'] == OrderedDict(
|
|
[
|
|
('type', 'object'),
|
|
(
|
|
'properties',
|
|
OrderedDict(
|
|
[
|
|
(
|
|
'$',
|
|
OrderedDict(
|
|
[('type', 'integer'), ('minimum', Decimal('0')), ('maximum', Decimal('1000'))]
|
|
),
|
|
),
|
|
('attribute', {'type': 'string'}),
|
|
]
|
|
),
|
|
),
|
|
]
|
|
)
|