mirror of
https://github.com/d3vyce/fastapi-toolsets.git
synced 2026-03-01 17:00:48 +01:00
187 lines
5.9 KiB
Python
187 lines
5.9 KiB
Python
"""Tests for fastapi_toolsets.dependencies module."""
|
|
|
|
import inspect
|
|
import uuid
|
|
from collections.abc import AsyncGenerator
|
|
from typing import Any, cast
|
|
|
|
import pytest
|
|
from fastapi.params import Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from fastapi_toolsets.dependencies import BodyDependency, PathDependency
|
|
|
|
from .conftest import Role, RoleCreate, RoleCrud, User
|
|
|
|
|
|
async def mock_get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
"""Mock session dependency for testing."""
|
|
yield None
|
|
|
|
|
|
class TestPathDependency:
|
|
"""Tests for PathDependency factory."""
|
|
|
|
def test_returns_depends_instance(self):
|
|
"""PathDependency returns a Depends instance."""
|
|
dep = PathDependency(Role, Role.id, session_dep=mock_get_db)
|
|
assert isinstance(dep, Depends)
|
|
|
|
def test_signature_has_default_param_name(self):
|
|
"""PathDependency uses model_field as default param name."""
|
|
dep = cast(Any, PathDependency(Role, Role.id, session_dep=mock_get_db))
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
params = list(sig.parameters.keys())
|
|
|
|
assert "role_id" in params
|
|
assert "session" in params
|
|
|
|
def test_signature_has_correct_type_annotation(self):
|
|
"""PathDependency uses field's python type for annotation."""
|
|
dep = cast(Any, PathDependency(Role, Role.id, session_dep=mock_get_db))
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
|
|
assert sig.parameters["role_id"].annotation == uuid.UUID
|
|
assert sig.parameters["session"].annotation == AsyncSession
|
|
|
|
def test_signature_session_has_depends_default(self):
|
|
"""PathDependency session param has Depends as default."""
|
|
dep = cast(Any, PathDependency(Role, Role.id, session_dep=mock_get_db))
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
|
|
assert isinstance(sig.parameters["session"].default, Depends)
|
|
|
|
def test_custom_param_name_in_signature(self):
|
|
"""PathDependency uses custom param_name in signature."""
|
|
dep = cast(
|
|
Any,
|
|
PathDependency(
|
|
Role, Role.id, session_dep=mock_get_db, param_name="role_uuid"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
params = list(sig.parameters.keys())
|
|
|
|
assert "role_uuid" in params
|
|
assert "id" not in params
|
|
|
|
def test_string_field_type(self):
|
|
"""PathDependency handles string field types."""
|
|
dep = cast(Any, PathDependency(User, User.username, session_dep=mock_get_db))
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
|
|
assert sig.parameters["user_username"].annotation is str
|
|
|
|
@pytest.mark.anyio
|
|
async def test_dependency_fetches_object(self, db_session):
|
|
"""PathDependency inner function fetches object from database."""
|
|
role = await RoleCrud.create(db_session, RoleCreate(name="test_role"))
|
|
|
|
dep = cast(Any, PathDependency(Role, Role.id, session_dep=mock_get_db))
|
|
func = dep.dependency
|
|
|
|
result = await func(session=db_session, role_id=role.id)
|
|
|
|
assert result.id == role.id
|
|
assert result.name == "test_role"
|
|
|
|
|
|
class TestBodyDependency:
|
|
"""Tests for BodyDependency factory."""
|
|
|
|
def test_returns_depends_instance(self):
|
|
"""BodyDependency returns a Depends instance."""
|
|
dep = BodyDependency(
|
|
Role, Role.id, session_dep=mock_get_db, body_field="role_id"
|
|
)
|
|
assert isinstance(dep, Depends)
|
|
|
|
def test_signature_has_body_field_as_param(self):
|
|
"""BodyDependency uses body_field as param name."""
|
|
dep = cast(
|
|
Any,
|
|
BodyDependency(
|
|
Role, Role.id, session_dep=mock_get_db, body_field="role_id"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
params = list(sig.parameters.keys())
|
|
|
|
assert "role_id" in params
|
|
assert "session" in params
|
|
|
|
def test_signature_has_correct_type_annotation(self):
|
|
"""BodyDependency uses field's python type for annotation."""
|
|
dep = cast(
|
|
Any,
|
|
BodyDependency(
|
|
Role, Role.id, session_dep=mock_get_db, body_field="role_id"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
|
|
assert sig.parameters["role_id"].annotation == uuid.UUID
|
|
assert sig.parameters["session"].annotation == AsyncSession
|
|
|
|
def test_signature_session_has_depends_default(self):
|
|
"""BodyDependency session param has Depends as default."""
|
|
dep = cast(
|
|
Any,
|
|
BodyDependency(
|
|
Role, Role.id, session_dep=mock_get_db, body_field="role_id"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
|
|
assert isinstance(sig.parameters["session"].default, Depends)
|
|
|
|
def test_different_body_field_name(self):
|
|
"""BodyDependency can use any body_field name."""
|
|
dep = cast(
|
|
Any,
|
|
BodyDependency(
|
|
User, User.id, session_dep=mock_get_db, body_field="user_uuid"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
sig = inspect.signature(func)
|
|
params = list(sig.parameters.keys())
|
|
|
|
assert "user_uuid" in params
|
|
assert "id" not in params
|
|
|
|
@pytest.mark.anyio
|
|
async def test_dependency_fetches_object(self, db_session):
|
|
"""BodyDependency inner function fetches object from database."""
|
|
role = await RoleCrud.create(db_session, RoleCreate(name="body_test_role"))
|
|
|
|
dep = cast(
|
|
Any,
|
|
BodyDependency(
|
|
Role, Role.id, session_dep=mock_get_db, body_field="role_id"
|
|
),
|
|
)
|
|
func = dep.dependency
|
|
|
|
result = await func(session=db_session, role_id=role.id)
|
|
|
|
assert result.id == role.id
|
|
assert result.name == "body_test_role"
|