mirror of
https://github.com/evroon/bracket.git
synced 2026-02-25 11:18:49 -05:00
Add more integration tests (#40)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
from fastapi import FastAPI
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
|
||||
from bracket.config import config
|
||||
from bracket.config import Environment, config, environment
|
||||
from bracket.database import database
|
||||
from bracket.routes import auth, matches, players, rounds, teams, tournaments
|
||||
from bracket.routes import auth, clubs, matches, players, rounds, teams, tournaments
|
||||
|
||||
app = FastAPI(
|
||||
title="Bracket API",
|
||||
@@ -30,7 +30,10 @@ async def startup() -> None:
|
||||
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown() -> None:
|
||||
await database.disconnect()
|
||||
# On CI, we need first to clean up db data in conftest.py before we can disconnect the
|
||||
# db connections.
|
||||
if environment != Environment.CI:
|
||||
await database.disconnect()
|
||||
|
||||
|
||||
@app.get('/ping', summary="Healthcheck ping")
|
||||
@@ -39,6 +42,7 @@ async def ping() -> str:
|
||||
|
||||
|
||||
app.include_router(auth.router, tags=['auth'])
|
||||
app.include_router(clubs.router, tags=['clubs'])
|
||||
app.include_router(tournaments.router, tags=['tournaments'])
|
||||
app.include_router(players.router, tags=['players'])
|
||||
app.include_router(rounds.router, tags=['rounds'])
|
||||
|
||||
@@ -2,18 +2,12 @@ from fastapi import APIRouter, Depends
|
||||
from heliclockter import datetime_utc
|
||||
|
||||
from bracket.database import database
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.team import Team, TeamBody, TeamToInsert, TeamWithPlayers
|
||||
from bracket.models.db.user import UserPublic
|
||||
from bracket.routes.auth import get_current_user
|
||||
from bracket.routes.models import (
|
||||
SingleTeamResponse,
|
||||
SuccessResponse,
|
||||
TeamsResponse,
|
||||
TeamsWithPlayersResponse,
|
||||
)
|
||||
from bracket.routes.models import SingleTeamResponse, SuccessResponse, TeamsWithPlayersResponse
|
||||
from bracket.schema import players, teams
|
||||
from bracket.utils.db import fetch_all_parsed, fetch_one_parsed
|
||||
from bracket.utils.db import fetch_one_parsed
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from heliclockter import datetime_utc
|
||||
from passlib.context import CryptContext
|
||||
|
||||
@@ -11,27 +13,29 @@ from bracket.models.db.user import User
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
DUMMY_MOCK_TIME = datetime_utc(2022, 1, 11, 4, 32, 11, tzinfo=ZoneInfo('UTC'))
|
||||
|
||||
DUMMY_CLUB = Club(
|
||||
name='Some Cool Club',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
)
|
||||
|
||||
DUMMY_TOURNAMENT = Tournament(
|
||||
club_id=1,
|
||||
name='Some Cool Tournament',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
)
|
||||
|
||||
DUMMY_ROUND1 = Round(
|
||||
tournament_id=1,
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_draft=False,
|
||||
name='Round 1',
|
||||
)
|
||||
|
||||
DUMMY_ROUND2 = Round(
|
||||
tournament_id=1,
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_active=True,
|
||||
is_draft=False,
|
||||
name='Round 2',
|
||||
@@ -39,13 +43,13 @@ DUMMY_ROUND2 = Round(
|
||||
|
||||
DUMMY_ROUND3 = Round(
|
||||
tournament_id=1,
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_draft=True,
|
||||
name='Round 3',
|
||||
)
|
||||
|
||||
DUMMY_MATCH1 = Match(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
round_id=1,
|
||||
team1_id=1,
|
||||
team2_id=2,
|
||||
@@ -54,7 +58,7 @@ DUMMY_MATCH1 = Match(
|
||||
)
|
||||
|
||||
DUMMY_MATCH2 = Match(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
round_id=1,
|
||||
team1_id=3,
|
||||
team2_id=4,
|
||||
@@ -63,7 +67,7 @@ DUMMY_MATCH2 = Match(
|
||||
)
|
||||
|
||||
DUMMY_MATCH3 = Match(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
round_id=2,
|
||||
team1_id=1,
|
||||
team2_id=4,
|
||||
@@ -72,7 +76,7 @@ DUMMY_MATCH3 = Match(
|
||||
)
|
||||
|
||||
DUMMY_MATCH4 = Match(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
round_id=2,
|
||||
team1_id=2,
|
||||
team2_id=3,
|
||||
@@ -84,32 +88,32 @@ DUMMY_USER = User(
|
||||
email='admin@example.com',
|
||||
name='Admin',
|
||||
password_hash=pwd_context.hash('adminadmin'),
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
)
|
||||
|
||||
DUMMY_TEAM1 = Team(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name='Team 1',
|
||||
tournament_id=1,
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM2 = Team(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name='Team 2',
|
||||
tournament_id=1,
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM3 = Team(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name='Team 3',
|
||||
tournament_id=1,
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM4 = Team(
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name='Team 4',
|
||||
tournament_id=1,
|
||||
active=True,
|
||||
@@ -118,7 +122,7 @@ DUMMY_TEAM4 = Team(
|
||||
|
||||
DUMMY_PLAYER1 = Player(
|
||||
name='Luke',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=1,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -126,7 +130,7 @@ DUMMY_PLAYER1 = Player(
|
||||
|
||||
DUMMY_PLAYER2 = Player(
|
||||
name='Anakin',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=1,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -134,7 +138,7 @@ DUMMY_PLAYER2 = Player(
|
||||
|
||||
DUMMY_PLAYER3 = Player(
|
||||
name='Leia',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=2,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -142,7 +146,7 @@ DUMMY_PLAYER3 = Player(
|
||||
|
||||
DUMMY_PLAYER4 = Player(
|
||||
name='Yoda',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=2,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -150,7 +154,7 @@ DUMMY_PLAYER4 = Player(
|
||||
|
||||
DUMMY_PLAYER5 = Player(
|
||||
name='Boba',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=3,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -158,7 +162,7 @@ DUMMY_PLAYER5 = Player(
|
||||
|
||||
DUMMY_PLAYER6 = Player(
|
||||
name='General',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=3,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -166,7 +170,7 @@ DUMMY_PLAYER6 = Player(
|
||||
|
||||
DUMMY_PLAYER7 = Player(
|
||||
name='Han',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=4,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -174,7 +178,7 @@ DUMMY_PLAYER7 = Player(
|
||||
|
||||
DUMMY_PLAYER8 = Player(
|
||||
name='Emperor',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=4,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
@@ -182,7 +186,7 @@ DUMMY_PLAYER8 = Player(
|
||||
|
||||
DUMMY_PLAYER9 = Player(
|
||||
name='R2D2',
|
||||
created=datetime_utc.now(),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
team_id=None,
|
||||
tournament_id=1,
|
||||
elo_score=0,
|
||||
|
||||
@@ -3,6 +3,6 @@ set -evo pipefail
|
||||
|
||||
black .
|
||||
dmypy run -- --follow-imports=normal --junit-xml= .
|
||||
ENVIRONMENT=CI pytest --cov .
|
||||
ENVIRONMENT=CI pytest --cov --cov-report=xml .
|
||||
pylint alembic bracket tests
|
||||
isort .
|
||||
|
||||
@@ -61,6 +61,7 @@ disable = [
|
||||
'unused-argument', # Gives false positives.
|
||||
'invalid-name',
|
||||
'dangerous-default-value',
|
||||
'duplicate-code',
|
||||
]
|
||||
|
||||
[tool.bandit]
|
||||
|
||||
@@ -8,7 +8,7 @@ from bracket.config import config
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import JsonDict
|
||||
from tests.integration_tests.api.shared import send_request
|
||||
from tests.integration_tests.mocks import MOCK_NOW, MOCK_USER
|
||||
from tests.integration_tests.mocks import MOCK_NOW, MOCK_USER, get_mock_token
|
||||
from tests.integration_tests.sql import inserted_user
|
||||
|
||||
|
||||
@@ -47,12 +47,7 @@ async def test_get_token_invalid_credentials(startup_and_shutdown_uvicorn_server
|
||||
|
||||
|
||||
async def test_auth_on_protected_endpoint(startup_and_shutdown_uvicorn_server: None) -> None:
|
||||
token = (
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'
|
||||
+ 'eyJ1c2VyIjoiZG9uYWxkX2R1Y2siLCJleHAiOjcyNTgxMjAyMDB9.'
|
||||
+ 'CRk4n5gmgto5K-qWtI4hbcqo92BxLkggwwK1yTgWGLM'
|
||||
)
|
||||
headers = {'Authorization': f'Bearer {token}'}
|
||||
headers = {'Authorization': f'Bearer {get_mock_token()}'}
|
||||
|
||||
async with inserted_user(MOCK_USER) as user_inserted:
|
||||
response = JsonDict(await send_request(HTTPMethod.GET, 'users/me', {}, headers))
|
||||
|
||||
18
backend/tests/integration_tests/api/clubs_test.py
Normal file
18
backend/tests/integration_tests/api/clubs_test.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from bracket.utils.dummy_records import DUMMY_MOCK_TIME
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from tests.integration_tests.api.shared import send_auth_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
|
||||
|
||||
async def test_clubs_endpoint(
|
||||
startup_and_shutdown_uvicorn_server: None, auth_context: AuthContext
|
||||
) -> None:
|
||||
assert await send_auth_request(HTTPMethod.GET, 'clubs', auth_context, {}) == {
|
||||
'data': [
|
||||
{
|
||||
'created': DUMMY_MOCK_TIME.isoformat(),
|
||||
'id': 1,
|
||||
'name': 'Some Cool Club',
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
# pylint: disable=redefined-outer-name
|
||||
import asyncio
|
||||
import os
|
||||
from asyncio import AbstractEventLoop
|
||||
from functools import partial
|
||||
from typing import AsyncIterator, Iterator
|
||||
from typing import AsyncIterator
|
||||
|
||||
import aioresponses
|
||||
import pytest
|
||||
from aiohttp import ClientResponse
|
||||
from databases import Database
|
||||
|
||||
from bracket.database import database, engine
|
||||
from bracket.schema import metadata
|
||||
from tests.integration_tests.api.shared import UvicornTestServer
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_auth_context
|
||||
|
||||
os.environ['ENVIRONMENT'] = 'CI'
|
||||
|
||||
@@ -29,13 +29,6 @@ async def startup_and_shutdown_uvicorn_server() -> AsyncIterator[None]:
|
||||
await server.down()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_http() -> Iterator[aioresponses.aioresponses]:
|
||||
with aioresponses.aioresponses() as m:
|
||||
m.add = partial(m.add, response_class=ClientResponse) # type: ignore[assignment]
|
||||
yield m
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def event_loop() -> AsyncIterator[AbstractEventLoop]: # type: ignore[misc]
|
||||
try:
|
||||
@@ -48,10 +41,18 @@ def event_loop() -> AsyncIterator[AbstractEventLoop]: # type: ignore[misc]
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
async def reinit_database(
|
||||
event_loop: AbstractEventLoop, # pylint: disable=redefined-outer-name
|
||||
) -> AsyncIterator[Database]:
|
||||
async def reinit_database(event_loop: AbstractEventLoop) -> AsyncIterator[Database]:
|
||||
await database.connect()
|
||||
metadata.drop_all(engine)
|
||||
metadata.create_all(engine)
|
||||
yield database
|
||||
try:
|
||||
yield database
|
||||
finally:
|
||||
await database.disconnect()
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
async def auth_context(reinit_database: Database) -> AsyncIterator[AuthContext]:
|
||||
async with reinit_database:
|
||||
async with inserted_auth_context() as auth_context:
|
||||
yield auth_context
|
||||
|
||||
24
backend/tests/integration_tests/api/players_test.py
Normal file
24
backend/tests/integration_tests/api/players_test.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from bracket.utils.dummy_records import DUMMY_MOCK_TIME, DUMMY_PLAYER1, DUMMY_TEAM1
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from tests.integration_tests.api.shared import send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_player, inserted_team
|
||||
|
||||
|
||||
async def test_players_endpoint(
|
||||
startup_and_shutdown_uvicorn_server: None, auth_context: AuthContext
|
||||
) -> None:
|
||||
async with inserted_team(DUMMY_TEAM1):
|
||||
async with inserted_player(DUMMY_PLAYER1) as player_inserted:
|
||||
assert await send_tournament_request(HTTPMethod.GET, 'players', auth_context, {}) == {
|
||||
'data': [
|
||||
{
|
||||
'created': DUMMY_MOCK_TIME.isoformat(),
|
||||
'id': player_inserted.id,
|
||||
'elo_score': 0.0,
|
||||
'name': 'Luke',
|
||||
'team_id': 1,
|
||||
'tournament_id': 1,
|
||||
}
|
||||
],
|
||||
}
|
||||
25
backend/tests/integration_tests/api/rounds_test.py
Normal file
25
backend/tests/integration_tests/api/rounds_test.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from bracket.utils.dummy_records import DUMMY_MOCK_TIME, DUMMY_ROUND1, DUMMY_TEAM1
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from tests.integration_tests.api.shared import send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_round, inserted_team
|
||||
|
||||
|
||||
async def test_rounds_endpoint(
|
||||
startup_and_shutdown_uvicorn_server: None, auth_context: AuthContext
|
||||
) -> None:
|
||||
async with inserted_team(DUMMY_TEAM1):
|
||||
async with inserted_round(DUMMY_ROUND1) as round_inserted:
|
||||
assert await send_tournament_request(HTTPMethod.GET, 'rounds', auth_context, {}) == {
|
||||
'data': [
|
||||
{
|
||||
'created': DUMMY_MOCK_TIME.isoformat(),
|
||||
'id': round_inserted.id,
|
||||
'is_active': False,
|
||||
'is_draft': False,
|
||||
'matches': [],
|
||||
'name': 'Round 1',
|
||||
'tournament_id': 1,
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -10,6 +10,7 @@ from fastapi import FastAPI
|
||||
from bracket.app import app
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import JsonDict, JsonObject
|
||||
from tests.integration_tests.models import AuthContext
|
||||
|
||||
|
||||
def find_free_port() -> int:
|
||||
@@ -74,3 +75,17 @@ async def send_request(
|
||||
) as resp:
|
||||
response: JsonObject = await resp.json()
|
||||
return response
|
||||
|
||||
|
||||
async def send_auth_request(
|
||||
method: HTTPMethod, endpoint: str, auth_context: AuthContext, body: JsonDict = {}
|
||||
) -> JsonObject:
|
||||
return await send_request(method, endpoint, body, auth_context.headers)
|
||||
|
||||
|
||||
async def send_tournament_request(
|
||||
method: HTTPMethod, endpoint: str, auth_context: AuthContext, body: JsonDict = {}
|
||||
) -> JsonObject:
|
||||
return await send_request(
|
||||
method, f'tournaments/{auth_context.tournament.id}/{endpoint}', body, auth_context.headers
|
||||
)
|
||||
|
||||
23
backend/tests/integration_tests/api/teams_test.py
Normal file
23
backend/tests/integration_tests/api/teams_test.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from bracket.utils.dummy_records import DUMMY_MOCK_TIME, DUMMY_TEAM1
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from tests.integration_tests.api.shared import send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_team
|
||||
|
||||
|
||||
async def test_teams_endpoint(
|
||||
startup_and_shutdown_uvicorn_server: None, auth_context: AuthContext
|
||||
) -> None:
|
||||
async with inserted_team(DUMMY_TEAM1) as team_inserted:
|
||||
assert await send_tournament_request(HTTPMethod.GET, 'teams', auth_context, {}) == {
|
||||
'data': [
|
||||
{
|
||||
'active': True,
|
||||
'created': DUMMY_MOCK_TIME.isoformat(),
|
||||
'id': team_inserted.id,
|
||||
'name': 'Team 1',
|
||||
'players': [],
|
||||
'tournament_id': 1,
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -9,6 +9,14 @@ MOCK_NOW = datetime_utc(
|
||||
)
|
||||
|
||||
|
||||
def get_mock_token() -> str:
|
||||
return (
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'
|
||||
+ 'eyJ1c2VyIjoiZG9uYWxkX2R1Y2siLCJleHAiOjcyNTgxMjAyMDB9.'
|
||||
+ 'CRk4n5gmgto5K-qWtI4hbcqo92BxLkggwwK1yTgWGLM'
|
||||
)
|
||||
|
||||
|
||||
MOCK_USER = User(
|
||||
email='donald_duck',
|
||||
name='Donald Duck',
|
||||
|
||||
12
backend/tests/integration_tests/models.py
Normal file
12
backend/tests/integration_tests/models.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
from bracket.models.db.club import Club
|
||||
from bracket.models.db.tournament import Tournament
|
||||
from bracket.models.db.user import User
|
||||
|
||||
|
||||
class AuthContext(BaseModel):
|
||||
club: Club
|
||||
tournament: Tournament
|
||||
user: User
|
||||
headers: dict[str, str]
|
||||
@@ -1,20 +1,90 @@
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import AsyncIterator
|
||||
from typing import AsyncIterator, Type, cast
|
||||
|
||||
from sqlalchemy import Table
|
||||
|
||||
from bracket.database import database
|
||||
from bracket.models.db.club import Club
|
||||
from bracket.models.db.match import Match
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.round import Round
|
||||
from bracket.models.db.team import Team
|
||||
from bracket.models.db.tournament import Tournament
|
||||
from bracket.models.db.user import User, UserInDB
|
||||
from bracket.schema import users
|
||||
from bracket.schema import clubs, matches, players, rounds, teams, tournaments, users
|
||||
from bracket.utils.db import fetch_one_parsed
|
||||
from bracket.utils.dummy_records import DUMMY_CLUB, DUMMY_TOURNAMENT
|
||||
from bracket.utils.types import BaseModelT
|
||||
from tests.integration_tests.mocks import MOCK_USER, get_mock_token
|
||||
from tests.integration_tests.models import AuthContext
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_generic(
|
||||
data_model: BaseModelT, table: Table, return_type: Type[BaseModelT]
|
||||
) -> AsyncIterator[BaseModelT]:
|
||||
last_record_id = await database.execute(query=table.insert(), values=data_model.dict())
|
||||
row_inserted = await fetch_one_parsed(
|
||||
database, return_type, table.select().where(table.c.id == last_record_id)
|
||||
)
|
||||
assert isinstance(row_inserted, return_type)
|
||||
try:
|
||||
yield row_inserted
|
||||
finally:
|
||||
await database.execute(query=table.delete().where(table.c.id == last_record_id))
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_user(user: User) -> AsyncIterator[UserInDB]:
|
||||
last_record_id = await database.execute(query=users.insert(), values=user.dict())
|
||||
user_inserted = await fetch_one_parsed(
|
||||
database, UserInDB, users.select().where(users.c.id == last_record_id)
|
||||
)
|
||||
assert user_inserted is not None
|
||||
try:
|
||||
yield user_inserted
|
||||
finally:
|
||||
await database.execute(query=users.delete().where(users.c.id == last_record_id))
|
||||
async with inserted_generic(user, users, UserInDB) as row_inserted:
|
||||
yield cast(UserInDB, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_club(club: Club) -> AsyncIterator[Club]:
|
||||
async with inserted_generic(club, clubs, Club) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_tournament(tournament: Tournament) -> AsyncIterator[Tournament]:
|
||||
async with inserted_generic(tournament, tournaments, Tournament) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_team(team: Team) -> AsyncIterator[Team]:
|
||||
async with inserted_generic(team, teams, Team) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_player(player: Player) -> AsyncIterator[Player]:
|
||||
async with inserted_generic(player, players, Player) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_round(round_: Round) -> AsyncIterator[Round]:
|
||||
async with inserted_generic(round_, rounds, Round) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_match(match: Match) -> AsyncIterator[Match]:
|
||||
async with inserted_generic(match, matches, Match) as row_inserted:
|
||||
yield row_inserted
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_auth_context() -> AsyncIterator[AuthContext]:
|
||||
headers = {'Authorization': f'Bearer {get_mock_token()}'}
|
||||
async with inserted_user(MOCK_USER) as user_inserted:
|
||||
async with inserted_club(DUMMY_CLUB) as club_inserted:
|
||||
async with inserted_tournament(DUMMY_TOURNAMENT) as tournament_inserted:
|
||||
yield AuthContext(
|
||||
headers=headers,
|
||||
user=user_inserted,
|
||||
club=club_inserted,
|
||||
tournament=tournament_inserted,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user