Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
koldakov committed May 8, 2024
1 parent c098718 commit c867a33
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
bdd_features_base_dir = tests/features/
Empty file added tests/__init__.py
Empty file.
14 changes: 14 additions & 0 deletions tests/features/entities.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Feature: Request entity
As a user,
I want to add or delete some items from my shopping cart,
So I can place order for my items.

Scenario Outline: Get entity
When The user requests the <entity_name> with id 1
Then The FuturamaAPI server responds with the <entity_name>

Examples:
| entity_name |
| character |
| episode |
| season |
Empty file added tests/functional/__init__.py
Empty file.
46 changes: 46 additions & 0 deletions tests/functional/test_entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# import pytest
# from pytest_bdd import scenario, then, when
# from pytest_bdd.parsers import parse
#
# from tests.helpers.enteties import EntityTestClient, get_entity_test_client
#
#
# @scenario(
# "entities.feature",
# "Get entity",
# )
# @pytest.mark.anyio
# async def test_get_entity():
# pass
#
#
# @when(
# parse("The user requests the {test_client} with id {entity_id}"),
# converters={
# "test_client": lambda v: get_entity_test_client(v),
# },
# target_fixture="request_result",
# )
# @pytest.mark.anyio
# async def request_entity(test_client: EntityTestClient, entity_id: int):
# from futuramaapi.main import app
# from httpx import AsyncClient
# from httpx import ASGITransport
# transport = ASGITransport(app)
# async with AsyncClient(transport=transport, base_url="http://test") as ac:
# response = await ac.get("/api/characters/1")
# return response.json()
# # return test_client.get(entity_id=entity_id)
#
#
# @then(
# parse("The FuturamaAPI server responds with the {test_client}"),
# converters={
# "test_client": lambda v: get_entity_test_client(v),
# },
# )
# @pytest.mark.anyio
# async def response_entity(request_result, test_client: EntityTestClient):
# res = await request_result
# response: test_client.entity = test_client.entity(**res)
# assert response.id == 1
15 changes: 15 additions & 0 deletions tests/helpers/enteties/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import typing

from .characters import CharactersTestClient
from .episodes import EpisodesTestClient
from .seasons import SeasonsTestClient

EntityTestClient = CharactersTestClient | EpisodesTestClient | SeasonsTestClient

ENTITY_TEST_CLIENT_MAP: dict[str, type[EntityTestClient]] = {
_class.entity_name: _class for _class in typing.get_args(EntityTestClient)
}


def get_entity_test_client(name: str, /) -> EntityTestClient:
return ENTITY_TEST_CLIENT_MAP[name]()
59 changes: 59 additions & 0 deletions tests/helpers/enteties/_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from abc import ABC, abstractmethod
from enum import StrEnum
from functools import cached_property
from typing import Any, ClassVar, Literal

from fastapi.testclient import TestClient

from futuramaapi.core import settings
from futuramaapi.main import app
from futuramaapi.pydantic._base import BaseModel


class EntityName(StrEnum):
character = "character"
episode = "episode"
season = "season"


class TestClientBase(ABC):
entity_name: ClassVar[EntityName]
entity: ClassVar[type[BaseModel]]

@property
def protocol(self) -> Literal["http", "https"]:
return "https"

@property
def entity_name_plural(self) -> str:
return f"{self.entity_name}s"

@abstractmethod
def assert_response(self, data: dict[str, Any], /) -> None: ...

@property
def headers(self) -> dict[str, str]:
return {
"host": settings.trusted_host,
"x-forwarded-proto": self.protocol,
"x-forwarded-port": "443",
}

@property
def path_base(self) -> str:
return "api"

@cached_property
def client(self) -> TestClient:
return TestClient(
app,
base_url=f"{self.protocol}://{settings.trusted_host}",
headers=self.headers,
)

def get(self, *, entity_id: int | None) -> dict[str, Any]:
path: str = f"{self.path_base}/{self.entity_name_plural}"
if entity_id is not None:
path += f"/{entity_id}"
response = self.client.get(path)
return response.json()
13 changes: 13 additions & 0 deletions tests/helpers/enteties/characters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Any

from futuramaapi.routers.characters.schemas import Character

from ._base import EntityName, TestClientBase


class CharactersTestClient(TestClientBase):
entity_name = EntityName.character
entity = Character

def assert_response(self, data: dict[str, Any], /) -> None:
pass
13 changes: 13 additions & 0 deletions tests/helpers/enteties/episodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Any

from futuramaapi.routers.episodes.schemas import Episode

from ._base import EntityName, TestClientBase


class EpisodesTestClient(TestClientBase):
entity_name = EntityName.episode
entity = Episode

def assert_response(self, data: dict[str, Any], /) -> None:
pass
13 changes: 13 additions & 0 deletions tests/helpers/enteties/seasons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Any

from futuramaapi.routers.seasons.schemas import Season

from ._base import EntityName, TestClientBase


class SeasonsTestClient(TestClientBase):
entity_name = EntityName.season
entity = Season

def assert_response(self, data: dict[str, Any], /) -> None:
pass

0 comments on commit c867a33

Please sign in to comment.