1- import pytest
2-
31from flask .wrappers import Request , Response
42from werkzeug .datastructures import EnvironHeaders , ImmutableMultiDict
53from werkzeug .routing import Map , Rule , Subdomain
64from werkzeug .test import create_environ
75
8- from openapi_core .wrappers .flask import (
9- FlaskOpenAPIRequest , FlaskOpenAPIResponse ,
10- )
11-
6+ import pytest
7+ from openapi_core .shortcuts import create_spec
8+ from openapi_core .validation .response .validators import ResponseValidator
9+ from openapi_core .validation .request .validators import RequestValidator
10+ from openapi_core .wrappers .flask import (FlaskOpenAPIRequest ,
11+ FlaskOpenAPIResponse )
12+
13+
14+ @pytest .fixture
15+ def environ_factory ():
16+ return create_environ
17+
18+
19+ @pytest .fixture
20+ def map ():
21+ return Map ([
22+ # Static URLs
23+ Rule ('/' , endpoint = 'static/index' ),
24+ Rule ('/about' , endpoint = 'static/about' ),
25+ Rule ('/help' , endpoint = 'static/help' ),
26+ # Knowledge Base
27+ Subdomain ('kb' , [
28+ Rule ('/' , endpoint = 'kb/index' ),
29+ Rule ('/browse/' , endpoint = 'kb/browse' ),
30+ Rule ('/browse/<int:id>/' , endpoint = 'kb/browse' ),
31+ Rule ('/browse/<int:id>/<int:page>' , endpoint = 'kb/browse' )
32+ ])
33+ ], default_subdomain = 'www' )
1234
13- class TestFlaskOpenAPIRequest (object ):
1435
36+ @pytest .fixture
37+ def request_factory (map , environ_factory ):
1538 server_name = 'localhost'
1639
17- @pytest .fixture
18- def environ_factory (self ):
19- return create_environ
40+ def create_request (method , path , subdomain = None , query_string = None ):
41+ environ = environ_factory (query_string = query_string )
42+ req = Request (environ )
43+ urls = map .bind_to_environ (
44+ environ , server_name = server_name , subdomain = subdomain )
45+ req .url_rule , req .view_args = urls .match (
46+ path , method , return_rule = True )
47+ return req
48+ return create_request
2049
21- @pytest .fixture
22- def map (self ):
23- return Map ([
24- # Static URLs
25- Rule ('/' , endpoint = 'static/index' ),
26- Rule ('/about' , endpoint = 'static/about' ),
27- Rule ('/help' , endpoint = 'static/help' ),
28- # Knowledge Base
29- Subdomain ('kb' , [
30- Rule ('/' , endpoint = 'kb/index' ),
31- Rule ('/browse/' , endpoint = 'kb/browse' ),
32- Rule ('/browse/<int:id>/' , endpoint = 'kb/browse' ),
33- Rule ('/browse/<int:id>/<int:page>' , endpoint = 'kb/browse' )
34- ])
35- ], default_subdomain = 'www' )
3650
37- @pytest .fixture
38- def request_factory (self , map , environ_factory ):
39- def create_request (method , path , subdomain = None , query_string = None ):
40- environ = environ_factory (query_string = query_string )
41- req = Request (environ )
42- urls = map .bind_to_environ (
43- environ , server_name = self .server_name , subdomain = subdomain )
44- req .url_rule , req .view_args = urls .match (
45- path , method , return_rule = True )
46- return req
47- return create_request
51+ @pytest .fixture
52+ def response_factory ():
53+ def create_response (data , status_code = 200 ):
54+ return Response (data , status = status_code )
55+ return create_response
4856
49- @pytest .fixture
50- def openapi_request (self , request ):
51- return FlaskOpenAPIRequest (request )
57+
58+ class TestFlaskOpenAPIRequest (object ):
5259
5360 def test_simple (self , request_factory , request ):
5461 request = request_factory ('GET' , '/' , subdomain = 'www' )
@@ -115,19 +122,13 @@ def test_url_rule(self, request_factory, request):
115122 assert openapi_request .host_url == request .host_url
116123 assert openapi_request .path == request .path
117124 assert openapi_request .method == request .method .lower ()
118- assert openapi_request .path_pattern == request . url_rule . rule
125+ assert openapi_request .path_pattern == '/browse/{id}/'
119126 assert openapi_request .body == request .data
120127 assert openapi_request .mimetype == request .mimetype
121128
122129
123130class TestFlaskOpenAPIResponse (object ):
124131
125- @pytest .fixture
126- def response_factory (self ):
127- def create_response (data , status_code = 200 ):
128- return Response (data , status = status_code )
129- return create_response
130-
131132 def test_invalid_server (self , response_factory ):
132133 response = response_factory ('Not Found' , status_code = 404 )
133134
@@ -137,3 +138,30 @@ def test_invalid_server(self, response_factory):
137138 assert openapi_response .data == response .data
138139 assert openapi_response .status_code == response ._status_code
139140 assert openapi_response .mimetype == response .mimetype
141+
142+
143+ class TestFlaskOpenAPIValidation (object ):
144+
145+ @pytest .fixture
146+ def flask_spec (self , factory ):
147+ specfile = 'data/v3.0/flask_wrapper.yaml'
148+ return create_spec (factory .spec_from_file (specfile ))
149+
150+ def test_response_validator_path_pattern (self ,
151+ flask_spec ,
152+ request_factory ,
153+ response_factory ):
154+ validator = ResponseValidator (flask_spec )
155+ request = request_factory ('GET' , '/browse/12/' , subdomain = 'kb' )
156+ openapi_request = FlaskOpenAPIRequest (request )
157+ response = response_factory ('Some item' , status_code = 200 )
158+ openapi_response = FlaskOpenAPIResponse (response )
159+ result = validator .validate (openapi_request , openapi_response )
160+ assert not result .errors
161+
162+ def test_request_validator_path_pattern (self , flask_spec , request_factory ):
163+ validator = RequestValidator (flask_spec )
164+ request = request_factory ('GET' , '/browse/12/' , subdomain = 'kb' )
165+ openapi_request = FlaskOpenAPIRequest (request )
166+ result = validator .validate (openapi_request )
167+ assert not result .errors
0 commit comments