def test_faulty_association(xml_builder_factory): """ Test NullAssociation being correctly assigned to invalid associations""" xml_builder = xml_builder_factory() xml_builder.add_schema('EXAMPLE_SRV', """ <EntityType Name="MasterEntity"> <Property Name="Key" Type="Edm.String" /> <NavigationProperty Name="Followers" Relationship="EXAMPLE_SRV.Followers" FromRole="MasterRole" ToRole="FollowerRole"/> </EntityType> <EntityType Name="FollowerEntity"> <Property Name="Key" Type="Edm.String" /> </EntityType> <Association Name="Followers"> <End Type="FaultyNamespace.MasterEntity" Multiplicity="1" Role="MasterRole"/> <End Type="FaultyNamespace.FollowerEntity" Multiplicity="*" Role="FollowerRole"/> </Association> """) metadata = MetadataBuilder( xml_builder.serialize(), config=Config( default_error_policy=PolicyIgnore() )) schema = metadata.build() assert isinstance(schema.associations[0], NullAssociation) with pytest.raises(PyODataModelError) as typ_ex_info: schema.associations[0].Any assert typ_ex_info.value.args[0] == 'Cannot access this association. An error occurred during parsing ' \ 'association metadata due to that annotation has been omitted.'
def test_faulty_association_set(xml_builder_factory): """ Test NullAssociation being correctly assigned to invalid associations""" xml_builder = xml_builder_factory() xml_builder.add_schema('EXAMPLE_SRV', """ <EntityContainer Name="EXAMPLE_SRV" m:IsDefaultEntityContainer="true"> <AssociationSet Name="toDataEntitySet" Association="EXAMPLE_SRV.toDataEntity"> <End EntitySet="MasterEntities" Role="FromRole_toDataEntity"/> <End EntitySet="DataValueHelp" Role="ToRole_toDataEntity"/> </AssociationSet> </EntityContainer> """) metadata = MetadataBuilder( xml_builder.serialize(), config=Config( default_error_policy=PolicyWarning() )) schema = metadata.build() assert isinstance(schema.association_set('toDataEntitySet'), NullAssociation) with pytest.raises(PyODataModelError) as typ_ex_info: schema.association_set('toDataEntitySet').Any assert typ_ex_info.value.args[0] == 'Cannot access this association. An error occurred during parsing ' \ 'association metadata due to that annotation has been omitted.'
def test_unsupported_schema_n(mock_from_etree, xml_builder_factory): """Test correct handling of non-whitelisted Schema namespaces""" xml_builder = xml_builder_factory() edm = 'wedonotsupportthisnamespace.com' xml_builder.namespaces['edm'] = edm xml_builder.add_schema('', '') xml = xml_builder.serialize() MetadataBuilder( xml, config=Config( xml_namespaces={'edm': edm} ) ).build() assert Schema.from_etree is mock_from_etree mock_from_etree.assert_called_once() try: MetadataBuilder(xml).build() except PyODataParserError as ex: assert str(ex) == f'Unsupported Schema namespace - {edm}' mock_from_etree.assert_called_once()
def test_null_type(xml_builder_factory): """ Test NullType being correctly assigned to invalid types""" xml_builder = xml_builder_factory() xml_builder.add_schema( 'TEST.NAMESPACE', """ <EntityType Name="MasterProperty"> <Property Name="Key" Type="Edm.UnknownType" /> </EntityType> <EnumType Name="MasterEnum" UnderlyingType="Edm.String" /> <ComplexType Name="MasterComplex"> <Property Name="Width" Type="Edm.Double" /> <Property Name="Width" Type="Edm.Double" /> </ComplexType> <EntityType Name="MasterEntity"> <NavigationProperty Name="ID" /> </EntityType> """) metadata = MetadataBuilder( xml_builder.serialize(), config=Config(default_error_policy=PolicyIgnore())) schema = metadata.build() type_info = TypeInfo(namespace=None, name='MasterProperty', is_collection=False) assert isinstance(schema.get_type(type_info).proprty('Key').typ, NullType) type_info = TypeInfo(namespace=None, name='MasterEnum', is_collection=False) assert isinstance(schema.get_type(type_info), NullType) type_info = TypeInfo(namespace=None, name='MasterComplex', is_collection=False) assert isinstance(schema.get_type(type_info), NullType) type_info = TypeInfo(namespace=None, name='MasterEntity', is_collection=False) assert isinstance(schema.get_type(type_info), NullType) with pytest.raises(PyODataModelError) as typ_ex_info: schema.get_type(type_info).Any assert typ_ex_info.value.args[0] == f'Cannot access this type. An error occurred during parsing type ' \ f'stated in xml({schema.get_type(type_info).name}) was not found, therefore it has been ' \ f'replaced with NullType.'
def test_missing_association_for_navigation_property(xml_builder_factory): """ Test faulty aassociations on navigation property""" xml_builder = xml_builder_factory() xml_builder.add_schema('EXAMPLE_SRV', """ <EntityType Name="MasterEntity"> <Property Name="Key" Type="Edm.String" /> <NavigationProperty Name="Followers" Relationship="EXAMPLE_SRV.Followers" FromRole="MasterRole" ToRole="FollowerRole"/> </EntityType> """) metadata = MetadataBuilder(xml_builder.serialize()) with pytest.raises(KeyError) as typ_ex_info: metadata.build() assert typ_ex_info.value.args[0] == 'Association Followers does not exist in namespace EXAMPLE_SRV'
def test_unsupported_enum_underlying_type(xml_builder_factory): """Test if parser will parse only allowed underlying types""" xml_builder = xml_builder_factory() xml_builder.add_schema('Test', '<EnumType Name="UnsupportedEnumType" UnderlyingType="Edm.Bool" />') xml = xml_builder.serialize() try: MetadataBuilder(xml).build() except PyODataParserError as ex: assert str(ex).startswith(f'Type Edm.Bool is not valid as underlying type for EnumType - must be one of')
def test_whitelisted_edm_namespace(mock_from_etree, xml_builder_factory): """Test correct handling of whitelisted Microsoft's edm namespace""" xml_builder = xml_builder_factory() xml_builder.namespaces['edm'] = 'http://schemas.microsoft.com/ado/2009/11/edm' xml_builder.add_schema('', '') xml = xml_builder.serialize() MetadataBuilder(xml).build() assert Schema.from_etree is mock_from_etree mock_from_etree.assert_called_once()
def test_missing_schema(xml_builder_factory): """Test correct handling of missing Schema tag in xml""" xml_builder = xml_builder_factory() xml_builder.schema_is_enabled = False xml = xml_builder.serialize() try: MetadataBuilder(xml).build() except PyODataParserError as ex: assert str(ex) == 'Metadata document is missing the element Schema'
def test_namespace_whitelist(mock_from_etree, xml_builder_factory): """Test correct handling of whitelisted namespaces""" xml_builder = xml_builder_factory() xml_builder.namespaces['edmx'] = 'http://docs.oasis-open.org/odata/ns/edmx' xml_builder.namespaces['edm'] = 'http://docs.oasis-open.org/odata/ns/edm' xml_builder.add_schema('', '') xml = xml_builder.serialize() MetadataBuilder(xml).build() assert Schema.from_etree is mock_from_etree mock_from_etree.assert_called_once()
def test_enum_value_out_of_range(xml_builder_factory): """Test if parser will check for values ot of range defined by underlying type""" xml_builder = xml_builder_factory() xml_builder.add_schema('Test', """ <EnumType Name="Num" UnderlyingType="Edm.Byte"> <Member Name="TooBig" Value="-130" /> </EnumType> """) xml = xml_builder.serialize() try: MetadataBuilder(xml).build() except PyODataParserError as ex: assert str(ex) == f'Value -130 is out of range for type Edm.Byte'
def test_annot_v_l_missing_e_t(mock_warning, xml_builder_factory): """Test correct handling of annotations whose target type does not exist""" xml_builder = xml_builder_factory() xml_builder.add_schema( 'MISSING_ET', """ <EntityType Name="Database" sap:content-version="1"> <Key><PropertyRef Name="Data"/></Key> <Property Name="Data" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> </EntityType> <EntityContainer Name="EXAMPLE_SRV" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx"> <EntitySet Name="DataValueHelp" EntityType="MISSING_ET.Database" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:searchable="true" sap:content-version="1"/> </EntityContainer> <Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="MISSING_ET.Dict/Value"> <Annotation Term="com.sap.vocabularies.Common.v1.ValueList"> <Record> <PropertyValue Property="Label" String="Data"/> <PropertyValue Property="CollectionPath" String="DataValueHelp"/> <PropertyValue Property="SearchSupported" Bool="true"/> <PropertyValue Property="Parameters"> <Collection> <Record Type="com.sap.vocabularies.Common.v1.ValueListParameterOut"> <PropertyValue Property="LocalDataProperty" PropertyPath="Value"/> <PropertyValue Property="ValueListProperty" String="Data"/> </Record> </Collection> </PropertyValue> </Record> </Annotation> </Annotations> """ ) metadata = MetadataBuilder(xml_builder.serialize()) try: metadata.build() assert 'Expected' == 'RuntimeError' except RuntimeError as ex: assert str(ex) == 'Target Type Dict of ValueHelper(Dict/Value) does not exist' metadata.config.set_custom_error_policy({ ParserError.ANNOTATION: PolicyWarning() }) metadata.build() assert_logging_policy(mock_warning, 'RuntimeError', 'Target Type Dict of ValueHelper(Dict/Value) does not exist' )
def test_annot_v_l_missing_e_s(mock_warning, xml_builder_factory): """Test correct handling of annotations whose entity set does not exist""" xml_builder = xml_builder_factory() xml_builder.add_schema( 'MISSING_ES', """ <EntityType Name="Dict" sap:content-version="1"> <Key><PropertyRef Name="Key"/></Key> <Property Name="Key" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> <Property Name="Value" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> </EntityType> <Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="MISSING_ES.Dict/Value"> <Annotation Term="com.sap.vocabularies.Common.v1.ValueList"> <Record> <PropertyValue Property="Label" String="Data"/> <PropertyValue Property="CollectionPath" String="DataValueHelp"/> <PropertyValue Property="SearchSupported" Bool="true"/> <PropertyValue Property="Parameters"> <Collection> <Record Type="com.sap.vocabularies.Common.v1.ValueListParameterOut"> <PropertyValue Property="LocalDataProperty" PropertyPath="Value"/> <PropertyValue Property="ValueListProperty" String="Data"/> </Record> </Collection> </PropertyValue> </Record> </Annotation> </Annotations> """ ) metadata = MetadataBuilder(xml_builder.serialize()) with pytest.raises(RuntimeError) as e_info: metadata.build() assert str(e_info.value) == 'Entity Set DataValueHelp for ValueHelper(Dict/Value) does not exist' metadata.config.set_custom_error_policy({ ParserError.ANNOTATION: PolicyWarning() }) metadata.build() assert_logging_policy(mock_warning, 'RuntimeError', 'Entity Set DataValueHelp for ValueHelper(Dict/Value) does not exist' )
def test_namespace_with_periods(xml_builder_factory): """Make sure Namespace can contain period""" xml_builder = xml_builder_factory() xml_builder.add_schema( 'Several.Levels.Of.Names', """ <EntityType Name="Dict" sap:content-version="1"> <Key><PropertyRef Name="Key"/></Key> <Property Name="Key" Type="Edm.String" Nullable="false"/> <Property Name="Value" Type="Edm.String" Nullable="false"/> </EntityType> <EntityType Name="Database" sap:content-version="1"> <Key><PropertyRef Name="Data"/></Key> <Property Name="Data" Type="Edm.String" Nullable="false"/> <NavigationProperty Name="Tables" Relationship="Several.Levels.Of.Names.DatabaseTables" ToRole="Table" FromRole="Schema"/> </EntityType> <Association Name="DatabaseTables"> <End Type="Several.Levels.Of.Names.Dict" Role="Table" Multiplicity="*"/> <End Type="Several.Levels.Of.Names.Database" Role="Schema" Multiplicity="0"/> <ReferentialConstraint> <Principal Role="Schema"> <PropertyRef Name="Data"/> </Principal> <Dependent Role="Table"> <PropertyRef Name="Key"/> </Dependent> </ReferentialConstraint> </Association> <EntityContainer Name="EXAMPLE_SRV"> <EntitySet Name="Schemas" EntityType="Several.Levels.Of.Names.Database"/> <EntitySet Name="Tables" EntityType="Several.Levels.Of.Names.Dict"/> <AssociationSet Name="SchemaTablesSet" Association="Several.Levels.Of.Names.DatabaseTables"> <End Role="Table" EntitySet="Tables"/> <End Role="Schema" EntitySet="Schemas"/> </AssociationSet> </EntityContainer> """ ) schema = MetadataBuilder(xml_builder.serialize()).build() db_entity = schema.entity_type('Database') nav_prop = db_entity.nav_proprty('Tables') assert str(nav_prop) == 'NavigationTypeProperty(Tables)' assert str(nav_prop.to_role) == 'EndRole(Table)' assert str(nav_prop.to_role.entity_type) == 'EntityType(Dict)' association_info = nav_prop.association_info association_set = schema.association_set_by_association(association_info.name, association_info.namespace) assert association_set is not None end_role = association_set.end_by_role(nav_prop.to_role.role) assert end_role is not None
def test_annot_v_l_trgt_inv_prop(mock_warning, mock_resolve, xml_builder_factory): """Test correct handling of annotations whose target property does not exist""" xml_builder = xml_builder_factory() xml_builder.add_schema( 'MISSING_TP', """ <EntityType Name="Dict" sap:content-version="1"> <Key><PropertyRef Name="Key"/></Key> <Property Name="Key" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> <Property Name="Value" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> </EntityType> <EntityType Name="Database" sap:content-version="1"> <Key><PropertyRef Name="Data"/></Key> <Property Name="Data" Type="Edm.String" Nullable="false" sap:unicode="false" sap:label="Key" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:value-list="standard"/> </EntityType> <EntityContainer Name="EXAMPLE_SRV" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx"> <EntitySet Name="DataValueHelp" EntityType="MISSING_TP.Database" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:searchable="true" sap:content-version="1"/> </EntityContainer> <Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="MISSING_TP.Dict/NoExisting"> <Annotation Term="com.sap.vocabularies.Common.v1.ValueList"> <Record> <PropertyValue Property="Label" String="Data"/> <PropertyValue Property="CollectionPath" String="DataValueHelp"/> <PropertyValue Property="SearchSupported" Bool="true"/> <PropertyValue Property="Parameters"> <Collection> <Record Type="com.sap.vocabularies.Common.v1.ValueListParameterOut"> <PropertyValue Property="LocalDataProperty" PropertyPath="Value"/> <PropertyValue Property="ValueListProperty" String="Data"/> </Record> </Collection> </PropertyValue> </Record> </Annotation> </Annotations> """ ) metadata = MetadataBuilder(xml_builder.serialize()) with pytest.raises(RuntimeError) as typ_ex_info: metadata.build() assert typ_ex_info.value.args[0] == 'Target Property NoExisting of EntityType(Dict) as defined in ' \ 'ValueHelper(Dict/NoExisting) does not exist' metadata.config.set_custom_error_policy({ ParserError.ANNOTATION: PolicyIgnore() }) metadata.build() assert PolicyIgnore.resolve is mock_resolve mock_resolve.asser_called_once() metadata.config.set_custom_error_policy({ ParserError.ANNOTATION: PolicyWarning() }) metadata.build() assert_logging_policy(mock_warning, 'RuntimeError', 'Target Property NoExisting of EntityType(Dict) as defined in ValueHelper(Dict/NoExisting)' ' does not exist' )