mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-06 12:27:45 +00:00
* Removed internal variable pass_context_arg_name * fixed issue with personalized context name in tests * restored code from pr suggestion * restore decorator functionality now the function accept a pass_context_arg boolean parameter, instead of the pass_context_arg_name value * Fixed security test checks, now passes tests * Removed pass_context_arg, fixed security handler fixed security handler as suggested removed pass_context_arg as before * Fix context injection test Co-authored-by: Niels Dewulf <87133686+nielsbox@users.noreply.github.com> Co-authored-by: Robbe Sneyders <robbe.sneyders@ml6.eu>
285 lines
8.0 KiB
Python
285 lines
8.0 KiB
Python
import json
|
|
import logging
|
|
import pathlib
|
|
|
|
import pytest
|
|
from connexion import App
|
|
from connexion.resolver import MethodResolver, MethodViewResolver
|
|
from connexion.security import SecurityHandlerFactory
|
|
from werkzeug.test import Client, EnvironBuilder
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
TEST_FOLDER = pathlib.Path(__file__).parent
|
|
FIXTURES_FOLDER = TEST_FOLDER / "fixtures"
|
|
SPEC_FOLDER = TEST_FOLDER / "fakeapi"
|
|
OPENAPI2_SPEC = ["swagger.yaml"]
|
|
OPENAPI3_SPEC = ["openapi.yaml"]
|
|
SPECS = OPENAPI2_SPEC + OPENAPI3_SPEC
|
|
METHOD_VIEW_RESOLVERS = [MethodResolver, MethodViewResolver]
|
|
|
|
|
|
class FakeResponse:
|
|
def __init__(self, status_code, text):
|
|
"""
|
|
:type status_code: int
|
|
:type text: ste
|
|
"""
|
|
self.status_code = status_code
|
|
self.text = text
|
|
self.ok = status_code == 200
|
|
|
|
def json(self):
|
|
return json.loads(self.text)
|
|
|
|
|
|
def fixed_get_environ():
|
|
"""See https://github.com/pallets/werkzeug/issues/2347"""
|
|
|
|
original_get_environ = EnvironBuilder.get_environ
|
|
|
|
def f(self):
|
|
result = original_get_environ(self)
|
|
result.pop("HTTP_CONTENT_TYPE", None)
|
|
result.pop("HTTP_CONTENT_LENGTH", None)
|
|
return result
|
|
|
|
return f
|
|
|
|
|
|
EnvironBuilder.get_environ = fixed_get_environ()
|
|
|
|
|
|
def buffered_open():
|
|
"""For use with ASGI middleware"""
|
|
|
|
original_open = Client.open
|
|
|
|
def f(*args, **kwargs):
|
|
kwargs["buffered"] = True
|
|
return original_open(*args, **kwargs)
|
|
|
|
return f
|
|
|
|
|
|
Client.open = buffered_open()
|
|
|
|
|
|
# Helper fixtures functions
|
|
# =========================
|
|
|
|
|
|
@pytest.fixture
|
|
def oauth_requests(monkeypatch):
|
|
class FakeClient:
|
|
@staticmethod
|
|
async def get(url, params=None, headers=None, timeout=None):
|
|
"""
|
|
:type url: str
|
|
:type params: dict| None
|
|
"""
|
|
headers = headers or {}
|
|
if url == "https://oauth.example/token_info":
|
|
token = headers.get("Authorization", "invalid").split()[-1]
|
|
if token in ["100", "has_myscope"]:
|
|
return FakeResponse(
|
|
200, '{"uid": "test-user", "scope": ["myscope"]}'
|
|
)
|
|
if token in ["200", "has_wrongscope"]:
|
|
return FakeResponse(
|
|
200, '{"uid": "test-user", "scope": ["wrongscope"]}'
|
|
)
|
|
if token == "has_myscope_otherscope":
|
|
return FakeResponse(
|
|
200, '{"uid": "test-user", "scope": ["myscope", "otherscope"]}'
|
|
)
|
|
if token in ["300", "is_not_invalid"]:
|
|
return FakeResponse(404, "")
|
|
if token == "has_scopes_in_scopes_with_s":
|
|
return FakeResponse(
|
|
200, '{"uid": "test-user", "scopes": ["myscope", "otherscope"]}'
|
|
)
|
|
return url
|
|
|
|
monkeypatch.setattr(SecurityHandlerFactory, "client", FakeClient())
|
|
|
|
|
|
@pytest.fixture
|
|
def security_handler_factory():
|
|
security_handler_factory = SecurityHandlerFactory()
|
|
yield security_handler_factory
|
|
|
|
|
|
@pytest.fixture
|
|
def app():
|
|
cnx_app = App(__name__, port=5001, specification_dir=SPEC_FOLDER, debug=True)
|
|
cnx_app.add_api("api.yaml", validate_responses=True)
|
|
return cnx_app
|
|
|
|
|
|
@pytest.fixture
|
|
def simple_api_spec_dir():
|
|
return FIXTURES_FOLDER / "simple"
|
|
|
|
|
|
@pytest.fixture
|
|
def problem_api_spec_dir():
|
|
return FIXTURES_FOLDER / "problem"
|
|
|
|
|
|
@pytest.fixture
|
|
def secure_api_spec_dir():
|
|
return FIXTURES_FOLDER / "secure_api"
|
|
|
|
|
|
@pytest.fixture
|
|
def default_param_error_spec_dir():
|
|
return FIXTURES_FOLDER / "default_param_error"
|
|
|
|
|
|
@pytest.fixture
|
|
def json_validation_spec_dir():
|
|
return FIXTURES_FOLDER / "json_validation"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def json_datetime_dir():
|
|
return FIXTURES_FOLDER / "datetime_support"
|
|
|
|
|
|
def build_app_from_fixture(
|
|
api_spec_folder, spec_file="openapi.yaml", middlewares=None, **kwargs
|
|
):
|
|
debug = True
|
|
if "debug" in kwargs:
|
|
debug = kwargs["debug"]
|
|
del kwargs["debug"]
|
|
|
|
cnx_app = App(
|
|
__name__,
|
|
port=5001,
|
|
specification_dir=FIXTURES_FOLDER / api_spec_folder,
|
|
middlewares=middlewares,
|
|
debug=debug,
|
|
)
|
|
|
|
cnx_app.add_api(spec_file, **kwargs)
|
|
cnx_app._spec_file = spec_file
|
|
return cnx_app
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def simple_app(request):
|
|
return build_app_from_fixture("simple", request.param, validate_responses=True)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=OPENAPI3_SPEC)
|
|
def simple_openapi_app(request):
|
|
return build_app_from_fixture("simple", request.param, validate_responses=True)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def reverse_proxied_app(request):
|
|
|
|
# adapted from http://flask.pocoo.org/snippets/35/
|
|
class ReverseProxied:
|
|
def __init__(self, app, script_name=None, scheme=None, server=None):
|
|
self.app = app
|
|
self.script_name = script_name
|
|
self.scheme = scheme
|
|
self.server = server
|
|
|
|
def __call__(self, environ, start_response):
|
|
script_name = environ.get("HTTP_X_FORWARDED_PATH", "") or self.script_name
|
|
if script_name:
|
|
environ["SCRIPT_NAME"] = "/" + script_name.lstrip("/")
|
|
path_info = environ["PATH_INFO"]
|
|
if path_info.startswith(script_name):
|
|
environ["PATH_INFO_OLD"] = path_info
|
|
environ["PATH_INFO"] = path_info[len(script_name) :]
|
|
scheme = environ.get("HTTP_X_SCHEME", "") or self.scheme
|
|
if scheme:
|
|
environ["wsgi.url_scheme"] = scheme
|
|
server = environ.get("HTTP_X_FORWARDED_SERVER", "") or self.server
|
|
if server:
|
|
environ["HTTP_HOST"] = server
|
|
return self.app(environ, start_response)
|
|
|
|
app = build_app_from_fixture("simple", request.param, validate_responses=True)
|
|
flask_app = app.app
|
|
proxied = ReverseProxied(flask_app.wsgi_app, script_name="/reverse_proxied/")
|
|
flask_app.wsgi_app = proxied
|
|
return app
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def snake_case_app(request):
|
|
return build_app_from_fixture(
|
|
"snake_case", request.param, validate_responses=True, pythonic_params=True
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def invalid_resp_allowed_app(request):
|
|
return build_app_from_fixture("simple", request.param, validate_responses=False)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def strict_app(request):
|
|
return build_app_from_fixture(
|
|
"simple", request.param, validate_responses=True, strict_validation=True
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def problem_app(request):
|
|
return build_app_from_fixture("problem", request.param, validate_responses=True)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def schema_app(request):
|
|
return build_app_from_fixture(
|
|
"different_schemas", request.param, validate_responses=True
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def secure_endpoint_app(request):
|
|
return build_app_from_fixture(
|
|
"secure_endpoint",
|
|
request.param,
|
|
validate_responses=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def secure_api_app(request):
|
|
options = {"swagger_ui": False}
|
|
return build_app_from_fixture(
|
|
"secure_api", request.param, options=options, auth_all_paths=True
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def unordered_definition_app(request):
|
|
return build_app_from_fixture("unordered_definition", request.param)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def bad_operations_app(request):
|
|
return build_app_from_fixture("bad_operations", request.param, resolver_error=501)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=SPECS)
|
|
def method_view_app(request):
|
|
return build_app_from_fixture(
|
|
"method_view",
|
|
request.param,
|
|
resolver=MethodViewResolver("fakeapi.example_method_view"),
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", params=METHOD_VIEW_RESOLVERS)
|
|
def method_view_resolver(request):
|
|
return request.param
|