mirror of
https://github.com/correl/openapi-core.git
synced 2024-12-28 19:19:23 +00:00
Add the default value for the 'servers' array
The specification: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#oasObject requires that if the 'servers' array is not provided or empty, its default value is an array of a single Server Object with 'url' of '/'.
This commit is contained in:
parent
821f14e84b
commit
a0305fb97d
6 changed files with 92 additions and 7 deletions
|
@ -41,6 +41,9 @@ class ServersGenerator(object):
|
|||
|
||||
def generate(self, servers_spec):
|
||||
servers_deref = self.dereferencer.dereference(servers_spec)
|
||||
if not servers_deref:
|
||||
yield Server('/')
|
||||
return
|
||||
for server_spec in servers_deref:
|
||||
url = server_spec['url']
|
||||
variables_spec = server_spec.get('variables', {})
|
||||
|
@ -65,9 +68,6 @@ class ServerVariablesGenerator(object):
|
|||
def generate(self, variables_spec):
|
||||
variables_deref = self.dereferencer.dereference(variables_spec)
|
||||
|
||||
if not variables_deref:
|
||||
return
|
||||
|
||||
for variable_name, variable_spec in iteritems(variables_deref):
|
||||
default = variable_spec['default']
|
||||
enum = variable_spec.get('enum')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""OpenAPI core validators module"""
|
||||
from six import iteritems
|
||||
from yarl import URL
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
OpenAPIMappingError, MissingParameter, MissingBody, InvalidResponse,
|
||||
|
@ -51,6 +52,16 @@ class ResponseValidationResult(BaseValidationResult):
|
|||
self.headers = headers
|
||||
|
||||
|
||||
def get_operation_pattern(server_url, request_url_pattern):
|
||||
"""Return an updated request URL pattern with the server URL removed."""
|
||||
if server_url[-1] == "/":
|
||||
# operations have to start with a slash, so do not remove it
|
||||
server_url = server_url[:-1]
|
||||
if URL(server_url).is_absolute():
|
||||
return request_url_pattern.replace(server_url, "", 1)
|
||||
return URL(request_url_pattern).path_qs.replace(server_url, "", 1)
|
||||
|
||||
|
||||
class RequestValidator(object):
|
||||
|
||||
def __init__(self, spec):
|
||||
|
@ -68,8 +79,9 @@ class RequestValidator(object):
|
|||
errors.append(exc)
|
||||
return RequestValidationResult(errors, body, parameters)
|
||||
|
||||
operation_pattern = request.full_url_pattern.replace(
|
||||
server.default_url, '')
|
||||
operation_pattern = get_operation_pattern(
|
||||
server.default_url, request.full_url_pattern
|
||||
)
|
||||
|
||||
try:
|
||||
operation = self.spec.get_operation(
|
||||
|
@ -154,8 +166,9 @@ class ResponseValidator(object):
|
|||
errors.append(exc)
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
|
||||
operation_pattern = request.full_url_pattern.replace(
|
||||
server.default_url, '')
|
||||
operation_pattern = get_operation_pattern(
|
||||
server.default_url, request.full_url_pattern
|
||||
)
|
||||
|
||||
try:
|
||||
operation = self.spec.get_operation(
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
openapi-spec-validator
|
||||
six
|
||||
yarl
|
||||
|
|
10
tests/integration/data/v3.0/minimal.yaml
Normal file
10
tests/integration/data/v3.0/minimal.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
openapi: "3.0.0"
|
||||
info:
|
||||
title: Minimal valid OpenAPI specification
|
||||
version: "0.1"
|
||||
paths:
|
||||
/status:
|
||||
get:
|
||||
responses:
|
||||
default:
|
||||
description: Return the API status.
|
12
tests/integration/data/v3.0/minimal_with_servers.yaml
Normal file
12
tests/integration/data/v3.0/minimal_with_servers.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
openapi: "3.0.0"
|
||||
info:
|
||||
title: Minimal valid OpenAPI specification with explicit 'servers' array
|
||||
version: "0.1"
|
||||
servers:
|
||||
- url: /
|
||||
paths:
|
||||
/status:
|
||||
get:
|
||||
responses:
|
||||
default:
|
||||
description: Return the API status.
|
49
tests/integration/test_minimal.py
Normal file
49
tests/integration/test_minimal.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
import pytest
|
||||
|
||||
from openapi_core.exceptions import InvalidOperation
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validators import RequestValidator
|
||||
from openapi_core.wrappers import MockRequest
|
||||
|
||||
|
||||
class TestMinimal(object):
|
||||
|
||||
servers = [
|
||||
"http://minimal.test/",
|
||||
"https://bad.remote.domain.net/",
|
||||
"http://localhost",
|
||||
"http://localhost:8080",
|
||||
"https://u:p@a.b:1337"
|
||||
]
|
||||
|
||||
spec_paths = [
|
||||
"data/v3.0/minimal_with_servers.yaml",
|
||||
"data/v3.0/minimal.yaml"
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("server", servers)
|
||||
@pytest.mark.parametrize("spec_path", spec_paths)
|
||||
def test_hosts(self, factory, server, spec_path):
|
||||
spec_dict = factory.spec_from_file(spec_path)
|
||||
spec = create_spec(spec_dict)
|
||||
validator = RequestValidator(spec)
|
||||
request = MockRequest(server, "get", "/status")
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert not result.errors
|
||||
|
||||
@pytest.mark.parametrize("server", servers)
|
||||
@pytest.mark.parametrize("spec_path", spec_paths)
|
||||
def test_invalid_operation(self, factory, server, spec_path):
|
||||
spec_dict = factory.spec_from_file(spec_path)
|
||||
spec = create_spec(spec_dict)
|
||||
validator = RequestValidator(spec)
|
||||
request = MockRequest(server, "get", "/nonexistent")
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert isinstance(result.errors[0], InvalidOperation)
|
||||
assert result.body is None
|
||||
assert result.parameters == {}
|
Loading…
Reference in a new issue