Skip to content

Commit 9837b3a

Browse files
committed
Add more comprehensive tests for ODATA V4
1 parent 961c950 commit 9837b3a

21 files changed

+830
-855
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- Add V4 to pyodata cmd interface - Martin Miksik
2020
- Permissive parsing for TypeDefinition
2121
- Changes all manually raised exception to be child of PyODataException - Martin Miksik
22+
- More comprehensive tests for ODATA V4 - Martin Miksik
2223

2324
### Changed
2425
- Implementation and naming schema of `from_etree` - Martin Miksik

dev-requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ pytest-cov
88
codecov
99
flake8
1010
sphinx
11+
jinja2

tests/conftest.py

+22-140
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,36 @@
11
"""PyTest Fixtures"""
2-
import logging
32
import os
3+
from typing import Type
44
import pytest
5+
import jinja2
56

67
from pyodata.config import Config
8+
from pyodata.version import ODATAVersion
79
from pyodata.model.builder import MetadataBuilder
8-
from pyodata.v2 import ODataV2
910
from pyodata.v4 import ODataV4
11+
from pyodata.v2 import ODataV2
1012

1113

12-
@pytest.fixture
13-
def metadata_v2():
14-
return metadata('metadata.xml')
15-
16-
17-
@pytest.fixture
18-
def metadata_v4():
19-
return metadata('metadata_v4.xml')
20-
21-
22-
def metadata(file_name: str):
23-
"""Example OData metadata"""
14+
def _path_to_file(file_name):
2415
path_to_current_file = os.path.realpath(__file__)
2516
current_directory = os.path.split(path_to_current_file)[0]
26-
path_to_file = os.path.join(current_directory, file_name)
27-
28-
return open(path_to_file, 'rb').read()
17+
return os.path.join(current_directory, file_name)
2918

3019

3120
@pytest.fixture
32-
def xml_builder_factory():
33-
"""Skeleton OData metadata"""
34-
35-
class XMLBuilder:
36-
"""Helper class for building XML metadata document"""
37-
38-
# pylint: disable=too-many-instance-attributes,line-too-long
39-
def __init__(self):
40-
self.reference_is_enabled = True
41-
self.data_services_is_enabled = True
42-
self.schema_is_enabled = True
43-
44-
self.namespaces = {
45-
'edmx': "http://schemas.microsoft.com/ado/2007/06/edmx",
46-
'sap': 'http://www.sap.com/Protocols/SAPData',
47-
'edm': 'http://schemas.microsoft.com/ado/2008/09/edm',
48-
'm': 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata',
49-
'd': 'http://schemas.microsoft.com/ado/2007/08/dataservices',
50-
}
51-
52-
self.custom_edmx_prologue = None
53-
self.custom_edmx_epilogue = None
54-
55-
self.custom_data_services_prologue = None
56-
self.custom_data_services_epilogue = None
57-
58-
self._reference = '\n<edmx:Reference xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Uri="https://example.sap.corp/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Vocabularies(TechnicalName=\'%2FIWBEP%2FVOC_COMMON\',Version=\'0001\',SAP__Origin=\'LOCAL\')/$value">' + \
59-
'\n<edmx:Include Namespace="com.sap.vocabularies.Common.v1" Alias="Common"/>' + \
60-
'\n</edmx:Reference>'
61-
62-
self._schemas = ''
63-
64-
def add_schema(self, namespace, xml_definition):
65-
"""Add schema element"""
66-
self._schemas += f""""\n<Schema xmlns:d="{self.namespaces["d"]}" xmlns:m="{self.namespaces["m"]}" xmlns="{
67-
self.namespaces["edm"]}" Namespace="{namespace}" xml:lang="en" sap:schema-version="1">"""
68-
self._schemas += "\n" + xml_definition
69-
self._schemas += '\n</Schema>'
70-
71-
def serialize(self):
72-
"""Returns full metadata XML document"""
73-
result = self._edmx_prologue()
74-
75-
if self.reference_is_enabled:
76-
result += self._reference
77-
78-
if self.data_services_is_enabled:
79-
result += self._data_services_prologue()
80-
81-
if self.schema_is_enabled:
82-
result += self._schemas
83-
84-
if self.data_services_is_enabled:
85-
result += self._data_services_epilogue()
86-
87-
result += self._edmx_epilogue()
88-
89-
return result
90-
91-
def _edmx_prologue(self):
92-
if self.custom_edmx_prologue:
93-
prologue = self.custom_edmx_prologue
94-
else:
95-
prologue = f"""<edmx:Edmx xmlns:edmx="{self.namespaces["edmx"]}" xmlns:m="{self.namespaces["m"]}" xmlns:sap="{self.namespaces["sap"]}" Version="1.0">"""
96-
return prologue
97-
98-
def _edmx_epilogue(self):
99-
if self.custom_edmx_epilogue:
100-
epilogue = self.custom_edmx_epilogue
101-
else:
102-
epilogue = '\n</edmx:Edmx>'
103-
return epilogue
104-
105-
def _data_services_prologue(self):
106-
if self.custom_data_services_prologue:
107-
prologue = self.custom_data_services_prologue
108-
else:
109-
prologue = '\n<edmx:DataServices m:DataServiceVersion="2.0">'
110-
return prologue
111-
112-
def _data_services_epilogue(self):
113-
if self.custom_data_services_epilogue:
114-
prologue = self.custom_data_services_epilogue
115-
else:
116-
prologue = '\n</edmx:DataServices>'
117-
return prologue
118-
119-
return XMLBuilder
120-
121-
122-
@pytest.fixture
123-
def schema(metadata_v2):
124-
"""Parsed metadata"""
125-
126-
# pylint: disable=redefined-outer-name
127-
128-
meta = MetadataBuilder(
129-
metadata_v2,
130-
config=Config(ODataV2)
131-
)
132-
133-
return meta.build()
134-
135-
136-
@pytest.fixture
137-
def schema_v4(metadata_v4):
138-
meta = MetadataBuilder(
139-
metadata_v4,
140-
config=Config(ODataV4)
141-
)
142-
143-
return meta.build()
144-
145-
146-
def assert_logging_policy(mock_warning, *args):
147-
"""Assert if an warning was outputted by PolicyWarning """
148-
assert logging.Logger.warning is mock_warning
149-
mock_warning.assert_called_with('[%s] %s', *args)
150-
151-
152-
def assert_request_contains_header(headers, name, value):
153-
assert name in headers
154-
assert headers[name] == value
21+
def template_builder():
22+
def _builder(version: Type[ODATAVersion], **kwargs):
23+
if version == ODataV4:
24+
config = Config(ODataV4)
25+
template = 'v4/metadata.template.xml'
26+
else:
27+
config = Config(ODataV2)
28+
template = 'v4/metadata.template.xml'
29+
30+
with open(_path_to_file(template), 'rb') as metadata_file:
31+
template = jinja2.Template(metadata_file.read().decode("utf-8"))
32+
template = template.render(**kwargs).encode('ascii')
33+
34+
return MetadataBuilder(template, config=config), config
35+
36+
return _builder

0 commit comments

Comments
 (0)