Skip to content

Commit

Permalink
[ADD] test_extendable_pydantic_fastapi: unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
marielejeune committed Jul 24, 2023
1 parent 291a534 commit 8ec5c45
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 6 deletions.
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ apispec>=4.0.0
cerberus
contextvars
extendable-pydantic
extendable-pydantic>0.0.5
extendable-pydantic>=1.0.0
extendable>=0.0.4
fastapi
Expand Down
1 change: 0 additions & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
httpx
extendable-pydantic @ git+https://github.com/lmignon/extendable-pydantic.git@refs/pull/7/head
3 changes: 2 additions & 1 deletion test_extendable_pydantic_fastapi/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"demo": [],
"external_dependencies": {
"python": [
"extendable-pydantic>0.0.5",
"pydantic>=2.0.0",
"extendable-pydantic>=1.0.0",
]
},
}
6 changes: 3 additions & 3 deletions test_extendable_pydantic_fastapi/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@


class Coordinate(BaseModel, metaclass=ExtendableModelMeta):
lat: int
lon: int
lat: float
lon: float


class ExtendedCoordinate(Coordinate, extends=Coordinate):
Expand All @@ -27,5 +27,5 @@ class SearchResponse(BaseModel, Generic[_T], metaclass=ExtendableModelMeta):

class CoordinateSearchResponse(SearchResponse[Coordinate]):
"""We declare the generic type of the items of the list as Coordinate
which is the base model of the extended. We used, it should be resolved
which is the base model of the extended. When used, it should be resolved
to ExtendedCoordinate"""
1 change: 1 addition & 0 deletions test_extendable_pydantic_fastapi/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_coordinate
71 changes: 71 additions & 0 deletions test_extendable_pydantic_fastapi/tests/test_coordinate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from requests import Response

from odoo.tests.common import tagged

from odoo.addons.extendable_fastapi.tests.common import FastAPITransactionCase

from ..routers import demo_pydantic_router
from ..schemas import Coordinate


@tagged("post_install", "-at_install")
class TestCoordinate(FastAPITransactionCase):
@classmethod
def setUpClass(cls) -> None:
super().setUpClass()

def test_app_components(self):
with self._create_test_client(router=demo_pydantic_router) as test_client:
to_openapi = test_client.app.openapi()
# Check post input and output types
self.assertEqual(
to_openapi["paths"]["/demo_pydantic"]["post"]["requestBody"]["content"][
"application/json"
]["schema"]["$ref"],
"#/components/schemas/Coordinate",
)
self.assertEqual(
to_openapi["paths"]["/demo_pydantic"]["post"]["responses"]["200"][
"content"
]["application/json"]["schema"]["$ref"],
"#/components/schemas/CoordinateSearchResponse",
)

# Check Pydantic model extension
self.assertEqual(
set(
to_openapi["components"]["schemas"]["Coordinate"][
"properties"
].keys()
),
{"lat", "lon", "name", "description"},
)
self.assertEqual(
to_openapi["components"]["schemas"]["CoordinateSearchResponse"][
"properties"
]["items"]["items"]["$ref"],
"#/components/schemas/Coordinate",
)

def test_post_coordinates(self):
name = "Bievre"
desc = "Small town in Belgium"
pydantic_data = Coordinate(lat=49.94, lon=5.02, name=name, description=desc)
# Assert that class was correctly extended
self.assertTrue(pydantic_data.name)
self.assertTrue(pydantic_data.description)

with self._create_test_client(router=demo_pydantic_router) as test_client:
response: Response = test_client.post(
"/demo_pydantic", content=pydantic_data.model_dump_json()
)
self.assertEqual(response.status_code, 200)
res = response.json()
self.assertEqual(res["total"], 1)
coordinate = res["items"][0]
self.assertEqual(coordinate["lat"], 49.94)
self.assertEqual(coordinate["lon"], 5.02)
self.assertEqual(coordinate["name"], name)
self.assertEqual(coordinate["description"], desc)

0 comments on commit 8ec5c45

Please sign in to comment.