Skip to content

Commit 0604145

Browse files
authored
Merge pull request #165 from p1c2u/feature/validation-datatypes
Validation datatypes
2 parents f12b6d8 + 48ee8f9 commit 0604145

File tree

14 files changed

+321
-301
lines changed

14 files changed

+321
-301
lines changed

openapi_core/validation/models.py renamed to openapi_core/validation/datatypes.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
"""OpenAPI core validation models module"""
1+
"""OpenAPI core validation datatypes module"""
2+
import attr
23

34

5+
@attr.s
46
class BaseValidationResult(object):
5-
6-
def __init__(self, errors):
7-
self.errors = errors
7+
errors = attr.ib(factory=list)
88

99
def raise_for_errors(self):
1010
for error in self.errors:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""OpenAPI core validation request datatypes module"""
2+
import attr
3+
4+
from openapi_core.validation.datatypes import BaseValidationResult
5+
6+
7+
@attr.s
8+
class RequestParameters(object):
9+
path = attr.ib(factory=dict)
10+
query = attr.ib(factory=dict)
11+
header = attr.ib(factory=dict)
12+
cookie = attr.ib(factory=dict)
13+
14+
def __getitem__(self, location):
15+
return getattr(self, location)
16+
17+
18+
@attr.s
19+
class RequestValidationResult(BaseValidationResult):
20+
body = attr.ib(default=None)
21+
parameters = attr.ib(factory=RequestParameters)

openapi_core/validation/request/models.py

Lines changed: 0 additions & 41 deletions
This file was deleted.

openapi_core/validation/request/validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from openapi_core.schema.exceptions import OpenAPIMappingError
66
from openapi_core.schema.parameters.exceptions import MissingParameter
7-
from openapi_core.validation.request.models import (
7+
from openapi_core.validation.request.datatypes import (
88
RequestParameters, RequestValidationResult,
99
)
1010
from openapi_core.validation.util import get_operation_pattern
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""OpenAPI core validation response datatypes module"""
2+
import attr
3+
4+
from openapi_core.validation.datatypes import BaseValidationResult
5+
6+
7+
@attr.s
8+
class ResponseValidationResult(BaseValidationResult):
9+
data = attr.ib(default=None)
10+
headers = attr.ib(factory=dict)

openapi_core/validation/response/models.py

Lines changed: 0 additions & 10 deletions
This file was deleted.

