diff --git a/app/api/cards.py b/app/api/cards.py index 36f08cd..6063c5f 100644 --- a/app/api/cards.py +++ b/app/api/cards.py @@ -41,7 +41,7 @@ async def create_cards( @ROUTER.put("/decks/{deck_id}/cards/") async def update_cards( deck_id: int, - data: list[schemas.Card], + data: list[schemas.CardUpdate], update_cards_use_case: UpdateCardsUseCase = FromDI(UpdateCardsUseCase), ) -> schemas.Cards: return schemas.Cards.from_models(await update_cards_use_case(deck_id=deck_id, data=data)) diff --git a/app/repositories.py b/app/repositories.py index 1e2f7e5..9accdc1 100644 --- a/app/repositories.py +++ b/app/repositories.py @@ -49,8 +49,8 @@ async def list_for_deck(self, deck_id: int) -> Sequence[models.Card]: async def add_cards(self, deck_id: int, cards: list[schemas.CardCreate]) -> Sequence[models.Card]: return await self.create_many([models.Card(**card.model_dump(), deck_id=deck_id) for card in cards]) - async def upsert_cards(self, deck_id: int, cards: list[schemas.Card]) -> Sequence[models.Card]: + async def upsert_cards(self, deck_id: int, cards: list[schemas.CardUpdate]) -> Sequence[models.Card]: upserted = await self.upsert_many( - [models.Card(**card.model_dump(exclude={"deck_id"}), deck_id=deck_id) for card in cards], + [models.Card(**card.model_dump(), deck_id=deck_id) for card in cards], ) return sorted(upserted, key=operator.attrgetter("id")) diff --git a/app/schemas.py b/app/schemas.py index 42a7fc5..f59a8a4 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -31,9 +31,12 @@ class CardCreate(CardBase): pass -class Card(CardBase): +class CardUpdate(CardBase): id: PositiveInt - deck_id: PositiveInt | None = None + + +class Card(CardUpdate): + deck_id: PositiveInt class Cards(Collection[Card]): diff --git a/app/use_cases/update_cards.py b/app/use_cases/update_cards.py index 6a6774c..291a893 100644 --- a/app/use_cases/update_cards.py +++ b/app/use_cases/update_cards.py @@ -14,7 +14,7 @@ class UpdateCardsUseCase: cards_repository: CardsRepository @postgres_retry - async def __call__(self, *, deck_id: int, data: list[schemas.Card]) -> Sequence[models.Card]: + async def __call__(self, *, deck_id: int, data: list[schemas.CardUpdate]) -> Sequence[models.Card]: async with self.transaction: cards: typing.Final = await self.cards_repository.upsert_cards(deck_id, data) await self.transaction.commit() diff --git a/tests/test_cards.py b/tests/test_cards.py index 2118284..6c0d876 100644 --- a/tests/test_cards.py +++ b/tests/test_cards.py @@ -135,3 +135,11 @@ async def test_cards_ordered_by_id_after_update(client: AsyncClient) -> None: response = await client.get(f"/api/decks/{deck.id}/cards/") assert response.status_code == status.HTTP_200_OK assert [x["id"] for x in response.json()["items"]] == [card1.id, card2.id] + + +async def test_openapi_card_deck_id_required(client: AsyncClient) -> None: + response = await client.get("/openapi.json") + assert response.status_code == status.HTTP_200_OK + card_schema = response.json()["components"]["schemas"]["Card"] + assert "deck_id" in card_schema["required"] + assert "null" not in {x.get("type") for x in card_schema["properties"]["deck_id"].get("anyOf", [])}