diff --git a/app/models/item.py b/app/models/item.py index 14bd92b..cd6491f 100644 --- a/app/models/item.py +++ b/app/models/item.py @@ -75,7 +75,7 @@ class Item(Base): # Relationships user = relationship("User", back_populates="items") - collection = relationship("Collection", back_populates="items") + collection = relationship("Collection", back_populates="items", lazy="selectin") tags = relationship("Tag", secondary=item_tags, back_populates="items", lazy="selectin") marks = relationship( "Mark", @@ -106,5 +106,9 @@ class Item(Base): cascade="all, delete-orphan", ) + @property + def collection_name(self) -> str | None: + return self.collection.name if self.collection else None + def __repr__(self) -> str: return f"" diff --git a/app/schemas/item.py b/app/schemas/item.py index 4dc7485..470bf64 100644 --- a/app/schemas/item.py +++ b/app/schemas/item.py @@ -106,6 +106,7 @@ class ItemRead(ItemBase): id: UUID user_id: UUID collection_id: UUID | None + collection_name: str | None = None tags: list[TagRead] = Field(default_factory=list) marks: list[MarkRead] = Field(default_factory=list) provenance_entries: list[ProvenanceEntryRead] = Field(default_factory=list) diff --git a/tests/test_items.py b/tests/test_items.py index 86cb0e2..224e4b9 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -578,3 +578,61 @@ async def test_items_isolation( data = response.json() assert len(data) == 1 assert data[0]["name"] == "My Item" + + +@pytest.mark.asyncio +async def test_collection_name_in_list( + client: AsyncClient, session: AsyncSession, test_user: User, auth_client +): + """Test that collection_name appears in list items response.""" + collection = Collection(user_id=str(test_user.id), name="Watches") + session.add(collection) + await session.commit() + await session.refresh(collection) + + item = Item(user_id=str(test_user.id), name="Rolex", collection_id=collection.id) + session.add(item) + await session.commit() + + response = await client.get("/items") + assert response.status_code == 200 + data = response.json() + assert len(data) == 1 + assert data[0]["collection_name"] == "Watches" + + +@pytest.mark.asyncio +async def test_collection_name_in_get( + client: AsyncClient, session: AsyncSession, test_user: User, auth_client +): + """Test that collection_name appears in single item response.""" + collection = Collection(user_id=str(test_user.id), name="Coins") + session.add(collection) + await session.commit() + await session.refresh(collection) + + item = Item(user_id=str(test_user.id), name="Gold Coin", collection_id=collection.id) + session.add(item) + await session.commit() + await session.refresh(item) + + response = await client.get(f"/items/{item.id}") + assert response.status_code == 200 + data = response.json() + assert data["collection_name"] == "Coins" + + +@pytest.mark.asyncio +async def test_collection_name_null_without_collection( + client: AsyncClient, session: AsyncSession, test_user: User, auth_client +): + """Test that collection_name is null when item has no collection.""" + item = Item(user_id=str(test_user.id), name="Loose Item") + session.add(item) + await session.commit() + await session.refresh(item) + + response = await client.get(f"/items/{item.id}") + assert response.status_code == 200 + data = response.json() + assert data["collection_name"] is None