From 81515d701a249fcb18cd2f496cba8dd25aad28a2 Mon Sep 17 00:00:00 2001 From: ychebyshev Date: Thu, 1 Feb 2024 23:38:27 +0300 Subject: [PATCH] added get game card and tests --- shvatka/api/models/responses.py | 49 ++++++++++++++++++++++++- shvatka/api/routes/game.py | 14 ++++++- tests/integration/api_full/conftest.py | 12 ++++++ tests/integration/api_full/test_game.py | 49 ++++++++++++++++++++++++- tests/integration/api_full/test_user.py | 12 ------ 5 files changed, 120 insertions(+), 16 deletions(-) diff --git a/shvatka/api/models/responses.py b/shvatka/api/models/responses.py index c13b76d2..e13a5f1f 100644 --- a/shvatka/api/models/responses.py +++ b/shvatka/api/models/responses.py @@ -1,7 +1,8 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field from datetime import datetime from shvatka.core.models import dto +from shvatka.core.models.dto import scn from shvatka.core.models.enums import GameStatus @@ -54,3 +55,49 @@ def from_core(cls, core: dto.Game | None): status=core.status, start_at=core.start_at, ) + + +@dataclass +class Level: + db_id: int + name_id: str + author: Player + scenario: scn.LevelScenario + game_id: int | None = None + number_in_game: int | None = None + + @classmethod + def from_core(cls, core: dto.Level | None = None): + if core is None: + return None + return cls( + db_id=core.db_id, + name_id=core.name_id, + author=Player.from_core(core.author), + scenario=core.scenario, + game_id=core.game_id, + number_in_game=core.number_in_game, + ) + + +@dataclass +class FullGame: + id: int + author: Player + name: str + status: GameStatus + start_at: datetime | None + levels: list[Level] = field(default_factory=list) + + @classmethod + def from_core(cls, core: dto.FullGame | None = None): + if core is None: + return None + return cls( + id=core.id, + author=Player.from_core(core.author), + name=core.name, + status=core.status, + start_at=core.start_at, + levels=[Level.from_core(level) for level in core.levels], + ) diff --git a/shvatka/api/routes/game.py b/shvatka/api/routes/game.py index fee37726..7ddcd103 100644 --- a/shvatka/api/routes/game.py +++ b/shvatka/api/routes/game.py @@ -1,12 +1,12 @@ from typing import Sequence from fastapi import APIRouter -from fastapi.params import Depends +from fastapi.params import Depends, Path from shvatka.api.dependencies import dao_provider, player_provider, active_game_provider from shvatka.api.models import responses from shvatka.core.models import dto -from shvatka.core.services.game import get_authors_games, get_completed_games +from shvatka.core.services.game import get_authors_games, get_completed_games, get_full_game from shvatka.infrastructure.db.dao.holder import HolderDao @@ -30,9 +30,19 @@ async def get_all_games( return [responses.Game.from_core(game) for game in games] +async def get_game_card( + dao: HolderDao = Depends(dao_provider), # type: ignore[assignment] + player: dto.Player = Depends(player_provider), # type: ignore[assignment] + id_: int = Path(alias="id"), # type: ignore[assignment] +): + game = await get_full_game(id_, player, dao.game) + return responses.FullGame.from_core(game) + + def setup() -> APIRouter: router = APIRouter(prefix="/games") router.add_api_route("", get_all_games, methods=["GET"]) router.add_api_route("/my", get_my_games_list, methods=["GET"]) router.add_api_route("/active", get_active_game, methods=["GET"]) + router.add_api_route("/{id}", get_game_card, methods=["GET"]) return router diff --git a/tests/integration/api_full/conftest.py b/tests/integration/api_full/conftest.py index 97928892..263694c8 100644 --- a/tests/integration/api_full/conftest.py +++ b/tests/integration/api_full/conftest.py @@ -12,6 +12,10 @@ from shvatka.api.dependencies import AuthProvider from shvatka.api.main_factory import create_app from shvatka.common import Paths +from shvatka.core.models import dto +from shvatka.core.services.user import upsert_user, set_password +from shvatka.infrastructure.db.dao.holder import HolderDao +from tests.fixtures.user_constants import create_dto_harry from tests.integration.conftest import game_log # noqa: F401 from tests.mocks.config import DBConfig @@ -45,3 +49,11 @@ def auth(api_config: ApiConfig): async def client(app: FastAPI) -> AsyncGenerator[AsyncClient, None]: async with AsyncClient(app=app, base_url="http://test") as ac: yield ac + + +@pytest_asyncio.fixture +async def user(dao: HolderDao, auth: AuthProvider) -> dto.User: + user_ = await upsert_user(create_dto_harry(), dao.user) + password = auth.get_password_hash("12345") + await set_password(user_, password, dao.user) + return user_ diff --git a/tests/integration/api_full/test_game.py b/tests/integration/api_full/test_game.py index 8e64e96f..fbcd3426 100644 --- a/tests/integration/api_full/test_game.py +++ b/tests/integration/api_full/test_game.py @@ -2,6 +2,7 @@ from dataclass_factory import Factory from httpx import AsyncClient +from shvatka.api.dependencies import AuthProvider from shvatka.api.models import responses from shvatka.core.models import dto from shvatka.core.models.enums import GameStatus @@ -9,7 +10,7 @@ @pytest.mark.asyncio -async def test_game(game: dto.FullGame, dao: HolderDao, client: AsyncClient): +async def test_active_game(game: dto.FullGame, dao: HolderDao, client: AsyncClient): await dao.game.start_waivers(game) await dao.commit() resp = await client.get("/games/active") @@ -20,3 +21,49 @@ async def test_game(game: dto.FullGame, dao: HolderDao, client: AsyncClient): actual = dcf.load(resp.json(), responses.Game) assert game.id == actual.id assert actual.status == GameStatus.getting_waivers + + +@pytest.mark.asyncio +async def test_games_list(finished_game: dto.FullGame, dao: HolderDao, client: AsyncClient): + await dao.game.set_completed(finished_game) + await dao.game.set_number(finished_game, 1) + await dao.commit() + resp = await client.get("/games") + assert resp.is_success + resp.read() + + dcf = Factory() + actual = dcf.load(resp.json(), list[responses.Game]) + assert len(actual) == 1 + game = actual[0] + assert game.id == finished_game.id + assert game.status == GameStatus.complete + + +@pytest.mark.asyncio +async def test_game_card( + finished_game: dto.FullGame, + dao: HolderDao, + client: AsyncClient, + auth: AuthProvider, + user: dto.User, +): + token = auth.create_user_token(user) + await dao.game.set_completed(finished_game) + await dao.game.set_number(finished_game, 1) + await dao.commit() + resp = await client.get( + f"/games/{finished_game.id}", + headers={"Authorization": "Bearer " + token.access_token}, + ) + assert resp.is_success + resp.read() + + dcf = Factory() + actual = dcf.load(resp.json(), responses.FullGame) + assert actual.id == finished_game.id + assert actual.status == GameStatus.complete + assert len(actual.levels) == len(finished_game.levels) + assert [lvl.scenario for lvl in actual.levels] == [ + lvl.scenario for lvl in finished_game.levels + ] diff --git a/tests/integration/api_full/test_user.py b/tests/integration/api_full/test_user.py index 857a4d9f..bc909eb1 100644 --- a/tests/integration/api_full/test_user.py +++ b/tests/integration/api_full/test_user.py @@ -1,20 +1,8 @@ import pytest -import pytest_asyncio from httpx import AsyncClient from shvatka.api.dependencies import AuthProvider from shvatka.core.models import dto -from shvatka.core.services.user import set_password, upsert_user -from shvatka.infrastructure.db.dao.holder import HolderDao -from tests.fixtures.user_constants import create_dto_harry - - -@pytest_asyncio.fixture -async def user(dao: HolderDao, auth: AuthProvider) -> dto.User: - user_ = await upsert_user(create_dto_harry(), dao.user) - password = auth.get_password_hash("12345") - await set_password(user_, password, dao.user) - return user_ @pytest.mark.asyncio