Skip to content

Commit

Permalink
add Event Group routers tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vtecovsky committed Aug 12, 2023
1 parent d6c2e2c commit 28f6541
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 9 deletions.
7 changes: 1 addition & 6 deletions src/storages/sql_storage/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ class User:
groups = Column("groups", String)


group = Table(
"group",
metadata,
Column("name", String),
Column("type", String)
)
group = Table("group", metadata, Column("name", String), Column("type", String))

user = Table(
"user",
Expand Down
94 changes: 94 additions & 0 deletions tests/app/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import httpx
import pytest
import pytest_asyncio
from sqlalchemy.ext.asyncio import AsyncSession

from src.config import Settings, settings as config_settings
from src.main import app
from src.repositories.event_groups import AbstractEventGroupRepository, SqlEventGroupRepository
from src.repositories.events import AbstractEventRepository, SqlEventRepository
from src.repositories.tags import AbstractTagRepository, SqlTagRepository
from src.repositories.users import AbstractUserRepository, SqlUserRepository
from src.storages.sql import AbstractSQLAlchemyStorage, SQLAlchemyStorage


# --- Monkey Patching --- #
@pytest.fixture(scope="session")
def monkeysession():
from _pytest.monkeypatch import MonkeyPatch

mpatch = MonkeyPatch()
yield mpatch
mpatch.undo()


# --- Settings Fixtures --- #
@pytest.fixture(scope="package")
def settings() -> "Settings":
return config_settings


# --- Storage Fixtures --- #
@pytest.fixture(scope="package")
def storage(settings: "Settings") -> "AbstractSQLAlchemyStorage":
_storage = SQLAlchemyStorage.from_url(settings.DB_URL.get_secret_value())
return _storage


@pytest_asyncio.fixture(scope="function", autouse=True)
async def setup_storage(storage: "AbstractSQLAlchemyStorage"):
# Create the necessary tables before each test
async with storage.create_session() as session:
await _init_models(session)
await session.commit()
yield

# Close the database connection after each test
async with storage.create_session() as session:
await _restore_session(session)
await session.commit()
await storage.close_connection()


async def _init_models(session: AsyncSession):
from src.storages.sql.models.base import Base

async with session.bind.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)


@pytest_asyncio.fixture()
async def client():
async with httpx.AsyncClient(app=app, base_url="http://127.0.0.1:8000/") as client:
yield client

async def _restore_session(session: AsyncSession):
from src.storages.sql.models.base import Base

async with session.begin():
for table in reversed(Base.metadata.sorted_tables):
await session.execute(table.delete())


# --- Repository Fixtures --- #


@pytest.fixture(scope="package")
def user_repository(storage) -> "AbstractUserRepository":
return SqlUserRepository(storage)


@pytest.fixture(scope="package")
def event_group_repository(storage) -> "AbstractEventGroupRepository":
return SqlEventGroupRepository(storage)


@pytest.fixture(scope="package")
def tag_repository(storage) -> "AbstractTagRepository":
return SqlTagRepository(storage)


@pytest.fixture(scope="package")
def event_repository(storage) -> "AbstractEventRepository":
return SqlEventRepository(storage)
62 changes: 62 additions & 0 deletions tests/app/event_group_routers/test_routers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import httpx
import pytest

from src.main import setup_repositories
from tests.misc.test_nonobvious_schemas import get_fake_create_event_group


async def create_event_group(event_group_repository):
await setup_repositories()
event_group_schema = get_fake_create_event_group()
event_group = await event_group_repository.create_or_read(event_group_schema)
return event_group


@pytest.mark.asyncio
async def test_get_event_group(client: httpx.AsyncClient, event_group_repository):
event_group = await create_event_group(event_group_repository)
response = await client.get(f"event-groups/{event_group.id}")
response_from_api = response.json()
assert response.status_code == 200
assert event_group.alias in response_from_api["alias"]
assert event_group.id == response_from_api["id"]
assert event_group.path in response_from_api["path"]
assert event_group.name in response_from_api["name"]


@pytest.mark.asyncio
async def test_find_event_group_by_path(client: httpx.AsyncClient, event_group_repository):
event_group = await create_event_group(event_group_repository)
response = await client.get(f"event-groups/by-path?path={event_group.path}")
assert response.status_code == 200
response_from_api = response.json()
assert event_group.alias in response_from_api["alias"]
assert event_group.id == response_from_api["id"]
assert event_group.path in response_from_api["path"]
assert event_group.name in response_from_api["name"]


