Paths finder paths order fix

This commit is contained in:
p1c2u 2020-03-17 18:37:44 +00:00
parent 187b3d669b
commit 9c22ddf01c
3 changed files with 58 additions and 10 deletions

View file

@ -1,6 +1,5 @@
"""OpenAPI core servers models module"""
from six import iteritems
from six.moves.urllib.parse import urljoin
class Server(object):
@ -28,15 +27,11 @@ class Server(object):
variables = self.default_variables
return self.url.format(**variables)
@staticmethod
def is_absolute(url):
def is_absolute(self, url=None):
if url is None:
url = self.url
return url.startswith('//') or '://' in url
def get_absolute_url(self, base_url=None):
if base_url is not None and not self.is_absolute(self.url):
return urljoin(base_url, self.url)
return self.url
class ServerVariable(object):

View file

@ -1,6 +1,7 @@
"""OpenAPI core templating paths finders module"""
from more_itertools import peekable
from six import iteritems
from six.moves.urllib.parse import urljoin, urlparse
from openapi_core.templating.datatypes import TemplateResult
from openapi_core.templating.util import parse, search
@ -63,11 +64,18 @@ class PathFinder(object):
for server in servers:
server_url_pattern = full_url_pattern.rsplit(
path_result.resolved, 1)[0]
server_url = server.get_absolute_url(self.base_url)
server_url = server.url
if not server.is_absolute():
# relative to absolute url
if self.base_url is not None:
server_url = urljoin(self.base_url, server.url)
# if no base url check only path part
else:
server_url_pattern = urlparse(server_url_pattern).path
if server_url.endswith('/'):
server_url = server_url[:-1]
# simple path
if server_url_pattern.startswith(server_url):
if server_url_pattern == server_url:
server_result = TemplateResult(server.url, {})
yield (
path, operation, server,

View file

@ -390,3 +390,48 @@ class TestPathVariableServerValid(
BaseTestVariableValid, BaseTestPathServer,
BaseTestSimplePath, BaseTestVariableServer):
pass
class TestSimilarPaths(
BaseTestSpecServer, BaseTestSimpleServer):
path_name = '/tokens'
@pytest.fixture
def operation_2(self):
return Operation('get', '/keys/{id}/tokens', {}, {})
@pytest.fixture
def operations_2(self, operation_2):
return {
'get': operation_2,
}
@pytest.fixture
def path(self, operations):
return Path('/tokens', operations)
@pytest.fixture
def path_2(self, operations_2):
return Path('/keys/{id}/tokens', operations_2)
@pytest.fixture
def paths(self, path, path_2):
return {
path.name: path,
path_2.name: path_2,
}
def test_valid(self, finder, path_2, operation_2, server):
token_id = '123'
request_uri = '/keys/{0}/tokens'.format(token_id)
request = MockRequest(
'http://petstore.swagger.io', 'get', request_uri)
result = finder.find(request)
path_result = TemplateResult(path_2.name, {'id': token_id})
server_result = TemplateResult(self.server_url, {})
assert result == (
path_2, operation_2, server, path_result, server_result,
)