mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-09 20:37:46 +00:00
This PR adds an interface for the ConnexionMiddleware, similar to the
interface of the Connexion Apps.
The Connexion Apps are now a simple wrapper around the
ConnexionMiddleware and framework app, delegating the work to the
middleware. This enables a similar interface and behavior for users when
using either the middleware or apps.
The arguments are repeated everywhere there is a user interface, but are
parsed in a central place. Repeating the arguments is not DRY, but
needed to provide users with IDE autocomplete, typing, etc. They are
parsed in a single `_Options` class, which also provides a mechanism to
set default options on an App level, and override them on the more
granular API level.
This makes the long list of provided parameters a lot more manageable,
so I would like to use it for the `Jsonifier` as well, and re-add the
`debug` and `extra_files` arguments which I have dropped in previous
PRs. I'll submit a separate PR for this.
I renamed the `options` parameter to `swagger_ui_options` since it only
contains swagger UI options. This is a breaking change though, and we'll
need to highlight this upon release.
We still have quite a lot of `App`, `MiddlewareApp`, and abstract
classes. It would be great if we could find a way to reduce those
further, or at least find better naming to make it more clear what each
one does 🙂 .
Finally, I added examples on how the middleware can be used with third
party frameworks under `examples/frameworks`. Currently there's an
example for Starlette and Quart, but this should be easy to extend. They
also show how the `ASGIDecorator` and `StarletteDecorator` from my
previous PR can be used.
205 lines
5.8 KiB
Python
205 lines
5.8 KiB
Python
from connexion.operations import OpenAPIOperation
|
|
from connexion.resolver import Resolver
|
|
|
|
COMPONENTS = {"parameters": {"myparam": {"in": "path", "schema": {"type": "integer"}}}}
|
|
|
|
|
|
def test_standard_resolve_x_router_controller():
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="endpoint",
|
|
path_parameters=[],
|
|
operation={
|
|
"x-openapi-router-controller": "fakeapi.hello",
|
|
"operationId": "post_greeting",
|
|
},
|
|
components=COMPONENTS,
|
|
resolver=Resolver(),
|
|
)
|
|
assert operation.operation_id == "fakeapi.hello.post_greeting"
|
|
|
|
|
|
def test_methodview_resolve_operation_id(method_view_resolver):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="endpoint",
|
|
path_parameters=[],
|
|
operation={
|
|
"operationId": "fakeapi.hello.post_greeting",
|
|
},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.hello.post_greeting"
|
|
|
|
|
|
def test_methodview_resolve_x_router_controller_with_operation_id(method_view_resolver):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="endpoint",
|
|
path_parameters=[],
|
|
operation={
|
|
"x-openapi-router-controller": "fakeapi.PetsView",
|
|
"operationId": "post_greeting",
|
|
},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.post_greeting"
|
|
|
|
|
|
def test_methodview_resolve_x_router_controller_without_operation_id(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/hello/{id}",
|
|
path_parameters=[],
|
|
operation={"x-openapi-router-controller": "fakeapi.pets"},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.get"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name(method_view_resolver):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/pets/{id}",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.get"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_lowercase_verb(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="get",
|
|
path="/pets/{id}",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.get"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_will_translate_dashes_in_resource_name(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/pets",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.search"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_can_resolve_api_root(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver(
|
|
"fakeapi.pets",
|
|
),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.get"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_will_resolve_resource_root_get_as_search(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/pets",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.search"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_and_x_router_controller_will_resolve_resource_root_get_as_search(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/hello",
|
|
path_parameters=[],
|
|
operation={
|
|
"x-openapi-router-controller": "fakeapi.pets",
|
|
},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.search"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_will_resolve_resource_root_as_configured(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="GET",
|
|
path="/pets",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi", "api_list"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.api_list"
|
|
|
|
|
|
def test_methodview_resolve_with_default_module_name_will_resolve_resource_root_post_as_post(
|
|
method_view_resolver,
|
|
):
|
|
operation = OpenAPIOperation(
|
|
api=None,
|
|
method="POST",
|
|
path="/pets",
|
|
path_parameters=[],
|
|
operation={},
|
|
components=COMPONENTS,
|
|
resolver=method_view_resolver("fakeapi"),
|
|
)
|
|
assert operation.operation_id == "fakeapi.PetsView.post"
|
|
|
|
|
|
def test_method_view_resolver_integration(method_view_app):
|
|
client = method_view_app.test_client()
|
|
|
|
r = client.get("/v1.0/pets")
|
|
assert r.json == [{"name": "get"}]
|
|
|
|
r = client.get("/v1.0/pets/1")
|
|
assert r.json == {"name": "get", "petId": 1}
|
|
|
|
r = client.post("/v1.0/pets", json={"name": "Musti"})
|
|
assert r.json == {"name": "post", "body": {"name": "Musti"}}
|
|
|
|
r = client.put("/v1.0/pets/1", json={"name": "Igor"})
|
|
assert r.json == {"name": "put", "petId": 1, "body": {"name": "Igor"}}
|