@pytest.mark.asyncio
async def test_not_find_event_group_by_path(client: httpx.AsyncClient, event_group_repository):
await setup_repositories()
response = await client.get(f"event-groups/by-path?path=nonexistingpath")
assert response.status_code == 404


@pytest.mark.asyncio
async def test_list_event_groups(client: httpx.AsyncClient, event_group_repository):
event_groups = []
event_groups_number = 10
for i in range(event_groups_number):
event_group = await create_event_group(event_group_repository)
event_groups.append(event_group)
response = await client.get(f"event-groups/")
response_from_api = response.json()
assert response.status_code == 200
for i in range(event_groups_number):
assert response_from_api["groups"][i]["alias"] == event_groups[i].alias
assert response_from_api["groups"][i]["name"] == event_groups[i].name
assert response_from_api["groups"][i]["path"] == event_groups[i].path
assert response_from_api["groups"][i]["description"] == event_groups[i].description
assert len(response_from_api["groups"][i]["ownerships"]) == 0
assert len(response_from_api["groups"][i]["tags"]) == 0
17 changes: 15 additions & 2 deletions tests/app/test_app_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
JsonTagStorage,
)

from src.main import app
from src.main import settings

fake = Faker()


Expand Down Expand Up @@ -82,9 +85,19 @@ def fake_user() -> JsonUserStorage.InJsonUser:

@pytest.mark.asyncio
async def test_startup():
from src.main import app

assert isinstance(app, FastAPI)

with TestClient(app):
...


def test_version():
client = TestClient(app)

response = client.get("/")
assert response.status_code == 200
assert response.json() == {
"title": settings.APP_TITLE,
"description": settings.APP_DESCRIPTION,
"version": settings.APP_VERSION,
}
6 changes: 5 additions & 1 deletion tests/misc/test_nonobvious_schemas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from faker import Faker

from src.schemas.event_groups import ListEventGroupsResponse, ViewEventGroup
from src.schemas.event_groups import ListEventGroupsResponse, ViewEventGroup, CreateEventGroup

fake = Faker()
i = 0
Expand All @@ -12,6 +12,10 @@ def get_fake_event_group():
return ViewEventGroup(id=i, alias=fake.slug(), path=fake.word(), name=fake.word(), description=fake.word(), tags=[])


def get_fake_create_event_group():
return CreateEventGroup(alias=fake.slug(), path=fake.word(), name=fake.word(), description=fake.word(), tags=[])


def test_list_event_groups_from_iterable():
groups = (get_fake_event_group() for _ in range(10))
response = ListEventGroupsResponse.from_iterable(groups)
Expand Down
8 changes: 8 additions & 0 deletions tests/repositories/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import httpx
import pytest
import pytest_asyncio
from sqlalchemy.ext.asyncio import AsyncSession

from src.config import Settings, settings as config_settings
from src.main import app
from src.repositories.event_groups import AbstractEventGroupRepository, SqlEventGroupRepository
from src.repositories.events import AbstractEventRepository, SqlEventRepository
from src.repositories.tags import AbstractTagRepository, SqlTagRepository
Expand All @@ -26,6 +28,12 @@ def settings() -> "Settings":
return config_settings


@pytest_asyncio.fixture()
async def client():
async with httpx.AsyncClient(app=app, base_url="http://127.0.0.1:8000/") as client:
yield client


# --- Storage Fixtures --- #
@pytest.fixture(scope="package")
def storage(settings: "Settings") -> "AbstractSQLAlchemyStorage":
Expand Down

1 comment on commit 28f6541

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
src
   exceptions.py31777%11, 24, 36, 48, 72, 84, 96
src/app/auth
   common.py281739%12–21, 25–32, 36–44, 49–50
   dependencies.py16662%33–38, 42
   jwt.py452936%25–27, 31–35, 39–43, 47–51, 55–63, 67–74
src/app/event_groups
   routes.py784345%25–27, 39–46, 86–90, 110, 152–178, 192–201, 219–228
src/app/tags
   routes.py10280%24–25
src/app/users
   routes.py654334%43–45, 62–105, 124–129, 147–149, 170–175
src/repositories
   crud.py93990%86–91, 126, 139–140
src/repositories/event_groups
   repository.py57296%44–45
src/schemas
   events.py71692%48, 56, 79, 98–100
   tags.py40198%36
TOTAL129516587% 

Tests Skipped Failures Errors Time
52 0 💤 0 ❌ 0 🔥 9.835s ⏱️

Please sign in to comment.