mirror of
https://github.com/d3vyce/fastapi-toolsets.git
synced 2026-04-15 22:26:25 +02:00
feat: add get_field_by_attr fixtures helper (#245)
This commit is contained in:
@@ -2,12 +2,18 @@
|
|||||||
|
|
||||||
from .enum import LoadStrategy
|
from .enum import LoadStrategy
|
||||||
from .registry import Context, FixtureRegistry
|
from .registry import Context, FixtureRegistry
|
||||||
from .utils import get_obj_by_attr, load_fixtures, load_fixtures_by_context
|
from .utils import (
|
||||||
|
get_field_by_attr,
|
||||||
|
get_obj_by_attr,
|
||||||
|
load_fixtures,
|
||||||
|
load_fixtures_by_context,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Context",
|
"Context",
|
||||||
"FixtureRegistry",
|
"FixtureRegistry",
|
||||||
"LoadStrategy",
|
"LoadStrategy",
|
||||||
|
"get_field_by_attr",
|
||||||
"get_obj_by_attr",
|
"get_obj_by_attr",
|
||||||
"load_fixtures",
|
"load_fixtures",
|
||||||
"load_fixtures_by_context",
|
"load_fixtures_by_context",
|
||||||
|
|||||||
@@ -250,6 +250,31 @@ def get_obj_by_attr(
|
|||||||
) from None
|
) from None
|
||||||
|
|
||||||
|
|
||||||
|
def get_field_by_attr(
|
||||||
|
fixtures: Callable[[], Sequence[ModelType]],
|
||||||
|
attr_name: str,
|
||||||
|
value: Any,
|
||||||
|
*,
|
||||||
|
field: str = "id",
|
||||||
|
) -> Any:
|
||||||
|
"""Get a single field value from a fixture object matched by an attribute.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fixtures: A fixture function registered via ``@registry.register``
|
||||||
|
that returns a sequence of SQLAlchemy model instances.
|
||||||
|
attr_name: Name of the attribute to match against.
|
||||||
|
value: Value to match.
|
||||||
|
field: Attribute name to return from the matched object (default: ``"id"``).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value of ``field`` on the first matching model instance.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
StopIteration: If no matching object is found in the fixture group.
|
||||||
|
"""
|
||||||
|
return getattr(get_obj_by_attr(fixtures, attr_name, value), field)
|
||||||
|
|
||||||
|
|
||||||
async def load_fixtures(
|
async def load_fixtures(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
registry: FixtureRegistry,
|
registry: FixtureRegistry,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from fastapi_toolsets.fixtures import (
|
|||||||
Context,
|
Context,
|
||||||
FixtureRegistry,
|
FixtureRegistry,
|
||||||
LoadStrategy,
|
LoadStrategy,
|
||||||
|
get_field_by_attr,
|
||||||
get_obj_by_attr,
|
get_obj_by_attr,
|
||||||
load_fixtures,
|
load_fixtures,
|
||||||
load_fixtures_by_context,
|
load_fixtures_by_context,
|
||||||
@@ -951,6 +952,41 @@ class TestGetObjByAttr:
|
|||||||
get_obj_by_attr(self.roles, "id", "not-a-uuid")
|
get_obj_by_attr(self.roles, "id", "not-a-uuid")
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetFieldByAttr:
|
||||||
|
"""Tests for get_field_by_attr helper function."""
|
||||||
|
|
||||||
|
def setup_method(self):
|
||||||
|
self.registry = FixtureRegistry()
|
||||||
|
self.role_id_1 = uuid.uuid4()
|
||||||
|
self.role_id_2 = uuid.uuid4()
|
||||||
|
role_id_1 = self.role_id_1
|
||||||
|
role_id_2 = self.role_id_2
|
||||||
|
|
||||||
|
@self.registry.register
|
||||||
|
def roles() -> list[Role]:
|
||||||
|
return [
|
||||||
|
Role(id=role_id_1, name="admin"),
|
||||||
|
Role(id=role_id_2, name="user"),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.roles = roles
|
||||||
|
|
||||||
|
def test_returns_id_by_default(self):
|
||||||
|
"""Returns the id field when no field is specified."""
|
||||||
|
result = get_field_by_attr(self.roles, "name", "admin")
|
||||||
|
assert result == self.role_id_1
|
||||||
|
|
||||||
|
def test_returns_specified_field(self):
|
||||||
|
"""Returns the requested field instead of id."""
|
||||||
|
result = get_field_by_attr(self.roles, "id", self.role_id_2, field="name")
|
||||||
|
assert result == "user"
|
||||||
|
|
||||||
|
def test_no_match_raises_stop_iteration(self):
|
||||||
|
"""Propagates StopIteration from get_obj_by_attr when no match found."""
|
||||||
|
with pytest.raises(StopIteration, match="No object with name=missing"):
|
||||||
|
get_field_by_attr(self.roles, "name", "missing")
|
||||||
|
|
||||||
|
|
||||||
class TestGetPrimaryKey:
|
class TestGetPrimaryKey:
|
||||||
"""Unit tests for the _get_primary_key helper (composite PK paths)."""
|
"""Unit tests for the _get_primary_key helper (composite PK paths)."""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user