From 74920a77de5babe1bade366c49c4b3dc11fed842 Mon Sep 17 00:00:00 2001 From: p1c2u Date: Wed, 24 Mar 2021 20:32:12 +0000 Subject: [PATCH] media type deserialize form urlencoded --- .../deserializing/media_types/factories.py | 3 +- .../deserializing/media_types/util.py | 5 ++ tests/unit/deserializing/test_deserialize.py | 88 ------------------- .../test_media_types_deserializers.py | 64 ++++++++++++++ .../test_parameters_deserializers.py | 42 +++++++++ 5 files changed, 113 insertions(+), 89 deletions(-) delete mode 100644 tests/unit/deserializing/test_deserialize.py create mode 100644 tests/unit/deserializing/test_media_types_deserializers.py create mode 100644 tests/unit/deserializing/test_parameters_deserializers.py diff --git a/openapi_core/deserializing/media_types/factories.py b/openapi_core/deserializing/media_types/factories.py index a6701c1..b174bef 100644 --- a/openapi_core/deserializing/media_types/factories.py +++ b/openapi_core/deserializing/media_types/factories.py @@ -1,4 +1,4 @@ -from openapi_core.deserializing.media_types.util import json_loads +from openapi_core.deserializing.media_types.util import json_loads, form_loads from openapi_core.deserializing.media_types.deserializers import ( PrimitiveDeserializer, @@ -9,6 +9,7 @@ class MediaTypeDeserializersFactory(object): MEDIA_TYPE_DESERIALIZERS = { 'application/json': json_loads, + 'application/x-www-form-urlencoded': form_loads, } def __init__(self, custom_deserializers=None): diff --git a/openapi_core/deserializing/media_types/util.py b/openapi_core/deserializing/media_types/util.py index e09c1d1..bc5a88f 100644 --- a/openapi_core/deserializing/media_types/util.py +++ b/openapi_core/deserializing/media_types/util.py @@ -1,6 +1,7 @@ from json import loads from six import binary_type +from six.moves.urllib.parse import parse_qsl def json_loads(value): @@ -8,3 +9,7 @@ def json_loads(value): if isinstance(value, (binary_type, )): value = value.decode() return loads(value) + + +def form_loads(value): + return dict(parse_qsl(value)) diff --git a/tests/unit/deserializing/test_deserialize.py b/tests/unit/deserializing/test_deserialize.py deleted file mode 100644 index f5b2921..0000000 --- a/tests/unit/deserializing/test_deserialize.py +++ /dev/null @@ -1,88 +0,0 @@ -import pytest - -from openapi_core.deserializing.exceptions import DeserializeError -from openapi_core.deserializing.media_types.factories import ( - MediaTypeDeserializersFactory, -) -from openapi_core.deserializing.parameters.factories import ( - ParameterDeserializersFactory, -) -from openapi_core.deserializing.parameters.exceptions import ( - EmptyParameterValue, -) -from openapi_core.schema.media_types.models import MediaType -from openapi_core.schema.parameters.models import Parameter - - -class TestParameterDeserialise(object): - - @pytest.fixture - def deserializer_factory(self): - def create_deserializer(param): - return ParameterDeserializersFactory().create(param) - return create_deserializer - - def test_deprecated(self, deserializer_factory): - param = Parameter('param', 'query', deprecated=True) - value = 'test' - - with pytest.warns(DeprecationWarning): - result = deserializer_factory(param)(value) - - assert result == value - - def test_query_empty(self, deserializer_factory): - param = Parameter('param', 'query') - value = '' - - with pytest.raises(EmptyParameterValue): - deserializer_factory(param)(value) - - def test_query_valid(self, deserializer_factory): - param = Parameter('param', 'query') - value = 'test' - - result = deserializer_factory(param)(value) - - assert result == value - - -class TestMediaTypeDeserialise(object): - - @pytest.fixture - def deserializer_factory(self): - def create_deserializer(media_type, custom_deserializers=None): - return MediaTypeDeserializersFactory( - custom_deserializers=custom_deserializers).create(media_type) - return create_deserializer - - def test_empty(self, deserializer_factory): - media_type = MediaType('application/json') - value = '' - - with pytest.raises(DeserializeError): - deserializer_factory(media_type)(value) - - def test_no_schema_deserialised(self, deserializer_factory): - media_type = MediaType('application/json') - value = "{}" - - result = deserializer_factory(media_type)(value) - - assert result == {} - - def test_no_schema_custom_deserialiser(self, deserializer_factory): - custom_mimetype = 'application/custom' - media_type = MediaType(custom_mimetype) - value = "{}" - - def custom_deserializer(value): - return 'custom' - custom_deserializers = { - custom_mimetype: custom_deserializer, - } - - result = deserializer_factory( - media_type, custom_deserializers=custom_deserializers)(value) - - assert result == 'custom' diff --git a/tests/unit/deserializing/test_media_types_deserializers.py b/tests/unit/deserializing/test_media_types_deserializers.py new file mode 100644 index 0000000..435feb4 --- /dev/null +++ b/tests/unit/deserializing/test_media_types_deserializers.py @@ -0,0 +1,64 @@ +import pytest + +from openapi_core.deserializing.exceptions import DeserializeError +from openapi_core.deserializing.media_types.factories import ( + MediaTypeDeserializersFactory, +) +from openapi_core.schema.media_types.models import MediaType + + +class TestMediaTypeDeserializer(object): + + @pytest.fixture + def deserializer_factory(self): + def create_deserializer(media_type, custom_deserializers=None): + return MediaTypeDeserializersFactory( + custom_deserializers=custom_deserializers).create(media_type) + return create_deserializer + + def test_json_empty(self, deserializer_factory): + media_type = MediaType('application/json') + value = '' + + with pytest.raises(DeserializeError): + deserializer_factory(media_type)(value) + + def test_json_empty_object(self, deserializer_factory): + media_type = MediaType('application/json') + value = "{}" + + result = deserializer_factory(media_type)(value) + + assert result == {} + + def test_form_urlencoded_empty(self, deserializer_factory): + media_type = MediaType('application/x-www-form-urlencoded') + value = '' + + result = deserializer_factory(media_type)(value) + + assert result == {} + + def test_form_urlencoded_simple(self, deserializer_factory): + media_type = MediaType('application/x-www-form-urlencoded') + value = 'param1=test' + + result = deserializer_factory(media_type)(value) + + assert result == {'param1': 'test'} + + def test_custom_simple(self, deserializer_factory): + custom_mimetype = 'application/custom' + media_type = MediaType(custom_mimetype) + value = "{}" + + def custom_deserializer(value): + return 'custom' + custom_deserializers = { + custom_mimetype: custom_deserializer, + } + + result = deserializer_factory( + media_type, custom_deserializers=custom_deserializers)(value) + + assert result == 'custom' diff --git a/tests/unit/deserializing/test_parameters_deserializers.py b/tests/unit/deserializing/test_parameters_deserializers.py new file mode 100644 index 0000000..9fdd224 --- /dev/null +++ b/tests/unit/deserializing/test_parameters_deserializers.py @@ -0,0 +1,42 @@ +import pytest + +from openapi_core.deserializing.parameters.factories import ( + ParameterDeserializersFactory, +) +from openapi_core.deserializing.parameters.exceptions import ( + EmptyParameterValue, +) +from openapi_core.schema.parameters.models import Parameter + + +class TestParameterDeserializer(object): + + @pytest.fixture + def deserializer_factory(self): + def create_deserializer(param): + return ParameterDeserializersFactory().create(param) + return create_deserializer + + def test_deprecated(self, deserializer_factory): + param = Parameter('param', 'query', deprecated=True) + value = 'test' + + with pytest.warns(DeprecationWarning): + result = deserializer_factory(param)(value) + + assert result == value + + def test_query_empty(self, deserializer_factory): + param = Parameter('param', 'query') + value = '' + + with pytest.raises(EmptyParameterValue): + deserializer_factory(param)(value) + + def test_query_valid(self, deserializer_factory): + param = Parameter('param', 'query') + value = 'test' + + result = deserializer_factory(param)(value) + + assert result == value