diff --git a/openapi_core/contrib/aiohttp/requests.py b/openapi_core/contrib/aiohttp/requests.py
index e2dc0a8e..c7f330c0 100644
--- a/openapi_core/contrib/aiohttp/requests.py
+++ b/openapi_core/contrib/aiohttp/requests.py
@@ -19,7 +19,7 @@ class Empty:
class AIOHTTPOpenAPIWebRequest:
__slots__ = ("request", "parameters", "_get_body", "_body")
- def __init__(self, request: web.Request, *, body: str | None):
+ def __init__(self, request: web.Request, *, body: bytes | None):
if not isinstance(request, web.Request):
raise TypeError(
f"'request' argument is not type of {web.Request.__qualname__!r}"
@@ -45,7 +45,7 @@ def method(self) -> str:
return self.request.method.lower()
@property
- def body(self) -> str | None:
+ def body(self) -> bytes | None:
return self._body
@property
diff --git a/openapi_core/contrib/aiohttp/responses.py b/openapi_core/contrib/aiohttp/responses.py
index 53a63698..ed337968 100644
--- a/openapi_core/contrib/aiohttp/responses.py
+++ b/openapi_core/contrib/aiohttp/responses.py
@@ -13,13 +13,13 @@ def __init__(self, response: web.Response):
self.response = response
@property
- def data(self) -> str:
+ def data(self) -> bytes:
if self.response.body is None:
- return ""
+ return b""
if isinstance(self.response.body, bytes):
- return self.response.body.decode("utf-8")
+ return self.response.body
assert isinstance(self.response.body, str)
- return self.response.body
+ return self.response.body.encode("utf-8")
@property
def status_code(self) -> int:
diff --git a/openapi_core/contrib/django/requests.py b/openapi_core/contrib/django/requests.py
index fe41a3cf..8b4f1987 100644
--- a/openapi_core/contrib/django/requests.py
+++ b/openapi_core/contrib/django/requests.py
@@ -76,9 +76,9 @@ def method(self) -> str:
return self.request.method.lower()
@property
- def body(self) -> str:
+ def body(self) -> bytes:
assert isinstance(self.request.body, bytes)
- return self.request.body.decode("utf-8")
+ return self.request.body
@property
def content_type(self) -> str:
diff --git a/openapi_core/contrib/django/responses.py b/openapi_core/contrib/django/responses.py
index ded826f4..19a58943 100644
--- a/openapi_core/contrib/django/responses.py
+++ b/openapi_core/contrib/django/responses.py
@@ -1,20 +1,28 @@
"""OpenAPI core contrib django responses module"""
+from itertools import tee
+
from django.http.response import HttpResponse
+from django.http.response import StreamingHttpResponse
from werkzeug.datastructures import Headers
class DjangoOpenAPIResponse:
def __init__(self, response: HttpResponse):
- if not isinstance(response, HttpResponse):
+ if not isinstance(response, (HttpResponse, StreamingHttpResponse)):
raise TypeError(
- f"'response' argument is not type of {HttpResponse}"
+ f"'response' argument is not type of {HttpResponse} or {StreamingHttpResponse}"
)
self.response = response
@property
- def data(self) -> str:
+ def data(self) -> bytes:
+ if isinstance(self.response, StreamingHttpResponse):
+ resp_iter1, resp_iter2 = tee(self.response._iterator)
+ self.response.streaming_content = resp_iter1
+ content = b"".join(map(self.response.make_bytes, resp_iter2))
+ return content
assert isinstance(self.response.content, bytes)
- return self.response.content.decode("utf-8")
+ return self.response.content
@property
def status_code(self) -> int:
diff --git a/openapi_core/contrib/falcon/requests.py b/openapi_core/contrib/falcon/requests.py
index 7ebf7274..af08b7b7 100644
--- a/openapi_core/contrib/falcon/requests.py
+++ b/openapi_core/contrib/falcon/requests.py
@@ -49,13 +49,14 @@ def method(self) -> str:
return self.request.method.lower()
@property
- def body(self) -> Optional[str]:
+ def body(self) -> Optional[bytes]:
+ # Falcon doesn't store raw request stream.
+ # That's why we need to revert deserialized data
+
# Support falcon-jsonify.
if hasattr(self.request, "json"):
- return dumps(self.request.json)
+ return dumps(self.request.json).encode("utf-8")
- # Falcon doesn't store raw request stream.
- # That's why we need to revert serialized data
media = self.request.get_media(
default_when_empty=self.default_when_empty,
)
@@ -74,7 +75,7 @@ def body(self) -> Optional[str]:
return None
else:
assert isinstance(body, bytes)
- return body.decode("utf-8")
+ return body
@property
def content_type(self) -> str:
diff --git a/openapi_core/contrib/falcon/responses.py b/openapi_core/contrib/falcon/responses.py
index 9aaa015a..1eddb7c2 100644
--- a/openapi_core/contrib/falcon/responses.py
+++ b/openapi_core/contrib/falcon/responses.py
@@ -1,4 +1,6 @@
"""OpenAPI core contrib falcon responses module"""
+from itertools import tee
+
from falcon.response import Response
from werkzeug.datastructures import Headers
@@ -10,11 +12,16 @@ def __init__(self, response: Response):
self.response = response
@property
- def data(self) -> str:
+ def data(self) -> bytes:
if self.response.text is None:
- return ""
+ if self.response.stream is None:
+ return b""
+ resp_iter1, resp_iter2 = tee(self.response.stream)
+ self.response.stream = resp_iter1
+ content = b"".join(resp_iter2)
+ return content
assert isinstance(self.response.text, str)
- return self.response.text
+ return self.response.text.encode("utf-8")
@property
def status_code(self) -> int:
diff --git a/openapi_core/contrib/requests/requests.py b/openapi_core/contrib/requests/requests.py
index 549ed90b..2e33f02d 100644
--- a/openapi_core/contrib/requests/requests.py
+++ b/openapi_core/contrib/requests/requests.py
@@ -64,14 +64,14 @@ def method(self) -> str:
return method and method.lower() or ""
@property
- def body(self) -> Optional[str]:
+ def body(self) -> Optional[bytes]:
if self.request.body is None:
return None
if isinstance(self.request.body, bytes):
- return self.request.body.decode("utf-8")
+ return self.request.body
assert isinstance(self.request.body, str)
# TODO: figure out if request._body_position is relevant
- return self.request.body
+ return self.request.body.encode("utf-8")
@property
def content_type(self) -> str:
diff --git a/openapi_core/contrib/requests/responses.py b/openapi_core/contrib/requests/responses.py
index be4d0650..b0dacc78 100644
--- a/openapi_core/contrib/requests/responses.py
+++ b/openapi_core/contrib/requests/responses.py
@@ -10,9 +10,9 @@ def __init__(self, response: Response):
self.response = response
@property
- def data(self) -> str:
+ def data(self) -> bytes:
assert isinstance(self.response.content, bytes)
- return self.response.content.decode("utf-8")
+ return self.response.content
@property
def status_code(self) -> int:
diff --git a/openapi_core/contrib/starlette/requests.py b/openapi_core/contrib/starlette/requests.py
index 60dc610c..b556fd8f 100644
--- a/openapi_core/contrib/starlette/requests.py
+++ b/openapi_core/contrib/starlette/requests.py
@@ -34,14 +34,14 @@ def method(self) -> str:
return self.request.method.lower()
@property
- def body(self) -> Optional[str]:
+ def body(self) -> Optional[bytes]:
body = self._get_body()
if body is None:
return None
if isinstance(body, bytes):
- return body.decode("utf-8")
+ return body
assert isinstance(body, str)
- return body
+ return body.encode("utf-8")
@property
def content_type(self) -> str:
diff --git a/openapi_core/contrib/starlette/responses.py b/openapi_core/contrib/starlette/responses.py
index 247f59a3..3070b6ec 100644
--- a/openapi_core/contrib/starlette/responses.py
+++ b/openapi_core/contrib/starlette/responses.py
@@ -1,20 +1,31 @@
"""OpenAPI core contrib starlette responses module"""
+from typing import Optional
+
from starlette.datastructures import Headers
from starlette.responses import Response
+from starlette.responses import StreamingResponse
class StarletteOpenAPIResponse:
- def __init__(self, response: Response):
+ def __init__(self, response: Response, data: Optional[bytes] = None):
if not isinstance(response, Response):
raise TypeError(f"'response' argument is not type of {Response}")
self.response = response
+ if data is None and isinstance(response, StreamingResponse):
+ raise RuntimeError(
+ f"'data' argument is required for {StreamingResponse}"
+ )
+ self._data = data
+
@property
- def data(self) -> str:
+ def data(self) -> bytes:
+ if self._data is not None:
+ return self._data
if isinstance(self.response.body, bytes):
- return self.response.body.decode("utf-8")
+ return self.response.body
assert isinstance(self.response.body, str)
- return self.response.body
+ return self.response.body.encode("utf-8")
@property
def status_code(self) -> int:
diff --git a/openapi_core/contrib/werkzeug/requests.py b/openapi_core/contrib/werkzeug/requests.py
index edd62c98..cd23c67d 100644
--- a/openapi_core/contrib/werkzeug/requests.py
+++ b/openapi_core/contrib/werkzeug/requests.py
@@ -39,8 +39,8 @@ def method(self) -> str:
return self.request.method.lower()
@property
- def body(self) -> Optional[str]:
- return self.request.get_data(as_text=True)
+ def body(self) -> Optional[bytes]:
+ return self.request.get_data(as_text=False)
@property
def content_type(self) -> str:
diff --git a/openapi_core/contrib/werkzeug/responses.py b/openapi_core/contrib/werkzeug/responses.py
index 6b930c0b..e3d229f9 100644
--- a/openapi_core/contrib/werkzeug/responses.py
+++ b/openapi_core/contrib/werkzeug/responses.py
@@ -1,4 +1,6 @@
"""OpenAPI core contrib werkzeug responses module"""
+from itertools import tee
+
from werkzeug.datastructures import Headers
from werkzeug.wrappers import Response
@@ -10,8 +12,12 @@ def __init__(self, response: Response):
self.response = response
@property
- def data(self) -> str:
- return self.response.get_data(as_text=True)
+ def data(self) -> bytes:
+ if not self.response.is_sequence:
+ resp_iter1, resp_iter2 = tee(self.response.iter_encoded())
+ self.response.response = resp_iter1
+ return b"".join(resp_iter2)
+ return self.response.get_data(as_text=False)
@property
def status_code(self) -> int:
diff --git a/openapi_core/deserializing/media_types/datatypes.py b/openapi_core/deserializing/media_types/datatypes.py
index db226cfe..4d8f8fd8 100644
--- a/openapi_core/deserializing/media_types/datatypes.py
+++ b/openapi_core/deserializing/media_types/datatypes.py
@@ -2,5 +2,5 @@
from typing import Callable
from typing import Dict
-DeserializerCallable = Callable[[Any], Any]
+DeserializerCallable = Callable[[bytes], Any]
MediaTypeDeserializersDict = Dict[str, DeserializerCallable]
diff --git a/openapi_core/deserializing/media_types/deserializers.py b/openapi_core/deserializing/media_types/deserializers.py
index e7169c4c..2169cc05 100644
--- a/openapi_core/deserializing/media_types/deserializers.py
+++ b/openapi_core/deserializing/media_types/deserializers.py
@@ -41,7 +41,9 @@ def __init__(
extra_media_type_deserializers = {}
self.extra_media_type_deserializers = extra_media_type_deserializers
- def deserialize(self, mimetype: str, value: Any, **parameters: str) -> Any:
+ def deserialize(
+ self, mimetype: str, value: bytes, **parameters: str
+ ) -> Any:
deserializer_callable = self.get_deserializer_callable(mimetype)
try:
@@ -75,7 +77,7 @@ def __init__(
self.encoding = encoding
self.parameters = parameters
- def deserialize(self, value: Any) -> Any:
+ def deserialize(self, value: bytes) -> Any:
deserialized = self.media_types_deserializer.deserialize(
self.mimetype, value, **self.parameters
)
@@ -192,5 +194,4 @@ def decode_property_content_type(
value = location.getlist(prop_name)
return list(map(prop_deserializer.deserialize, value))
- value = location[prop_name]
- return prop_deserializer.deserialize(value)
+ return prop_deserializer.deserialize(location[prop_name])
diff --git a/openapi_core/deserializing/media_types/exceptions.py b/openapi_core/deserializing/media_types/exceptions.py
index 66dd904d..a5ecfeb4 100644
--- a/openapi_core/deserializing/media_types/exceptions.py
+++ b/openapi_core/deserializing/media_types/exceptions.py
@@ -8,9 +8,9 @@ class MediaTypeDeserializeError(DeserializeError):
"""Media type deserialize operation error"""
mimetype: str
- value: str
+ value: bytes
def __str__(self) -> str:
return (
"Failed to deserialize value with {mimetype} mimetype: {value}"
- ).format(value=self.value, mimetype=self.mimetype)
+ ).format(value=self.value.decode("utf-8"), mimetype=self.mimetype)
diff --git a/openapi_core/deserializing/media_types/util.py b/openapi_core/deserializing/media_types/util.py
index 1469bed1..fb5cc645 100644
--- a/openapi_core/deserializing/media_types/util.py
+++ b/openapi_core/deserializing/media_types/util.py
@@ -10,16 +10,11 @@
from werkzeug.datastructures import ImmutableMultiDict
-def binary_loads(value: Union[str, bytes], **parameters: str) -> bytes:
- charset = "utf-8"
- if "charset" in parameters:
- charset = parameters["charset"]
- if isinstance(value, str):
- return value.encode(charset)
+def binary_loads(value: bytes, **parameters: str) -> bytes:
return value
-def plain_loads(value: Union[str, bytes], **parameters: str) -> str:
+def plain_loads(value: bytes, **parameters: str) -> str:
charset = "utf-8"
if "charset" in parameters:
charset = parameters["charset"]
@@ -32,30 +27,36 @@ def plain_loads(value: Union[str, bytes], **parameters: str) -> str:
return value
-def json_loads(value: Union[str, bytes], **parameters: str) -> Any:
+def json_loads(value: bytes, **parameters: str) -> Any:
return loads(value)
-def xml_loads(value: Union[str, bytes], **parameters: str) -> Element:
- return fromstring(value)
+def xml_loads(value: bytes, **parameters: str) -> Element:
+ charset = "utf-8"
+ if "charset" in parameters:
+ charset = parameters["charset"]
+ return fromstring(value.decode(charset))
-def urlencoded_form_loads(value: Any, **parameters: str) -> Mapping[str, Any]:
- return ImmutableMultiDict(parse_qsl(value))
+def urlencoded_form_loads(
+ value: bytes, **parameters: str
+) -> Mapping[str, Any]:
+ # only UTF-8 is conforming
+ return ImmutableMultiDict(parse_qsl(value.decode("utf-8")))
-def data_form_loads(
- value: Union[str, bytes], **parameters: str
-) -> Mapping[str, Any]:
- if isinstance(value, bytes):
- value = value.decode("ASCII", errors="surrogateescape")
+def data_form_loads(value: bytes, **parameters: str) -> Mapping[str, Any]:
+ charset = "ASCII"
+ if "charset" in parameters:
+ charset = parameters["charset"]
+ decoded = value.decode(charset, errors="surrogateescape")
boundary = ""
if "boundary" in parameters:
boundary = parameters["boundary"]
parser = Parser()
mimetype = "multipart/form-data"
header = f'Content-Type: {mimetype}; boundary="{boundary}"'
- text = "\n\n".join([header, value])
+ text = "\n\n".join([header, decoded])
parts = parser.parsestr(text, headersonly=False)
return ImmutableMultiDict(
[
diff --git a/openapi_core/protocols.py b/openapi_core/protocols.py
index d60b36bf..82bf1532 100644
--- a/openapi_core/protocols.py
+++ b/openapi_core/protocols.py
@@ -17,7 +17,7 @@ def method(self) -> str:
...
@property
- def body(self) -> Optional[str]:
+ def body(self) -> Optional[bytes]:
...
@property
@@ -120,7 +120,7 @@ class Response(Protocol):
"""
@property
- def data(self) -> str:
+ def data(self) -> Optional[bytes]:
...
@property
diff --git a/openapi_core/testing/requests.py b/openapi_core/testing/requests.py
index 9fe50e77..81e97f24 100644
--- a/openapi_core/testing/requests.py
+++ b/openapi_core/testing/requests.py
@@ -20,7 +20,7 @@ def __init__(
view_args: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, Any]] = None,
cookies: Optional[Dict[str, Any]] = None,
- data: Optional[str] = None,
+ data: Optional[bytes] = None,
content_type: str = "application/json",
):
self.host_url = host_url
diff --git a/openapi_core/testing/responses.py b/openapi_core/testing/responses.py
index b957829b..ddd068a4 100644
--- a/openapi_core/testing/responses.py
+++ b/openapi_core/testing/responses.py
@@ -9,7 +9,7 @@
class MockResponse:
def __init__(
self,
- data: str,
+ data: bytes,
status_code: int = 200,
headers: Optional[Dict[str, Any]] = None,
content_type: str = "application/json",
diff --git a/openapi_core/validation/request/validators.py b/openapi_core/validation/request/validators.py
index 1781fd2b..dc12bb34 100644
--- a/openapi_core/validation/request/validators.py
+++ b/openapi_core/validation/request/validators.py
@@ -248,7 +248,7 @@ def _get_security_value(
@ValidationErrorWrapper(RequestBodyValidationError, InvalidRequestBody)
def _get_body(
- self, body: Optional[str], mimetype: str, operation: SchemaPath
+ self, body: Optional[bytes], mimetype: str, operation: SchemaPath
) -> Any:
if "requestBody" not in operation:
return None
@@ -262,8 +262,8 @@ def _get_body(
return value
def _get_body_value(
- self, body: Optional[str], request_body: SchemaPath
- ) -> Any:
+ self, body: Optional[bytes], request_body: SchemaPath
+ ) -> bytes:
if not body:
if request_body.getkey("required", False):
raise MissingRequiredRequestBody
diff --git a/openapi_core/validation/response/validators.py b/openapi_core/validation/response/validators.py
index c67de77b..02af9d46 100644
--- a/openapi_core/validation/response/validators.py
+++ b/openapi_core/validation/response/validators.py
@@ -5,6 +5,7 @@
from typing import Iterator
from typing import List
from typing import Mapping
+from typing import Optional
from jsonschema_path import SchemaPath
from openapi_spec_validator import OpenAPIV30SpecValidator
@@ -41,7 +42,7 @@ class BaseResponseValidator(BaseValidator):
def _iter_errors(
self,
status_code: int,
- data: str,
+ data: Optional[bytes],
headers: Mapping[str, Any],
mimetype: str,
operation: SchemaPath,
@@ -66,7 +67,11 @@ def _iter_errors(
yield from exc.context
def _iter_data_errors(
- self, status_code: int, data: str, mimetype: str, operation: SchemaPath
+ self,
+ status_code: int,
+ data: Optional[bytes],
+ mimetype: str,
+ operation: SchemaPath,
) -> Iterator[Exception]:
try:
operation_response = self._find_operation_response(
@@ -114,7 +119,10 @@ def _find_operation_response(
@ValidationErrorWrapper(DataValidationError, InvalidData)
def _get_data(
- self, data: str, mimetype: str, operation_response: SchemaPath
+ self,
+ data: Optional[bytes],
+ mimetype: str,
+ operation_response: SchemaPath,
) -> Any:
if "content" not in operation_response:
return None
@@ -125,7 +133,7 @@ def _get_data(
value, _ = self._get_content_and_schema(raw_data, content, mimetype)
return value
- def _get_data_value(self, data: str) -> Any:
+ def _get_data_value(self, data: Optional[bytes]) -> bytes:
if not data:
raise MissingData
diff --git a/openapi_core/validation/validators.py b/openapi_core/validation/validators.py
index ad82705e..03e80f1b 100644
--- a/openapi_core/validation/validators.py
+++ b/openapi_core/validation/validators.py
@@ -106,7 +106,7 @@ def _deserialise_media_type(
media_type: SchemaPath,
mimetype: str,
parameters: Mapping[str, str],
- value: Any,
+ value: bytes,
) -> Any:
schema = media_type.get("schema")
encoding = None
@@ -222,7 +222,7 @@ def _get_complex_param_or_header(
def _get_content_schema_value_and_schema(
self,
- raw: Any,
+ raw: bytes,
content: SchemaPath,
mimetype: Optional[str] = None,
) -> Tuple[Any, Optional[SchemaPath]]:
@@ -246,7 +246,7 @@ def _get_content_schema_value_and_schema(
return casted, schema
def _get_content_and_schema(
- self, raw: Any, content: SchemaPath, mimetype: Optional[str] = None
+ self, raw: bytes, content: SchemaPath, mimetype: Optional[str] = None
) -> Tuple[Any, Optional[SchemaPath]]:
casted, schema = self._get_content_schema_value_and_schema(
raw, content, mimetype
diff --git a/tests/integration/contrib/aiohttp/test_aiohttp_project.py b/tests/integration/contrib/aiohttp/test_aiohttp_project.py
index f7abfee3..9b1aee14 100644
--- a/tests/integration/contrib/aiohttp/test_aiohttp_project.py
+++ b/tests/integration/contrib/aiohttp/test_aiohttp_project.py
@@ -38,10 +38,6 @@ def api_key_encoded(self):
class TestPetPhotoView(BaseTestPetstore):
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
async def test_get_valid(self, client, data_gif):
headers = {
"Authorization": "Basic testuser",
diff --git a/tests/integration/contrib/django/data/v3.0/djangoproject/pets/views.py b/tests/integration/contrib/django/data/v3.0/djangoproject/pets/views.py
index 16a8f1c1..cb83ce71 100644
--- a/tests/integration/contrib/django/data/v3.0/djangoproject/pets/views.py
+++ b/tests/integration/contrib/django/data/v3.0/djangoproject/pets/views.py
@@ -110,7 +110,7 @@ def get(self, request, petId):
)
return django_response
- def post(self, request):
+ def post(self, request, petId):
assert request.openapi
assert not request.openapi.errors
diff --git a/tests/integration/contrib/django/test_django_project.py b/tests/integration/contrib/django/test_django_project.py
index a9c3b90c..6614eeaf 100644
--- a/tests/integration/contrib/django/test_django_project.py
+++ b/tests/integration/contrib/django/test_django_project.py
@@ -398,10 +398,6 @@ def test_get_skip_response_validation(self, client):
class TestPetPhotoView(BaseTestDjangoProject):
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
def test_get_valid(self, client, data_gif):
headers = {
"HTTP_AUTHORIZATION": "Basic testuser",
@@ -412,10 +408,6 @@ def test_get_valid(self, client, data_gif):
assert response.status_code == 200
assert b"".join(list(response.streaming_content)) == data_gif
- @pytest.mark.xfail(
- reason="request binary format not supported",
- strict=True,
- )
def test_post_valid(self, client, data_gif):
client.cookies.load({"user": 1})
content_type = "image/gif"
@@ -425,7 +417,7 @@ def test_post_valid(self, client, data_gif):
"HTTP_API_KEY": self.api_key_encoded,
}
response = client.post(
- "/v1/pets/12/photo", data_gif, content_type, secure=True, **headers
+ "/v1/pets/12/photo", data_gif, content_type, **headers
)
assert response.status_code == 201
diff --git a/tests/integration/contrib/falcon/test_falcon_project.py b/tests/integration/contrib/falcon/test_falcon_project.py
index 6984acbe..ca9bc066 100644
--- a/tests/integration/contrib/falcon/test_falcon_project.py
+++ b/tests/integration/contrib/falcon/test_falcon_project.py
@@ -371,10 +371,6 @@ def test_delete_method_invalid(self, client):
class TestPetPhotoResource(BaseTestFalconProject):
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
def test_get_valid(self, client, data_gif):
cookies = {"user": 1}
headers = {
@@ -393,24 +389,23 @@ def test_get_valid(self, client, data_gif):
assert response.status_code == 200
@pytest.mark.xfail(
- reason="request binary format not supported",
+ reason="falcon request binary handler not implemented",
strict=True,
)
- def test_post_valid(self, client, data_json):
+ def test_post_valid(self, client, data_gif):
cookies = {"user": 1}
- content_type = "image/gif"
+ content_type = "image/jpeg"
headers = {
"Authorization": "Basic testuser",
"Api-Key": self.api_key_encoded,
"Content-Type": content_type,
}
- body = dumps(data_json)
response = client.simulate_post(
"/v1/pets/1/photo",
host="petstore.swagger.io",
headers=headers,
- body=body,
+ body=data_gif,
cookies=cookies,
)
diff --git a/tests/integration/contrib/flask/data/v3.0/flaskproject/pets/views.py b/tests/integration/contrib/flask/data/v3.0/flaskproject/pets/views.py
index 2cc15b7b..091b942e 100644
--- a/tests/integration/contrib/flask/data/v3.0/flaskproject/pets/views.py
+++ b/tests/integration/contrib/flask/data/v3.0/flaskproject/pets/views.py
@@ -1,6 +1,8 @@
from base64 import b64decode
from io import BytesIO
+from flask import Response
+from flask import request
from flask.helpers import send_file
from openapi_core.contrib.flask.views import FlaskOpenAPIView
@@ -23,4 +25,4 @@ def get(self, petId):
def post(self, petId):
data = request.stream.read()
- response.status = HTTP_201
+ return Response(status=201)
diff --git a/tests/integration/contrib/flask/test_flask_project.py b/tests/integration/contrib/flask/test_flask_project.py
index b90b06ae..ddeb9320 100644
--- a/tests/integration/contrib/flask/test_flask_project.py
+++ b/tests/integration/contrib/flask/test_flask_project.py
@@ -41,17 +41,13 @@ def api_key_encoded(self):
class TestPetPhotoView(BaseTestFlaskProject):
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
def test_get_valid(self, client, data_gif):
headers = {
"Authorization": "Basic testuser",
"Api-Key": self.api_key_encoded,
}
- client.set_cookie("petstore.swagger.io", "user", "1")
+ client.set_cookie("user", "1", domain="petstore.swagger.io")
response = client.get(
"/v1/pets/1/photo",
headers=headers,
@@ -60,10 +56,6 @@ def test_get_valid(self, client, data_gif):
assert response.get_data() == data_gif
assert response.status_code == 200
- @pytest.mark.xfail(
- reason="request binary format not supported",
- strict=True,
- )
def test_post_valid(self, client, data_gif):
content_type = "image/gif"
headers = {
@@ -71,15 +63,12 @@ def test_post_valid(self, client, data_gif):
"Api-Key": self.api_key_encoded,
"Content-Type": content_type,
}
- data = {
- "file": data_gif,
- }
- client.set_cookie("petstore.swagger.io", "user", "1")
+ client.set_cookie("user", "1", domain="petstore.swagger.io")
response = client.post(
"/v1/pets/1/photo",
headers=headers,
- data=data,
+ data=data_gif,
)
assert not response.text
diff --git a/tests/integration/contrib/requests/test_requests_validation.py b/tests/integration/contrib/requests/test_requests_validation.py
index df2182b0..54d98096 100644
--- a/tests/integration/contrib/requests/test_requests_validation.py
+++ b/tests/integration/contrib/requests/test_requests_validation.py
@@ -165,10 +165,6 @@ def request_unmarshaller(self, spec):
def response_unmarshaller(self, spec):
return V30ResponseUnmarshaller(spec)
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
@responses.activate
def test_response_binary_valid(self, response_unmarshaller, data_gif):
responses.add(
@@ -198,10 +194,6 @@ def test_response_binary_valid(self, response_unmarshaller, data_gif):
assert not result.errors
assert result.data == data_gif
- @pytest.mark.xfail(
- reason="request binary format not supported",
- strict=True,
- )
@responses.activate
def test_request_binary_valid(self, request_unmarshaller, data_gif):
headers = {
diff --git a/tests/integration/contrib/starlette/data/v3.0/starletteproject/pets/endpoints.py b/tests/integration/contrib/starlette/data/v3.0/starletteproject/pets/endpoints.py
index eb0b2c76..99f88ceb 100644
--- a/tests/integration/contrib/starlette/data/v3.0/starletteproject/pets/endpoints.py
+++ b/tests/integration/contrib/starlette/data/v3.0/starletteproject/pets/endpoints.py
@@ -24,11 +24,13 @@ def pet_photo_endpoint(request):
openapi_request = StarletteOpenAPIRequest(request)
request_unmarshalled = unmarshal_request(openapi_request, spec=spec)
if request.method == "GET":
- response = StreamingResponse([OPENID_LOGO], media_type="image/gif")
+ contents = iter([OPENID_LOGO])
+ response = StreamingResponse(contents, media_type="image/gif")
+ openapi_response = StarletteOpenAPIResponse(response, data=OPENID_LOGO)
elif request.method == "POST":
contents = request.body()
response = Response(status_code=201)
- openapi_response = StarletteOpenAPIResponse(response)
+ openapi_response = StarletteOpenAPIResponse(response)
response_unmarshalled = unmarshal_response(
openapi_request, openapi_response, spec=spec
)
diff --git a/tests/integration/contrib/starlette/test_starlette_project.py b/tests/integration/contrib/starlette/test_starlette_project.py
index c4783208..f2cef304 100644
--- a/tests/integration/contrib/starlette/test_starlette_project.py
+++ b/tests/integration/contrib/starlette/test_starlette_project.py
@@ -38,10 +38,6 @@ def api_key_encoded(self):
class TestPetPhotoView(BaseTestPetstore):
- @pytest.mark.xfail(
- reason="response binary format not supported",
- strict=True,
- )
def test_get_valid(self, client, data_gif):
headers = {
"Authorization": "Basic testuser",
@@ -55,13 +51,9 @@ def test_get_valid(self, client, data_gif):
cookies=cookies,
)
- assert response.get_data() == data_gif
+ assert response.content == data_gif
assert response.status_code == 200
- @pytest.mark.xfail(
- reason="request binary format not supported",
- strict=True,
- )
def test_post_valid(self, client, data_gif):
content_type = "image/gif"
headers = {
diff --git a/tests/integration/test_petstore.py b/tests/integration/test_petstore.py
index 2fa5441f..59650ad4 100644
--- a/tests/integration/test_petstore.py
+++ b/tests/integration/test_petstore.py
@@ -123,7 +123,7 @@ def test_get_pets(self, spec):
data_json = {
"data": [],
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"Content-Type": "application/json",
"x-next": "next-url",
@@ -185,7 +185,7 @@ def test_get_pets_response(self, spec):
}
],
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
response_result = unmarshal_response(request, response, spec=spec)
@@ -286,7 +286,7 @@ def test_get_pets_invalid_response(self, spec, response_unmarshaller):
}
],
}
- response_data = json.dumps(response_data_json)
+ response_data = json.dumps(response_data_json).encode()
response = MockResponse(response_data)
with pytest.raises(InvalidData) as exc_info:
@@ -349,7 +349,7 @@ def test_get_pets_ids_param(self, spec):
data_json = {
"data": [],
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
response_result = unmarshal_response(request, response, spec=spec)
@@ -398,7 +398,7 @@ def test_get_pets_tags_param(self, spec):
data_json = {
"data": [],
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
response_result = unmarshal_response(request, response, spec=spec)
@@ -688,7 +688,7 @@ def test_post_birds(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -770,7 +770,7 @@ def test_post_cats(self, spec, spec_dict):
},
"extra": None,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -841,7 +841,7 @@ def test_post_cats_boolean_string(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -915,7 +915,7 @@ def test_post_urlencoded(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = urlencode(data_json)
+ data = urlencode(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -985,7 +985,7 @@ def test_post_no_one_of_schema(self, spec):
"name": pet_name,
"alias": alias,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -1037,7 +1037,7 @@ def test_post_cats_only_required_body(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -1088,7 +1088,7 @@ def test_post_pets_raises_invalid_mimetype(self, spec):
"name": "Cat",
"tag": "cats",
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -1141,7 +1141,7 @@ def test_post_pets_missing_cookie(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -1184,7 +1184,7 @@ def test_post_pets_missing_header(self, spec, spec_dict):
"healthy": pet_healthy,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
cookies = {
"user": "123",
}
@@ -1223,7 +1223,7 @@ def test_post_pets_raises_invalid_server_error(self, spec):
"name": "Cat",
"tag": "cats",
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": "12345",
}
@@ -1267,7 +1267,7 @@ def test_post_pets_raises_invalid_server_error(self, spec):
},
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
with pytest.raises(ServerNotFound):
@@ -1362,7 +1362,7 @@ def test_get_pet(self, spec):
},
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1413,7 +1413,7 @@ def test_get_pet_not_found(self, spec):
"message": message,
"rootCause": rootCause,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data, status_code=404)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1492,7 +1492,7 @@ def test_get_tags(self, spec):
assert result.body is None
data_json = ["cats", "birds"]
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1509,7 +1509,7 @@ def test_post_tags_extra_body_properties(self, spec):
"name": pet_name,
"alias": alias,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1539,7 +1539,7 @@ def test_post_tags_empty_body(self, spec):
host_url = "http://petstore.swagger.io/v1"
path_pattern = "/v1/tags"
data_json = {}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1569,7 +1569,7 @@ def test_post_tags_wrong_property_type(self, spec):
host_url = "http://petstore.swagger.io/v1"
path_pattern = "/v1/tags"
tag_name = 123
- data = json.dumps(tag_name)
+ data = json.dumps(tag_name).encode()
request = MockRequest(
host_url,
@@ -1602,7 +1602,7 @@ def test_post_tags_additional_properties(self, spec):
data_json = {
"name": pet_name,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1637,7 +1637,7 @@ def test_post_tags_additional_properties(self, spec):
"rootCause": rootCause,
"additionalinfo": additionalinfo,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data, status_code=404)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1658,7 +1658,7 @@ def test_post_tags_created_now(self, spec):
"created": created,
"name": pet_name,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1694,7 +1694,7 @@ def test_post_tags_created_now(self, spec):
"rootCause": "Tag already exist",
"additionalinfo": "Tag Dog already exist",
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data, status_code=404)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1715,7 +1715,7 @@ def test_post_tags_created_datetime(self, spec):
"created": created,
"name": pet_name,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1753,7 +1753,7 @@ def test_post_tags_created_datetime(self, spec):
"rootCause": rootCause,
"additionalinfo": additionalinfo,
}
- response_data = json.dumps(response_data_json)
+ response_data = json.dumps(response_data_json).encode()
response = MockResponse(response_data, status_code=404)
result = unmarshal_response(
@@ -1787,7 +1787,7 @@ def test_post_tags_urlencoded(self, spec):
"created": created,
"name": pet_name,
}
- data = urlencode(data_json)
+ data = urlencode(data_json).encode()
content_type = "application/x-www-form-urlencoded"
request = MockRequest(
@@ -1827,7 +1827,7 @@ def test_post_tags_urlencoded(self, spec):
"rootCause": rootCause,
"additionalinfo": additionalinfo,
}
- response_data = json.dumps(response_data_json)
+ response_data = json.dumps(response_data_json).encode()
response = MockResponse(response_data, status_code=404)
result = unmarshal_response(
@@ -1861,7 +1861,7 @@ def test_post_tags_created_invalid_type(self, spec):
"created": created,
"name": pet_name,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
@@ -1898,7 +1898,7 @@ def test_post_tags_created_invalid_type(self, spec):
"rootCause": rootCause,
"additionalinfo": additionalinfo,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
response = MockResponse(data, status_code=404)
response_result = unmarshal_response(request, response, spec=spec)
@@ -1918,7 +1918,7 @@ def test_delete_tags_with_requestbody(self, spec):
data_json = {
"ids": ids,
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
request = MockRequest(
host_url,
"DELETE",
diff --git a/tests/integration/unmarshalling/test_read_only_write_only.py b/tests/integration/unmarshalling/test_read_only_write_only.py
index 3a54636b..d8727cac 100644
--- a/tests/integration/unmarshalling/test_read_only_write_only.py
+++ b/tests/integration/unmarshalling/test_read_only_write_only.py
@@ -37,7 +37,7 @@ def test_write_a_read_only_property(self, request_unmarshaller):
"id": 10,
"name": "Pedro",
}
- )
+ ).encode()
request = MockRequest(
host_url="", method="POST", path="/users", data=data
@@ -55,7 +55,7 @@ def test_read_only_property_response(self, response_unmarshaller):
"id": 10,
"name": "Pedro",
}
- )
+ ).encode()
request = MockRequest(host_url="", method="POST", path="/users")
@@ -77,7 +77,7 @@ def test_write_only_property(self, request_unmarshaller):
"name": "Pedro",
"hidden": False,
}
- )
+ ).encode()
request = MockRequest(
host_url="", method="POST", path="/users", data=data
@@ -98,7 +98,7 @@ def test_read_a_write_only_property(self, response_unmarshaller):
"name": "Pedro",
"hidden": True,
}
- )
+ ).encode()
request = MockRequest(host_url="", method="POST", path="/users")
response = MockResponse(data)
diff --git a/tests/integration/unmarshalling/test_request_unmarshaller.py b/tests/integration/unmarshalling/test_request_unmarshaller.py
index a09675e8..df774373 100644
--- a/tests/integration/unmarshalling/test_request_unmarshaller.py
+++ b/tests/integration/unmarshalling/test_request_unmarshaller.py
@@ -174,7 +174,7 @@ def test_missing_body(self, request_unmarshaller):
)
def test_invalid_content_type(self, request_unmarshaller):
- data = "csv,data"
+ data = b"csv,data"
headers = {
"api-key": self.api_key_encoded,
}
@@ -231,7 +231,7 @@ def test_invalid_complex_parameter(self, request_unmarshaller, spec_dict):
"healthy": True,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -296,7 +296,7 @@ def test_post_pets(self, request_unmarshaller, spec_dict):
"healthy": True,
},
}
- data = json.dumps(data_json)
+ data = json.dumps(data_json).encode()
headers = {
"api-key": self.api_key_encoded,
}
@@ -338,7 +338,7 @@ def test_post_pets(self, request_unmarshaller, spec_dict):
assert result.body.address.city == pet_city
def test_post_pets_plain_no_schema(self, request_unmarshaller):
- data = "plain text"
+ data = b"plain text"
headers = {
"api-key": self.api_key_encoded,
}
@@ -368,7 +368,7 @@ def test_post_pets_plain_no_schema(self, request_unmarshaller):
},
)
assert result.security == {}
- assert result.body == data
+ assert result.body == data.decode()
def test_get_pet_unauthorized(self, request_unmarshaller):
request = MockRequest(
diff --git a/tests/integration/unmarshalling/test_response_unmarshaller.py b/tests/integration/unmarshalling/test_response_unmarshaller.py
index cfec2ba3..515696a0 100644
--- a/tests/integration/unmarshalling/test_response_unmarshaller.py
+++ b/tests/integration/unmarshalling/test_response_unmarshaller.py
@@ -39,7 +39,7 @@ def response_unmarshaller(self, spec):
def test_invalid_server(self, response_unmarshaller):
request = MockRequest("http://petstore.invalid.net/v1", "get", "/")
- response = MockResponse("Not Found", status_code=404)
+ response = MockResponse(b"Not Found", status_code=404)
result = response_unmarshaller.unmarshal(request, response)
@@ -50,7 +50,7 @@ def test_invalid_server(self, response_unmarshaller):
def test_invalid_operation(self, response_unmarshaller):
request = MockRequest(self.host_url, "patch", "/v1/pets")
- response = MockResponse("Not Found", status_code=404)
+ response = MockResponse(b"Not Found", status_code=404)
result = response_unmarshaller.unmarshal(request, response)
@@ -61,7 +61,7 @@ def test_invalid_operation(self, response_unmarshaller):
def test_invalid_response(self, response_unmarshaller):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("Not Found", status_code=409)
+ response = MockResponse(b"Not Found", status_code=409)
result = response_unmarshaller.unmarshal(request, response)
@@ -72,7 +72,7 @@ def test_invalid_response(self, response_unmarshaller):
def test_invalid_content_type(self, response_unmarshaller):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("Not Found", content_type="text/csv")
+ response = MockResponse(b"Not Found", content_type="text/csv")
result = response_unmarshaller.unmarshal(request, response)
@@ -93,20 +93,20 @@ def test_missing_body(self, response_unmarshaller):
def test_invalid_media_type(self, response_unmarshaller):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("abcde")
+ response = MockResponse(b"abcde")
result = response_unmarshaller.unmarshal(request, response)
assert result.errors == [DataValidationError()]
assert result.errors[0].__cause__ == MediaTypeDeserializeError(
- mimetype="application/json", value="abcde"
+ mimetype="application/json", value=b"abcde"
)
assert result.data is None
assert result.headers == {}
def test_invalid_media_type_value(self, response_unmarshaller):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("{}")
+ response = MockResponse(b"{}")
result = response_unmarshaller.unmarshal(request, response)
@@ -154,7 +154,7 @@ def test_invalid_header(self, response_unmarshaller):
},
],
}
- response_data = json.dumps(response_json)
+ response_data = json.dumps(response_json).encode()
headers = {
"x-delete-confirm": "true",
"x-delete-date": "today",
@@ -181,7 +181,7 @@ def test_get_pets(self, response_unmarshaller):
},
],
}
- response_data = json.dumps(response_json)
+ response_data = json.dumps(response_json).encode()
response = MockResponse(response_data)
result = response_unmarshaller.unmarshal(request, response)
diff --git a/tests/integration/validation/test_request_validators.py b/tests/integration/validation/test_request_validators.py
index 61ad611a..5cae21a9 100644
--- a/tests/integration/validation/test_request_validators.py
+++ b/tests/integration/validation/test_request_validators.py
@@ -89,7 +89,7 @@ def test_security_not_found(self, request_validator):
)
def test_media_type_not_found(self, request_validator):
- data = "csv,data"
+ data = b"csv,data"
headers = {
"api-key": self.api_key_encoded,
}
diff --git a/tests/integration/validation/test_response_validators.py b/tests/integration/validation/test_response_validators.py
index 260b2a72..807aa13e 100644
--- a/tests/integration/validation/test_response_validators.py
+++ b/tests/integration/validation/test_response_validators.py
@@ -40,28 +40,28 @@ def response_validator(self, spec):
def test_invalid_server(self, response_validator):
request = MockRequest("http://petstore.invalid.net/v1", "get", "/")
- response = MockResponse("Not Found", status_code=404)
+ response = MockResponse(b"Not Found", status_code=404)
with pytest.raises(PathNotFound):
response_validator.validate(request, response)
def test_invalid_operation(self, response_validator):
request = MockRequest(self.host_url, "patch", "/v1/pets")
- response = MockResponse("Not Found", status_code=404)
+ response = MockResponse(b"Not Found", status_code=404)
with pytest.raises(OperationNotFound):
response_validator.validate(request, response)
def test_invalid_response(self, response_validator):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("Not Found", status_code=409)
+ response = MockResponse(b"Not Found", status_code=409)
with pytest.raises(ResponseNotFound):
response_validator.validate(request, response)
def test_invalid_content_type(self, response_validator):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("Not Found", content_type="text/csv")
+ response = MockResponse(b"Not Found", content_type="text/csv")
with pytest.raises(DataValidationError) as exc_info:
response_validator.validate(request, response)
@@ -77,18 +77,18 @@ def test_missing_body(self, response_validator):
def test_invalid_media_type(self, response_validator):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("abcde")
+ response = MockResponse(b"abcde")
with pytest.raises(DataValidationError) as exc_info:
response_validator.validate(request, response)
assert exc_info.value.__cause__ == MediaTypeDeserializeError(
- mimetype="application/json", value="abcde"
+ mimetype="application/json", value=b"abcde"
)
def test_invalid_media_type_value(self, response_validator):
request = MockRequest(self.host_url, "get", "/v1/pets")
- response = MockResponse("{}")
+ response = MockResponse(b"{}")
with pytest.raises(DataValidationError) as exc_info:
response_validator.validate(request, response)
@@ -102,7 +102,7 @@ def test_invalid_value(self, response_validator):
{"id": 1, "name": "Sparky"},
],
}
- response_data = json.dumps(response_json)
+ response_data = json.dumps(response_json).encode()
response = MockResponse(response_data)
with pytest.raises(InvalidData) as exc_info:
@@ -128,7 +128,7 @@ def test_invalid_header(self, response_validator):
},
],
}
- response_data = json.dumps(response_json)
+ response_data = json.dumps(response_json).encode()
headers = {
"x-delete-confirm": "true",
"x-delete-date": "today",
@@ -152,7 +152,7 @@ def test_valid(self, response_validator):
},
],
}
- response_data = json.dumps(response_json)
+ response_data = json.dumps(response_json).encode()
response = MockResponse(response_data)
result = response_validator.validate(request, response)
diff --git a/tests/unit/contrib/django/test_django.py b/tests/unit/contrib/django/test_django.py
index be4735af..49621937 100644
--- a/tests/unit/contrib/django/test_django.py
+++ b/tests/unit/contrib/django/test_django.py
@@ -83,7 +83,7 @@ def test_no_resolver(self, request_factory):
assert openapi_request.host_url == request._current_scheme_host
assert openapi_request.path == request.path
assert openapi_request.path_pattern is None
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == request.content_type
def test_simple(self, request_factory):
@@ -104,7 +104,7 @@ def test_simple(self, request_factory):
assert openapi_request.host_url == request._current_scheme_host
assert openapi_request.path == request.path
assert openapi_request.path_pattern == request.path
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == request.content_type
def test_url_rule(self, request_factory):
@@ -125,7 +125,7 @@ def test_url_rule(self, request_factory):
assert openapi_request.host_url == request._current_scheme_host
assert openapi_request.path == request.path
assert openapi_request.path_pattern == "/admin/auth/group/{object_id}/"
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == request.content_type
def test_url_regexp_pattern(self, request_factory):
@@ -146,7 +146,7 @@ def test_url_regexp_pattern(self, request_factory):
assert openapi_request.host_url == request._current_scheme_host
assert openapi_request.path == request.path
assert openapi_request.path_pattern == request.path
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == request.content_type
def test_drf_default_value_pattern(self, request_factory):
@@ -167,7 +167,7 @@ def test_drf_default_value_pattern(self, request_factory):
assert openapi_request.host_url == request._current_scheme_host
assert openapi_request.path == request.path
assert openapi_request.path_pattern == "/object/{pk}/action/"
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == request.content_type
@@ -182,12 +182,12 @@ def test_stream_response(self, response_factory):
openapi_response = DjangoOpenAPIResponse(response)
- assert openapi_response.data == "foo\nbar\nbaz\n"
+ assert openapi_response.data == b"foo\nbar\nbaz\n"
assert openapi_response.status_code == response.status_code
assert openapi_response.content_type == response["Content-Type"]
def test_redirect_response(self, response_factory):
- data = "/redirected/"
+ data = b"/redirected/"
response = response_factory(data, status_code=302)
openapi_response = DjangoOpenAPIResponse(response)
diff --git a/tests/unit/contrib/flask/test_flask_requests.py b/tests/unit/contrib/flask/test_flask_requests.py
index 3348ed62..63e51abf 100644
--- a/tests/unit/contrib/flask/test_flask_requests.py
+++ b/tests/unit/contrib/flask/test_flask_requests.py
@@ -31,7 +31,7 @@ def test_simple(self, request_factory, request):
assert openapi_request.method == "get"
assert openapi_request.host_url == request.host_url
assert openapi_request.path == request.path
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == "application/octet-stream"
def test_multiple_values(self, request_factory, request):
@@ -59,7 +59,7 @@ def test_multiple_values(self, request_factory, request):
assert openapi_request.method == "get"
assert openapi_request.host_url == request.host_url
assert openapi_request.path == request.path
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == "application/octet-stream"
def test_url_rule(self, request_factory, request):
@@ -81,5 +81,5 @@ def test_url_rule(self, request_factory, request):
assert openapi_request.host_url == request.host_url
assert openapi_request.path == request.path
assert openapi_request.path_pattern == "/browse/{id}/"
- assert openapi_request.body == ""
+ assert openapi_request.body == b""
assert openapi_request.content_type == "application/octet-stream"
diff --git a/tests/unit/contrib/flask/test_flask_responses.py b/tests/unit/contrib/flask/test_flask_responses.py
index 3741e5a8..c2b893ac 100644
--- a/tests/unit/contrib/flask/test_flask_responses.py
+++ b/tests/unit/contrib/flask/test_flask_responses.py
@@ -9,7 +9,7 @@ def test_type_invalid(self):
FlaskOpenAPIResponse(None)
def test_invalid_server(self, response_factory):
- data = "Not Found"
+ data = b"Not Found"
status_code = 404
response = response_factory(data, status_code=status_code)
diff --git a/tests/unit/contrib/requests/conftest.py b/tests/unit/contrib/requests/conftest.py
index 65b2c913..121b5149 100644
--- a/tests/unit/contrib/requests/conftest.py
+++ b/tests/unit/contrib/requests/conftest.py
@@ -37,7 +37,7 @@ def response_factory():
def create_response(
data, status_code=200, content_type="application/json"
):
- fp = BytesIO(bytes(data, "latin-1"))
+ fp = BytesIO(data)
raw = HTTPResponse(fp, preload_content=False)
resp = Response()
resp.headers = CaseInsensitiveDict(
diff --git a/tests/unit/contrib/requests/test_requests_responses.py b/tests/unit/contrib/requests/test_requests_responses.py
index 6d515046..f032e658 100644
--- a/tests/unit/contrib/requests/test_requests_responses.py
+++ b/tests/unit/contrib/requests/test_requests_responses.py
@@ -9,7 +9,7 @@ def test_type_invalid(self):
RequestsOpenAPIResponse(None)
def test_invalid_server(self, response_factory):
- data = "Not Found"
+ data = b"Not Found"
status_code = 404
response = response_factory(data, status_code=status_code)
diff --git a/tests/unit/deserializing/test_media_types_deserializers.py b/tests/unit/deserializing/test_media_types_deserializers.py
index 56ccb17f..5b8104a2 100644
--- a/tests/unit/deserializing/test_media_types_deserializers.py
+++ b/tests/unit/deserializing/test_media_types_deserializers.py
@@ -74,7 +74,7 @@ def test_plain_valid(
def test_json_valid(self, deserializer_factory, mimetype):
parameters = {"charset": "utf-8"}
deserializer = deserializer_factory(mimetype, parameters=parameters)
- value = '{"test": "test"}'
+ value = b'{"test": "test"}'
result = deserializer.deserialize(value)
@@ -90,7 +90,7 @@ def test_json_valid(self, deserializer_factory, mimetype):
)
def test_json_empty(self, deserializer_factory, mimetype):
deserializer = deserializer_factory(mimetype)
- value = ""
+ value = b""
with pytest.raises(DeserializeError):
deserializer.deserialize(value)
@@ -104,7 +104,7 @@ def test_json_empty(self, deserializer_factory, mimetype):
)
def test_json_empty_object(self, deserializer_factory, mimetype):
deserializer = deserializer_factory(mimetype)
- value = "{}"
+ value = b"{}"
result = deserializer.deserialize(value)
@@ -119,11 +119,26 @@ def test_json_empty_object(self, deserializer_factory, mimetype):
)
def test_xml_empty(self, deserializer_factory, mimetype):
deserializer = deserializer_factory(mimetype)
- value = ""
+ value = b""
with pytest.raises(DeserializeError):
deserializer.deserialize(value)
+ @pytest.mark.parametrize(
+ "mimetype",
+ [
+ "application/xml",
+ "application/xhtml+xml",
+ ],
+ )
+ def test_xml_default_charset_valid(self, deserializer_factory, mimetype):
+ deserializer = deserializer_factory(mimetype)
+ value = b"text"
+
+ result = deserializer.deserialize(value)
+
+ assert type(result) is Element
+
@pytest.mark.parametrize(
"mimetype",
[
@@ -134,7 +149,7 @@ def test_xml_empty(self, deserializer_factory, mimetype):
def test_xml_valid(self, deserializer_factory, mimetype):
parameters = {"charset": "utf-8"}
deserializer = deserializer_factory(mimetype, parameters=parameters)
- value = "text"
+ value = b"text"
result = deserializer.deserialize(value)
@@ -143,7 +158,7 @@ def test_xml_valid(self, deserializer_factory, mimetype):
def test_octet_stream_empty(self, deserializer_factory):
mimetype = "application/octet-stream"
deserializer = deserializer_factory(mimetype)
- value = ""
+ value = b""
result = deserializer.deserialize(value)
@@ -180,7 +195,7 @@ def test_urlencoded_form_empty(self, deserializer_factory):
schema_dict = {}
schema = SchemaPath.from_dict(schema_dict)
deserializer = deserializer_factory(mimetype, schema=schema)
- value = ""
+ value = b""
result = deserializer.deserialize(value)
@@ -206,7 +221,7 @@ def test_urlencoded_form_simple(self, deserializer_factory):
deserializer = deserializer_factory(
mimetype, schema=schema, encoding=encoding
)
- value = "name=foo+bar"
+ value = b"name=foo+bar"
result = deserializer.deserialize(value)
@@ -229,7 +244,7 @@ def test_urlencoded_complex(self, deserializer_factory):
}
schema = SchemaPath.from_dict(schema_dict)
deserializer = deserializer_factory(mimetype, schema=schema)
- value = "prop=a&prop=b&prop=c"
+ value = b"prop=a&prop=b&prop=c"
result = deserializer.deserialize(value)
@@ -260,7 +275,7 @@ def test_urlencoded_content_type(self, deserializer_factory):
deserializer = deserializer_factory(
mimetype, schema=schema, encoding=encoding
)
- value = 'prop=["a","b","c"]'
+ value = b'prop=["a","b","c"]'
result = deserializer.deserialize(value)
@@ -300,7 +315,7 @@ def test_urlencoded_deepobject(self, deserializer_factory):
deserializer = deserializer_factory(
mimetype, schema=schema, encoding=encoding
)
- value = "color[R]=100&color[G]=200&color[B]=150"
+ value = b"color[R]=100&color[G]=200&color[B]=150"
result = deserializer.deserialize(value)
@@ -312,12 +327,12 @@ def test_urlencoded_deepobject(self, deserializer_factory):
},
}
- @pytest.mark.parametrize("value", [b"", ""])
- def test_multipart_form_empty(self, deserializer_factory, value):
+ def test_multipart_form_empty(self, deserializer_factory):
mimetype = "multipart/form-data"
schema_dict = {}
schema = SchemaPath.from_dict(schema_dict)
deserializer = deserializer_factory(mimetype, schema=schema)
+ value = b""
result = deserializer.deserialize(value)
@@ -416,7 +431,7 @@ def custom_deserializer(value):
custom_mimetype,
extra_media_type_deserializers=extra_media_type_deserializers,
)
- value = "{}"
+ value = b"{}"
result = deserializer.deserialize(
value,