Skip to content

Commit

Permalink
request response binary format integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
p1c2u committed Feb 3, 2023
1 parent 759e0c3 commit b901c40
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 8 deletions.
19 changes: 16 additions & 3 deletions openapi_core/contrib/django/responses.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
"""OpenAPI core contrib django responses module"""
from itertools import tee
from typing import Union

from django.http.response import HttpResponse
from django.http.response import StreamingHttpResponse
from werkzeug.datastructures import Headers

DjangoResponse = Union[HttpResponse, StreamingHttpResponse]


class DjangoOpenAPIResponse:
def __init__(self, response: HttpResponse):
if not isinstance(response, HttpResponse):
def __init__(self, response: DjangoResponse):
if not isinstance(response, (HttpResponse, StreamingHttpResponse)):
raise TypeError(
f"'response' argument is not type of {HttpResponse}"
f"'response' argument is not type of (Streaming)HttpResponse"
)
self.response = response

@property
def data(self) -> str:
if isinstance(self.response, StreamingHttpResponse):
_, response_iterator = tee(self.response._iterator)
content = b"".join(
map(self.response.make_bytes, response_iterator)
)
return content.decode("utf-8")

assert isinstance(self.response.content, bytes)
return self.response.content.decode("utf-8")

Expand Down
14 changes: 14 additions & 0 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from base64 import b64decode
from os import path
from urllib import request

Expand Down Expand Up @@ -25,6 +26,19 @@ def spec_from_url(spec_url):
return Spec.from_dict(spec_dict, spec_url=spec_url)


@pytest.fixture(scope="session")
def data_gif():
return b64decode(
"""
R0lGODlhEAAQAMQAAO3t7eHh4srKyvz8/P5pDP9rENLS0v/28P/17tXV1dHEvPDw8M3Nzfn5+d3d
3f5jA97Syvnv6MfLzcfHx/1mCPx4Kc/S1Pf189C+tP+xgv/k1N3OxfHy9NLV1/39/f///yH5BAAA
AAAALAAAAAAQABAAAAVq4CeOZGme6KhlSDoexdO6H0IUR+otwUYRkMDCUwIYJhLFTyGZJACAwQcg
EAQ4kVuEE2AIGAOPQQAQwXCfS8KQGAwMjIYIUSi03B7iJ+AcnmclHg4TAh0QDzIpCw4WGBUZeikD
Fzk0lpcjIQA7
"""
)


class Factory(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from base64 import b64decode

from django.conf import settings
from django.http import FileResponse
from django.http import HttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
Expand Down Expand Up @@ -76,6 +80,44 @@ def get(self, request, petId):
}
django_response = JsonResponse(response_dict)
django_response["X-Rate-Limit"] = "12"
return django_response

@staticmethod
def get_extra_actions():
return []


class PetPhotoView(APIView):

OPENID_LOGO = b64decode(
"""
R0lGODlhEAAQAMQAAO3t7eHh4srKyvz8/P5pDP9rENLS0v/28P/17tXV1dHEvPDw8M3Nzfn5+d3d
3f5jA97Syvnv6MfLzcfHx/1mCPx4Kc/S1Pf189C+tP+xgv/k1N3OxfHy9NLV1/39/f///yH5BAAA
AAAALAAAAAAQABAAAAVq4CeOZGme6KhlSDoexdO6H0IUR+otwUYRkMDCUwIYJhLFTyGZJACAwQcg
EAQ4kVuEE2AIGAOPQQAQwXCfS8KQGAwMjIYIUSi03B7iJ+AcnmclHg4TAh0QDzIpCw4WGBUZeikD
Fzk0lpcjIQA7
"""
)

def get(self, request, petId):
assert request.openapi
assert not request.openapi.errors
assert request.openapi.parameters.path == {
"petId": 12,
}
django_response = FileResponse(
[self.OPENID_LOGO],
content_type="image/gif",
)
return django_response

def post(self, request):
assert request.openapi
assert not request.openapi.errors

# implement file upload here

django_response = HttpResponse(status=201)

return django_response

Expand Down
29 changes: 29 additions & 0 deletions tests/integration/contrib/django/test_django_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,32 @@ def test_post_valid(self, api_client):

assert response.status_code == 201
assert not response.content


class TestPetPhotoView(BaseTestDjangoProject):
@pytest.mark.xfail(reason="response binary format not supported")
def test_get_valid(self, client):
headers = {
"HTTP_AUTHORIZATION": "Basic testuser",
"HTTP_HOST": "petstore.swagger.io",
}
response = client.get("/v1/pets/12/photo", **headers)

assert response.status_code == 200
assert response.content

@pytest.mark.xfail(reason="request binary format not supported")
def test_post_valid(self, client, data_gif):
client.cookies.load({"user": 1})
content_type = "image/gif"
headers = {
"HTTP_AUTHORIZATION": "Basic testuser",
"HTTP_HOST": "petstore.swagger.io",
"HTTP_API_KEY": self.api_key_encoded,
}
response = client.post(
"/v1/pets/12/photo", data_gif, content_type, secure=True, **headers
)

assert response.status_code == 201
assert not response.content
50 changes: 50 additions & 0 deletions tests/integration/data/v3.0/petstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,56 @@ paths:
format: binary
default:
$ref: "#/components/responses/ErrorResponse"
/pets/{petId}/photo:
get:
summary: Photo for a specific pet
operationId: showPetPhotoById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: integer
format: int64
responses:
'200':
description: Expected response to a valid request
content:
image/*:
schema:
type: string
format: binary
default:
$ref: "#/components/responses/ErrorResponse"
post:
summary: Create a pet photo
description: Creates new pet photo entry
operationId: createPetPhotoById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: integer
format: int64
requestBody:
required: true
content:
image/*:
schema:
type: string
format: binary
responses:
'201':
description: Null response
default:
$ref: "#/components/responses/ErrorResponse"
/tags:
get:
summary: List all tags
Expand Down
10 changes: 5 additions & 5 deletions tests/integration/schema/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,13 @@ def test_spec(self, spec, spec_dict):
if "$ref" in schema_spec:
continue

schema = content.get("schema")
schema = media_type.get("schema")
assert bool(schema_spec) == bool(schema)

assert schema.type.value == schema_spec["type"]
assert schema.format == schema_spec.get("format")
assert schema.required == schema_spec.get(
"required", False
assert schema["type"] == schema_spec["type"]
assert schema.getkey("format") == schema_spec.get("format")
assert schema.getkey("required") == schema_spec.get(
"required"
)

components = spec.get("components")
Expand Down

0 comments on commit b901c40

Please sign in to comment.