Skip to content

Commit 36eae62

Browse files
mamiksikfilak-sap
authored andcommitted
model: enforce policies for unknown refs in Annotation
Fix parser failing while annotation property is pointing to unknown type and annotation policy is set to nonfatal Resolves #67 Closes #68
1 parent b399f8a commit 36eae62

File tree

3 files changed

+102
-4
lines changed

3 files changed

+102
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99
### Added
1010
- Client can be created from local metadata - Jakub Filak
1111

12+
### Fixed
13+
- make sure configured error policies are applied for Annotations referencing
14+
unknown type/member - Martin Miksik
15+
1216
## [1.3.0]
1317

1418
### Added

pyodata/v2/model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,11 +1164,11 @@ def from_etree(schema_nodes, config: Config):
11641164
except KeyError:
11651165
raise RuntimeError(f'Target Property {annotation.proprty_name} '
11661166
f'of {vh_type} as defined in {annotation} does not exist')
1167+
1168+
annotation.proprty = target_proprty
1169+
target_proprty.value_helper = annotation
11671170
except (RuntimeError, PyODataModelError) as ex:
11681171
config.err_policy(ParserError.ANNOTATION).resolve(ex)
1169-
else:
1170-
annotation.proprty = target_proprty
1171-
target_proprty.value_helper = annotation
11721172

11731173
return schema
11741174

tests/test_model_v2.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests for OData Model module"""
22
# pylint: disable=line-too-long,too-many-locals,too-many-statements,invalid-name, too-many-lines, no-name-in-module, expression-not-assigned, pointless-statement
3-
3+
import os
44
from datetime import datetime, timezone
55
from unittest.mock import patch
66
import pytest
@@ -1206,3 +1206,97 @@ def test_enum_value_out_of_range(xml_builder_factory):
12061206
MetadataBuilder(xml).build()
12071207
except PyODataParserError as ex:
12081208
assert str(ex) == f'Value -130 is out of range for type Edm.Byte'
1209+
1210+
1211+
@patch('logging.Logger.warning')
1212+
def test_missing_property_referenced_in_annotation(mock_warning, xml_builder_factory):
1213+
"""Test that correct behavior when non existing property is referenced in annotation"""
1214+
1215+
local_data_property = 'DataType'
1216+
value_list_property = 'Type'
1217+
1218+
schema = """
1219+
<EntityType Name="MasterEntity" sap:content-version="1">
1220+
<Property Name="Data" Type="Edm.String" sap:text="DataName"/>
1221+
<Property Name="DataName" Type="Edm.String" />
1222+
<Property Name="DataType" Type="Edm.String"/>
1223+
</EntityType>
1224+
<EntityType Name="DataEntity" sap:content-version="1" sap:value-list="true" sap:label="Data entities">
1225+
<Property Name="Type" Type="Edm.String" Nullable="false"/>
1226+
</EntityType>
1227+
1228+
<EntityContainer Name="EXAMPLE_SRV" >
1229+
<EntitySet Name="DataValueHelp" EntityType="EXAMPLE_SRV.DataEntity" />
1230+
</EntityContainer>
1231+
1232+
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="EXAMPLE_SRV.MasterEntity/Data">
1233+
<Annotation Term="com.sap.vocabularies.Common.v1.ValueList">
1234+
<Record>
1235+
<PropertyValue Property="CollectionPath" String="DataValueHelp"/>
1236+
<PropertyValue Property="Parameters">
1237+
<Collection>
1238+
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly">
1239+
<PropertyValue Property="LocalDataProperty" PropertyPath="{}"/>
1240+
<PropertyValue Property="ValueListProperty" String="{}"/>
1241+
</Record>
1242+
</Collection>
1243+
</PropertyValue>
1244+
</Record>
1245+
</Annotation>
1246+
</Annotations>
1247+
"""
1248+
1249+
# Test case 1. -> LocalDataProperty is faulty and ValueListProperty is valid
1250+
xml_builder = xml_builder_factory()
1251+
xml_builder.add_schema('EXAMPLE_SRV', schema.format('---', value_list_property))
1252+
xml = xml_builder.serialize()
1253+
1254+
with pytest.raises(RuntimeError) as typ_ex_info:
1255+
MetadataBuilder(xml).build()
1256+
1257+
assert typ_ex_info.value.args[0] == 'ValueHelperParameter(Type) of ValueHelper(MasterEntity/Data) points to ' \
1258+
'an non existing LocalDataProperty --- of EntityType(MasterEntity)'
1259+
1260+
MetadataBuilder(xml, Config(
1261+
default_error_policy=PolicyWarning()
1262+
)).build()
1263+
1264+
assert_logging_policy(mock_warning,
1265+
'RuntimeError',
1266+
'ValueHelperParameter(Type) of ValueHelper(MasterEntity/Data) points to '
1267+
'an non existing LocalDataProperty --- of EntityType(MasterEntity)'
1268+
)
1269+
1270+
# Test case 2. -> LocalDataProperty is valid and ValueListProperty is faulty
1271+
xml_builder = xml_builder_factory()
1272+
xml_builder.add_schema('EXAMPLE_SRV', schema.format(local_data_property, '---'))
1273+
xml = xml_builder.serialize()
1274+
1275+
with pytest.raises(RuntimeError) as typ_ex_info:
1276+
MetadataBuilder(xml).build()
1277+
1278+
assert typ_ex_info.value.args[0] == 'ValueHelperParameter(---) of ValueHelper(MasterEntity/Data) points to an non ' \
1279+
'existing ValueListProperty --- of EntityType(DataEntity)'
1280+
1281+
MetadataBuilder(xml, Config(
1282+
default_error_policy=PolicyWarning()
1283+
)).build()
1284+
1285+
assert_logging_policy(mock_warning,
1286+
'RuntimeError',
1287+
'ValueHelperParameter(---) of ValueHelper(MasterEntity/Data) points to an non '
1288+
'existing ValueListProperty --- of EntityType(DataEntity)'
1289+
)
1290+
1291+
# Test case 3. -> LocalDataProperty is valid and ValueListProperty is also valid
1292+
xml_builder = xml_builder_factory()
1293+
xml_builder.add_schema('EXAMPLE_SRV', schema.format(local_data_property, value_list_property))
1294+
xml = xml_builder.serialize()
1295+
1296+
mock_warning.reset_mock()
1297+
1298+
MetadataBuilder(xml, Config(
1299+
default_error_policy=PolicyWarning()
1300+
)).build()
1301+
1302+
assert mock_warning.called is False

0 commit comments

Comments
 (0)