openapi_core/validation/response/validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""OpenAPI core validation response validators module"""
22
from openapi_core.schema.exceptions import OpenAPIMappingError
3-
from openapi_core.validation.response.models import ResponseValidationResult
3+
from openapi_core.validation.response.datatypes import ResponseValidationResult
44
from openapi_core.validation.util import get_operation_pattern
55

66

tests/integration/schema/test_spec.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import pytest
2+
from base64 import b64encode
3+
from six import iteritems, text_type
4+
5+
from openapi_core.schema.media_types.models import MediaType
6+
from openapi_core.schema.operations.models import Operation
7+
from openapi_core.schema.parameters.models import Parameter
8+
from openapi_core.schema.paths.models import Path
9+
from openapi_core.schema.request_bodies.models import RequestBody
10+
from openapi_core.schema.responses.models import Response
11+
from openapi_core.schema.schemas.models import Schema
12+
from openapi_core.schema.servers.models import Server, ServerVariable
13+
from openapi_core.shortcuts import create_spec
14+
from openapi_core.validation.request.validators import RequestValidator
15+
from openapi_core.validation.response.validators import ResponseValidator
16+
17+
18+
class TestPetstore(object):
19+
20+
api_key = '12345'
21+
22+
@property
23+
def api_key_encoded(self):
24+
api_key_bytes = self.api_key.encode('utf8')
25+
api_key_bytes_enc = b64encode(api_key_bytes)
26+
return text_type(api_key_bytes_enc, 'utf8')
27+
28+
@pytest.fixture
29+
def spec_uri(self):
30+
return "file://tests/integration/data/v3.0/petstore.yaml"
31+
32+
@pytest.fixture
33+
def spec_dict(self, factory):
34+
return factory.spec_from_file("data/v3.0/petstore.yaml")
35+
36+
@pytest.fixture
37+
def spec(self, spec_dict, spec_uri):
38+
return create_spec(spec_dict, spec_uri)
39+
40+
@pytest.fixture
41+
def request_validator(self, spec):
42+
return RequestValidator(spec)
43+
44+
@pytest.fixture
45+
def response_validator(self, spec):
46+
return ResponseValidator(spec)
47+
48+
def test_spec(self, spec, spec_dict):
49+
url = 'http://petstore.swagger.io/v1'
50+
assert spec.info.title == spec_dict['info']['title']
51+
assert spec.info.version == spec_dict['info']['version']
52+
53+
assert spec.get_server_url() == url
54+
55+
for idx, server in enumerate(spec.servers):
56+
assert type(server) == Server
57+
58+
server_spec = spec_dict['servers'][idx]
59+
assert server.url == server_spec['url']
60+
assert server.default_url == url
61+
62+
for variable_name, variable in iteritems(server.variables):
63+
assert type(variable) == ServerVariable
64+
assert variable.name == variable_name
65+
66+
variable_spec = server_spec['variables'][variable_name]
67+
assert variable.default == variable_spec['default']
68+
assert variable.enum == variable_spec.get('enum')
69+
70+
for path_name, path in iteritems(spec.paths):
71+
assert type(path) == Path
72+
assert path.name == path_name
73+
74+
for http_method, operation in iteritems(path.operations):
75+
operation_spec = spec_dict['paths'][path_name][http_method]
76+
77+
assert type(operation) == Operation
78+
assert operation.path_name == path_name
79+
assert operation.http_method == http_method
80+
assert operation.operation_id is not None
81+
assert operation.tags == operation_spec['tags']
82+
83+
responses_spec = operation_spec.get('responses')
84+
85+
for http_status, response in iteritems(operation.responses):
86+
assert type(response) == Response
87+
assert response.http_status == http_status
88+
89+
response_spec = responses_spec[http_status]
90+
91+
if not response_spec:
92+
continue
93+
94+
# @todo: test with defererence
95+
if '$ref' in response_spec:
96+
continue
97+
98+
description_spec = response_spec['description']
99+
100+
assert response.description == description_spec
101+
102+
for mimetype, media_type in iteritems(response.content):
103+
assert type(media_type) == MediaType
104+
assert media_type.mimetype == mimetype
105+
106+
content_spec = response_spec['content'][mimetype]
107+
108+
example_spec = content_spec.get('example')
109+
assert media_type.example == example_spec
110+
111+
schema_spec = content_spec.get('schema')
112+
assert bool(schema_spec) == bool(media_type.schema)
113+
114+
if not schema_spec:
115+
continue
116+
117+
# @todo: test with defererence
118+
if '$ref' in schema_spec:
119+
continue
120+
121+
assert type(media_type.schema) == Schema
122+
assert media_type.schema.type.value ==\
123+
schema_spec['type']
124+
assert media_type.schema.required == schema_spec.get(
125+
'required', [])
126+
127+
for parameter_name, parameter in iteritems(
128+
response.headers):
129+
assert type(parameter) == Parameter
130+
assert parameter.name == parameter_name
131+
132+
headers_spec = response_spec['headers']
133+
parameter_spec = headers_spec[parameter_name]
134+
schema_spec = parameter_spec.get('schema')
135+
assert bool(schema_spec) == bool(parameter.schema)
136+
137+
if not schema_spec:
138+
continue
139+
140+
# @todo: test with defererence
141+
if '$ref' in schema_spec:
142+
continue
143+
144+
assert type(parameter.schema) == Schema
145+
assert parameter.schema.type.value ==\
146+
schema_spec['type']
147+
assert parameter.schema.format ==\
148+
schema_spec.get('format')
149+
assert parameter.schema.required == schema_spec.get(
150+
'required', [])
151+
152+
request_body_spec = operation_spec.get('requestBody')
153+
154+
assert bool(request_body_spec) == bool(operation.request_body)
155+
156+
if not request_body_spec:
157+
continue
158+
159+
assert type(operation.request_body) == RequestBody
160+
assert bool(operation.request_body.required) ==\
161+
request_body_spec.get('required', False)
162+
163+
for mimetype, media_type in iteritems(
164+
operation.request_body.content):
165+
assert type(media_type) == MediaType
166+
assert media_type.mimetype == mimetype
167+
168+
content_spec = request_body_spec['content'][mimetype]
169+
schema_spec = content_spec.get('schema')
170+
assert bool(schema_spec) == bool(media_type.schema)
171+
172+
if not schema_spec:
173+
continue
174+
175+
# @todo: test with defererence
176+
if '$ref' in schema_spec:
177+
continue
178+
179+
assert type(media_type.schema) == Schema
180+
assert media_type.schema.type.value ==\
181+
schema_spec['type']
182+
assert media_type.schema.format ==\
183+
schema_spec.get('format')
184+
assert media_type.schema.required == schema_spec.get(
185+
'required', False)
186+
187+
if not spec.components:
188+
return
189+
190+
for _, schema in iteritems(spec.components.schemas):
191+
assert type(schema) == Schema

tests/integration/test_minimal.py renamed to tests/integration/validation/test_minimal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_invalid_operation(self, factory, server, spec_path):
4747
assert len(result.errors) == 1
4848
assert isinstance(result.errors[0], InvalidOperation)
4949
assert result.body is None
50-
assert result.parameters == {}
50+
assert result.parameters is None
5151

5252
@pytest.mark.parametrize("server", servers)
5353
@pytest.mark.parametrize("spec_path", spec_paths)
@@ -62,4 +62,4 @@ def test_invalid_path(self, factory, server, spec_path):
6262
assert len(result.errors) == 1
6363
assert isinstance(result.errors[0], InvalidPath)
6464
assert result.body is None
65-
assert result.parameters == {}
65+
assert result.parameters is None

0 commit comments

Comments
 (0)