From fe55453676ad95dbba61ab41d56ef3e05a68805d Mon Sep 17 00:00:00 2001 From: Sergii Kozak Date: Sat, 2 Mar 2024 16:00:24 +0100 Subject: [PATCH 1/2] - invalid usage of super() when having multi-baseclass inheritance: use direct basecls.__init__() to avoid nasty side effect of calling 'wrong' base class __init__(). Particularly in this case, openapi_core.validation.request.BaseRequestUnmarshaller got 'extra_format_unmarshallers' property reset to None after BaseRequestValidator.__init__() call --- openapi_core/unmarshalling/unmarshallers.py | 3 +- openapi_core/validation/request/validators.py | 4 +- .../test_request_unmarshallers.py | 128 ++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 tests/unit/unmarshalling/test_request_unmarshallers.py diff --git a/openapi_core/unmarshalling/unmarshallers.py b/openapi_core/unmarshalling/unmarshallers.py index ddc8b891..984b9ea1 100644 --- a/openapi_core/unmarshalling/unmarshallers.py +++ b/openapi_core/unmarshalling/unmarshallers.py @@ -60,7 +60,8 @@ def __init__( schema_validators_factory = ( schema_unmarshallers_factory.schema_validators_factory ) - super().__init__( + BaseValidator.__init__( + self, spec, base_url=base_url, style_deserializers_factory=style_deserializers_factory, diff --git a/openapi_core/validation/request/validators.py b/openapi_core/validation/request/validators.py index 34e23ecd..f2e1ae95 100644 --- a/openapi_core/validation/request/validators.py +++ b/openapi_core/validation/request/validators.py @@ -84,7 +84,9 @@ def __init__( ] = None, security_provider_factory: SecurityProviderFactory = security_provider_factory, ): - super().__init__( + + BaseValidator.__init__( + self, spec, base_url=base_url, style_deserializers_factory=style_deserializers_factory, diff --git a/tests/unit/unmarshalling/test_request_unmarshallers.py b/tests/unit/unmarshalling/test_request_unmarshallers.py new file mode 100644 index 00000000..a9696943 --- /dev/null +++ b/tests/unit/unmarshalling/test_request_unmarshallers.py @@ -0,0 +1,128 @@ +import enum +import pytest +from jsonschema_path import SchemaPath + +from openapi_core import V30RequestUnmarshaller, V31RequestUnmarshaller +from openapi_core.datatypes import Parameters +from openapi_core.testing import MockRequest + + +class Colors(enum.Enum): + + YELLOW = "yellow" + BLUE = "blue" + RED = "red" + + @classmethod + def of(cls, v: str): + for it in cls: + if it.value == v: + return it + raise ValueError(f"Invalid value: {v}") + + +class TestRequestUnmarshaller: + + @pytest.fixture(scope="session") + def spec_dict(self): + return { + "openapi": "3.1.0", + "info": { + "title": "Test request body unmarshaller", + "version": "0.1", + }, + "paths": { + "/resources": { + "post": { + "description": "POST resources test request", + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/createResource" + } + } + } + }, + "responses": { + "201": { + "description": "Resource was created." + } + } + }, + "get": { + "description": "POST resources test request", + "parameters": [ + { + "name": "color", + "in": "query", + "required": False, + "schema": { + "$ref": "#/components/schemas/colors" + }, + }, + ], + "responses": { + "default": { + "description": "Returned resources matching request." + } + } + } + } + }, + "components": { + "schemas": { + "colors": { + "type": "string", + "enum": ["yellow", "blue", "red"], + "format": "enum_Colors" + }, + "createResource": { + "type": "object", + "properties": { + "resId": { + "type": "integer" + }, + "color": { + "$ref": "#/components/schemas/colors" + } + }, + "required": ["resId", "color"] + } + } + } + } + + @pytest.fixture(scope="session") + def spec(self, spec_dict): + return SchemaPath.from_dict(spec_dict) + + @pytest.mark.parametrize("req_unmarshaller_cls", [V30RequestUnmarshaller, V31RequestUnmarshaller]) + def test_request_body_extra_unmarshaller(self, spec, req_unmarshaller_cls): + ru = req_unmarshaller_cls(spec=spec, extra_format_unmarshallers={ + "enum_Colors": Colors.of + }) + request = MockRequest(host_url="http://example.com", + method="post", + path="/resources", + data=b'{"resId": 23498572, "color": "blue"}') + result = ru.unmarshal(request) + + assert not result.errors + assert result.body == {"resId": 23498572, "color": Colors.BLUE} + assert result.parameters == Parameters() + + @pytest.mark.parametrize("req_unmarshaller_cls", [V30RequestUnmarshaller, V31RequestUnmarshaller]) + def test_request_param_extra_unmarshaller(self, spec, req_unmarshaller_cls): + ru = req_unmarshaller_cls(spec=spec, extra_format_unmarshallers={ + "enum_Colors": Colors.of + }) + request = MockRequest(host_url="http://example.com", + method="get", + path="/resources", + args={"color": "blue"}) + result = ru.unmarshal(request) + + assert not result.errors + assert result.parameters == Parameters(query=dict(color=Colors.BLUE)) From 0a0565dc06273ed427801529ab737c31263f2cd4 Mon Sep 17 00:00:00 2001 From: p1c2u Date: Tue, 5 Mar 2024 22:26:40 +0000 Subject: [PATCH 2/2] Request unmarshaller test formatting fix --- .../test_request_unmarshallers.py | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/tests/unit/unmarshalling/test_request_unmarshallers.py b/tests/unit/unmarshalling/test_request_unmarshallers.py index a9696943..a407d567 100644 --- a/tests/unit/unmarshalling/test_request_unmarshallers.py +++ b/tests/unit/unmarshalling/test_request_unmarshallers.py @@ -1,8 +1,10 @@ import enum + import pytest from jsonschema_path import SchemaPath -from openapi_core import V30RequestUnmarshaller, V31RequestUnmarshaller +from openapi_core import V30RequestUnmarshaller +from openapi_core import V31RequestUnmarshaller from openapi_core.datatypes import Parameters from openapi_core.testing import MockRequest @@ -43,13 +45,11 @@ def spec_dict(self): "$ref": "#/components/schemas/createResource" } } - } + }, }, "responses": { - "201": { - "description": "Resource was created." - } - } + "201": {"description": "Resource was created."} + }, }, "get": { "description": "POST resources test request", @@ -67,8 +67,8 @@ def spec_dict(self): "default": { "description": "Returned resources matching request." } - } - } + }, + }, } }, "components": { @@ -76,52 +76,60 @@ def spec_dict(self): "colors": { "type": "string", "enum": ["yellow", "blue", "red"], - "format": "enum_Colors" + "format": "enum_Colors", }, "createResource": { "type": "object", "properties": { - "resId": { - "type": "integer" - }, - "color": { - "$ref": "#/components/schemas/colors" - } + "resId": {"type": "integer"}, + "color": {"$ref": "#/components/schemas/colors"}, }, - "required": ["resId", "color"] - } + "required": ["resId", "color"], + }, } - } + }, } @pytest.fixture(scope="session") def spec(self, spec_dict): return SchemaPath.from_dict(spec_dict) - @pytest.mark.parametrize("req_unmarshaller_cls", [V30RequestUnmarshaller, V31RequestUnmarshaller]) + @pytest.mark.parametrize( + "req_unmarshaller_cls", + [V30RequestUnmarshaller, V31RequestUnmarshaller], + ) def test_request_body_extra_unmarshaller(self, spec, req_unmarshaller_cls): - ru = req_unmarshaller_cls(spec=spec, extra_format_unmarshallers={ - "enum_Colors": Colors.of - }) - request = MockRequest(host_url="http://example.com", - method="post", - path="/resources", - data=b'{"resId": 23498572, "color": "blue"}') + ru = req_unmarshaller_cls( + spec=spec, extra_format_unmarshallers={"enum_Colors": Colors.of} + ) + request = MockRequest( + host_url="http://example.com", + method="post", + path="/resources", + data=b'{"resId": 23498572, "color": "blue"}', + ) result = ru.unmarshal(request) assert not result.errors assert result.body == {"resId": 23498572, "color": Colors.BLUE} assert result.parameters == Parameters() - @pytest.mark.parametrize("req_unmarshaller_cls", [V30RequestUnmarshaller, V31RequestUnmarshaller]) - def test_request_param_extra_unmarshaller(self, spec, req_unmarshaller_cls): - ru = req_unmarshaller_cls(spec=spec, extra_format_unmarshallers={ - "enum_Colors": Colors.of - }) - request = MockRequest(host_url="http://example.com", - method="get", - path="/resources", - args={"color": "blue"}) + @pytest.mark.parametrize( + "req_unmarshaller_cls", + [V30RequestUnmarshaller, V31RequestUnmarshaller], + ) + def test_request_param_extra_unmarshaller( + self, spec, req_unmarshaller_cls + ): + ru = req_unmarshaller_cls( + spec=spec, extra_format_unmarshallers={"enum_Colors": Colors.of} + ) + request = MockRequest( + host_url="http://example.com", + method="get", + path="/resources", + args={"color": "blue"}, + ) result = ru.unmarshal(request) assert not result.errors pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy