Skip to content

Commit

Permalink
Add extra tests for the upload
Browse files Browse the repository at this point in the history
  • Loading branch information
tarsil committed Jul 17, 2023
1 parent 99b27ab commit 92c9a25
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 202 deletions.
20 changes: 11 additions & 9 deletions esmerald/parsers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from contextlib import suppress
from json import JSONDecodeError, loads
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING, Any, Dict, get_origin

from pydantic import BaseModel, ConfigDict
from starlette.datastructures import UploadFile as StarletteUploadFile
Expand Down Expand Up @@ -66,20 +66,22 @@ def parse_form_data(media_type: "EncodingType", form_data: "FormData", field: "F
Converts, parses and transforms a multidict into a dict and tries to load them all into
json.
"""
values: Dict[str, Any] = {}
values_dict: Dict[str, Any] = {}
for key, value in form_data.multi_items():
if not isinstance(value, StarletteUploadFile):
with suppress(JSONDecodeError):
value = loads(value)
value_in_dict = values.get(key)
value_in_dict = values_dict.get(key)
if isinstance(value_in_dict, list):
values[key].append(value)
values_dict[key].append(value)
elif value_in_dict:
values[key] = [value_in_dict, value]
values_dict[key] = [value_in_dict, value]
else:
values[key] = value
values_dict[key] = value

if media_type == EncodingType.MULTI_PART:
if field.annotation in (StarletteUploadFile, UploadFile) and values:
return list(values.values())[0]
return values
if get_origin(field.annotation) is list:
return list(values_dict.values())
if isinstance(value, (StarletteUploadFile, UploadFile)) and values_dict:
return list(values_dict.values())[0]
return values_dict
193 changes: 0 additions & 193 deletions esmerald/utils/parsers.py

This file was deleted.

54 changes: 54 additions & 0 deletions tests/uploads/test_no_upload_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from typing import Dict, Union

from esmerald import Esmerald, Gateway, UploadFile, post, status
from esmerald.params import File
from esmerald.testclient import EsmeraldTestClient


@post("/files", status_code=status.HTTP_200_OK)
async def create_file(data: Union[UploadFile, None] = File()) -> Dict[str, str]:
if not data:
return {"details": "No file sent"}

file = await data.read()
return {"size": len(file)}


@post("/upload", status_code=status.HTTP_200_OK)
async def upload_file(data: Union[UploadFile, None] = File()) -> Dict[str, str]:
if not data:
return {"details": "No file sent"}
return {"size": data.filename}


app = Esmerald(routes=[Gateway(handler=create_file), Gateway(handler=upload_file)])
client = EsmeraldTestClient(app)


def test_post_form_no_body():
response = client.post("/files")
assert response.status_code == 200, response.text
assert response.json() == {"details": "No file sent"}


def test_post_file(tmp_path):
path = tmp_path / "test.txt"
path.write_bytes(b"<file content>")

client = EsmeraldTestClient(app)
with path.open("rb") as file:
response = client.post("/files", files={"file": file})
assert response.status_code == 200, response.text
assert response.json() == {"size": 14}


def test_post_upload_file(tmp_path):
path = tmp_path / "test.txt"
path.write_bytes(b"<file content>")

client = EsmeraldTestClient(app)
with path.open("rb") as file:
response = client.post("/upload", files={"file": file})

assert response.status_code == 200, response.text
assert response.json() == {"size": "test.txt"}

0 comments on commit 92c9a25

Please sign in to comment.