Skip to content

Commit

Permalink
test: Add tests for dto factory doc examples (#3453)
Browse files Browse the repository at this point in the history
* test: Add tests for dto factory doc examples
---------

Co-authored-by: kedod <kedod>
  • Loading branch information
kedod authored Apr 30, 2024
1 parent 5ec8e5b commit d5196ed
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from __future__ import annotations

from dataclasses import dataclass
from uuid import UUID
from dataclasses import dataclass, field
from uuid import UUID, uuid4

from litestar import Litestar, post
from litestar.dto import DataclassDTO, DTOConfig


@dataclass
class Person:
id: UUID
class User:
name: str
email: str
age: int
id: UUID = field(default_factory=uuid4)


class WriteDTO(DataclassDTO[Person]):
class UserWriteDTO(DataclassDTO[User]):
"""Don't allow client to set the id."""

config = DTOConfig(exclude={"id"})
Expand All @@ -23,12 +24,12 @@ class WriteDTO(DataclassDTO[Person]):
# We need a dto for the handler to parse the request data per the configuration, however,
# we don't need a return DTO as we are returning a dataclass, and Litestar already knows
# how to serialize dataclasses.
@post("/person", dto=WriteDTO, return_dto=None, sync_to_thread=False)
def create_person(data: Person) -> Person:
"""Create a person."""
@post("/users", dto=UserWriteDTO, return_dto=None, sync_to_thread=False)
def create_user(data: User) -> User:
"""Create an user."""
return data


app = Litestar(route_handlers=[create_person])
app = Litestar(route_handlers=[create_user])

# run: /person -H "Content-Type: application/json" -d '{"name":"Peter","age":41}'
# run: /users -H "Content-Type: application/json" -d '{"name":"Peter","email": "[email protected]", "age":41}'
19 changes: 9 additions & 10 deletions docs/examples/data_transfer_objects/factory/dto_data_usage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import annotations

from dataclasses import dataclass
from uuid import UUID, uuid4

Expand All @@ -8,24 +6,25 @@


@dataclass
class Person:
id: UUID
class User:
name: str
email: str
age: int
id: UUID


class WriteDTO(DataclassDTO[Person]):
class UserWriteDTO(DataclassDTO[User]):
"""Don't allow client to set the id."""

config = DTOConfig(exclude={"id"})


@post("/person", dto=WriteDTO, return_dto=None, sync_to_thread=False)
def create_person(data: DTOData[Person]) -> Person:
"""Create a person."""
@post("/users", dto=UserWriteDTO, return_dto=None, sync_to_thread=False)
def create_user(data: DTOData[User]) -> User:
"""Create an user."""
return data.create_instance(id=uuid4())


app = Litestar(route_handlers=[create_person])
app = Litestar(route_handlers=[create_user])

# run: /person -H "Content-Type: application/json" -d '{"name":"Peter","age":41}'
# run: /users -H "Content-Type: application/json" -d '{"name":"Peter", "email": "[email protected]", "age":41}'
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

@dataclass
class Foo:
bar: str
_baz: str = "Mars"
this_will: str
_this_will: str = "Mars"


@post("/", dto=DataclassDTO[Foo], sync_to_thread=False)
Expand All @@ -17,4 +17,4 @@ def handler(data: Foo) -> Foo:

app = Litestar(route_handlers=[handler])

# run: / -H "Content-Type: application/json" -d '{"bar":"Hello","_baz":"World!"}'
# run: / -H "Content-Type: application/json" -d '{"bar":"stay","_baz":"go_away!"}'
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

@dataclass
class Foo:
bar: str
_baz: str = "Mars"
this_will: str
_this_will: str = "not_go_away!"


class DTO(DataclassDTO[Foo]):
Expand All @@ -21,4 +21,4 @@ def handler(data: Foo) -> Foo:

app = Litestar(route_handlers=[handler])

# run: / -H "Content-Type: application/json" -d '{"bar":"Hello","_baz":"World!"}'
# run: / -H "Content-Type: application/json" -d '{"this_will":"stay","_this_will":"not_go_away!"}'
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
from litestar import post
from dataclasses import dataclass, field
from uuid import UUID, uuid4

from .models import User, UserDTO
from litestar import Litestar, post
from litestar.dto import DataclassDTO


@post(dto=UserDTO, return_dto=None)
@dataclass
class User:
name: str
email: str
age: int
id: UUID = field(default_factory=uuid4)


UserDTO = DataclassDTO[User]


@post(dto=UserDTO, return_dto=None, sync_to_thread=False)
def create_user(data: User) -> bytes:
return data.name.encode(encoding="utf-8")


app = Litestar([create_user])
2 changes: 1 addition & 1 deletion docs/usage/dto/1-abstract-dto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ handler.

.. literalinclude:: /examples/data_transfer_objects/factory/dto_data_problem_statement.py
:language: python
:emphasize-lines: 18,19,20,21,27
:emphasize-lines: 19,20,21,22,28
:linenos:

Notice that we get a ``500`` response from the handler - this is because the DTO has attempted to convert the request
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from unittest.mock import ANY

from litestar.status_codes import HTTP_201_CREATED
from litestar.testing.client import TestClient


def test_create_user(user_data: dict) -> None:
from docs.examples.data_transfer_objects.factory.dto_data_problem_statement import app

with TestClient(app=app) as client:
response = client.post("/users", json=user_data)

assert response.status_code == HTTP_201_CREATED
assert response.json() == {"id": ANY, "name": "Mr Sunglass", "email": "[email protected]", "age": 30}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from unittest.mock import ANY

from litestar.testing import TestClient


def test_create_user(user_data) -> None:
from docs.examples.data_transfer_objects.factory.dto_data_usage import app

with TestClient(app) as client:
response = client.post("/users", json=user_data)

assert response.status_code == 201
assert response.json() == {"id": ANY, "name": "Mr Sunglass", "email": "[email protected]", "age": 30}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from litestar.status_codes import HTTP_201_CREATED
from litestar.testing.client import TestClient


def test_create_underscored_value() -> None:
from docs.examples.data_transfer_objects.factory.leading_underscore_private import app

with TestClient(app=app) as client:
response = client.post("/", json={"this_will": "stay", "_this_will": "go_away!"})

assert response.status_code == HTTP_201_CREATED
assert response.json() == {"this_will": "stay"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from litestar.status_codes import HTTP_201_CREATED
from litestar.testing.client import TestClient


def test_create_underscored_field() -> None:
from docs.examples.data_transfer_objects.factory.leading_underscore_private_override import app

with TestClient(app=app) as client:
response = client.post("/", json={"this_will": "stay", "_this_will": "not_go_away!"})

assert response.status_code == HTTP_201_CREATED
assert response.json() == {"this_will": "stay", "_this_will": "not_go_away!"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pytest

from litestar.exceptions.dto_exceptions import InvalidAnnotationException


def test_should_raise_error_on_route_registration() -> None:
with pytest.raises(InvalidAnnotationException):
from docs.examples.data_transfer_objects.factory.type_checking import app # noqa: F401
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from litestar.status_codes import HTTP_201_CREATED
from litestar.testing.client import TestClient


def test_create_user(user_data: dict) -> None:
from docs.examples.data_transfer_objects.overriding_implicit_return_dto import app

with TestClient(app=app) as client:
response = client.post("/", json=user_data)

assert response.status_code == HTTP_201_CREATED
assert response.content == b"Mr Sunglass"
19 changes: 0 additions & 19 deletions tests/examples/test_dto/test_example_apps.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
from __future__ import annotations

from unittest.mock import ANY

from litestar.testing import TestClient


def test_dto_data_problem_statement_app() -> None:
from docs.examples.data_transfer_objects.factory.dto_data_problem_statement import app

with TestClient(app) as client:
response = client.post("/person", json={"name": "John", "age": 30})
assert response.status_code == 500


def test_dto_data_usage_app() -> None:
from docs.examples.data_transfer_objects.factory.dto_data_usage import app

with TestClient(app) as client:
response = client.post("/person", json={"name": "John", "age": 30})
assert response.status_code == 201
assert response.json() == {"id": ANY, "name": "John", "age": 30}


def test_dto_data_nested_data_create_instance_app() -> None:
from docs.examples.data_transfer_objects.factory.providing_values_for_nested_data import app

Expand Down

0 comments on commit d5196ed

Please sign in to comment.