mirror of
https://github.com/evroon/bracket.git
synced 2026-05-04 05:58:23 -04:00
Make primary key typing stricter (#904)
This commit is contained in:
@@ -7,7 +7,6 @@ from bracket.models.db.account import UserAccountType
|
||||
from bracket.sql.users import delete_user_and_owned_clubs, get_expired_demo_users
|
||||
from bracket.utils.asyncio import AsyncioTasksManager
|
||||
from bracket.utils.logging import logger
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
CronjobT = Callable[[], Awaitable[None]]
|
||||
|
||||
@@ -21,7 +20,7 @@ async def delete_demo_accounts() -> None:
|
||||
|
||||
for demo_user in demo_users:
|
||||
assert demo_user.account_type is UserAccountType.DEMO
|
||||
user_id = assert_some(demo_user.id)
|
||||
user_id = demo_user.id
|
||||
|
||||
await delete_user_and_owned_clubs(user_id)
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ async def schedule_all_unscheduled_matches(tournament_id: TournamentId) -> None:
|
||||
for match in round_.matches:
|
||||
if match.start_time is None and match.position_in_schedule is None:
|
||||
await sql_reschedule_match_and_determine_duration_and_margin(
|
||||
assert_some(match.id),
|
||||
match.id,
|
||||
court.id,
|
||||
start_time,
|
||||
position_in_schedule,
|
||||
@@ -63,7 +63,7 @@ async def schedule_all_unscheduled_matches(tournament_id: TournamentId) -> None:
|
||||
|
||||
if match.start_time is None and match.position_in_schedule is None:
|
||||
await sql_reschedule_match_and_determine_duration_and_margin(
|
||||
assert_some(match.id),
|
||||
match.id,
|
||||
courts[-1].id,
|
||||
start_time,
|
||||
position_in_schedule,
|
||||
@@ -92,7 +92,7 @@ async def reorder_matches_for_court(
|
||||
last_start_time = tournament.start_time
|
||||
for i, match_pos in enumerate(matches_this_court):
|
||||
await sql_reschedule_match_and_determine_duration_and_margin(
|
||||
assert_some(match_pos.match.id),
|
||||
match_pos.match.id,
|
||||
court_id,
|
||||
last_start_time,
|
||||
position_in_schedule=i,
|
||||
@@ -151,7 +151,7 @@ async def update_start_times_of_matches(tournament_id: TournamentId) -> None:
|
||||
scheduled_matches = get_scheduled_matches(stages)
|
||||
|
||||
for court in courts:
|
||||
await reorder_matches_for_court(tournament, scheduled_matches, assert_some(court.id))
|
||||
await reorder_matches_for_court(tournament, scheduled_matches, court.id)
|
||||
|
||||
|
||||
def get_scheduled_matches(stages: list[StageWithStageItems]) -> list[MatchPosition]:
|
||||
|
||||
@@ -22,13 +22,9 @@ def get_active_and_next_rounds(
|
||||
active_round = next((round_ for round_ in stage_item.rounds if round_.is_active), None)
|
||||
|
||||
def is_round_in_future(round_: RoundWithMatches) -> bool:
|
||||
return (
|
||||
(assert_some(round_.id) > assert_some(active_round.id))
|
||||
if active_round is not None
|
||||
else True
|
||||
)
|
||||
return (round_.id > active_round.id) if active_round is not None else True
|
||||
|
||||
rounds_chronologically_sorted = sorted(stage_item.rounds, key=lambda r: assert_some(r.id))
|
||||
rounds_chronologically_sorted = sorted(stage_item.rounds, key=lambda r: r.id)
|
||||
next_round = next(
|
||||
(round_ for round_ in rounds_chronologically_sorted if is_round_in_future(round_)),
|
||||
None,
|
||||
@@ -53,7 +49,7 @@ async def schedule_all_matches_for_swiss_round(
|
||||
assert len(active_round.matches) <= len(courts)
|
||||
|
||||
for i, match in enumerate(active_round.matches):
|
||||
court_id = assert_some(courts[i].id)
|
||||
court_id = courts[i].id
|
||||
last_match = (
|
||||
next((m for m in matches_per_court[court_id][::-1] if m.match.id != match.id), None)
|
||||
if court_id in matches_per_court
|
||||
@@ -83,7 +79,7 @@ async def schedule_all_matches_for_swiss_round(
|
||||
)
|
||||
rescheduling_operations.append(
|
||||
sql_reschedule_match_and_determine_duration_and_margin(
|
||||
assert_some(last_match.match.id),
|
||||
last_match.match.id,
|
||||
court_id,
|
||||
assert_some(last_match.match.start_time),
|
||||
assert_some(last_match.match.position_in_schedule),
|
||||
@@ -104,7 +100,7 @@ async def schedule_all_matches_for_swiss_round(
|
||||
|
||||
rescheduling_operations.append(
|
||||
sql_reschedule_match_and_determine_duration_and_margin(
|
||||
assert_some(match.id), court_id, start_time, pos_in_schedule, match, tournament
|
||||
match.id, court_id, start_time, pos_in_schedule, match, tournament
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from bracket.logic.scheduling.round_robin import (
|
||||
build_round_robin_stage_item,
|
||||
get_number_of_rounds_to_create_round_robin,
|
||||
)
|
||||
from bracket.models.db.round import RoundToInsert
|
||||
from bracket.models.db.round import RoundInsertable
|
||||
from bracket.models.db.stage_item import StageItem, StageType
|
||||
from bracket.models.db.stage_item_inputs import (
|
||||
StageItemInputOptionFinal,
|
||||
@@ -19,7 +19,7 @@ from bracket.models.db.util import StageWithStageItems
|
||||
from bracket.sql.rounds import get_next_round_name, sql_create_round
|
||||
from bracket.sql.stage_items import get_stage_item
|
||||
from bracket.utils.id_types import StageId, TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.mocks import MOCK_NOW
|
||||
|
||||
|
||||
async def create_rounds_for_new_stage_item(
|
||||
@@ -38,16 +38,18 @@ async def create_rounds_for_new_stage_item(
|
||||
|
||||
for _ in range(rounds_count):
|
||||
await sql_create_round(
|
||||
RoundToInsert(
|
||||
stage_item_id=assert_some(stage_item.id),
|
||||
name=await get_next_round_name(tournament_id, assert_some(stage_item.id)),
|
||||
RoundInsertable(
|
||||
created=MOCK_NOW,
|
||||
is_draft=False,
|
||||
stage_item_id=stage_item.id,
|
||||
name=await get_next_round_name(tournament_id, stage_item.id),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def build_matches_for_stage_item(stage_item: StageItem, tournament_id: TournamentId) -> None:
|
||||
await create_rounds_for_new_stage_item(tournament_id, stage_item)
|
||||
stage_item_with_rounds = await get_stage_item(tournament_id, assert_some(stage_item.id))
|
||||
stage_item_with_rounds = await get_stage_item(tournament_id, stage_item.id)
|
||||
|
||||
if stage_item_with_rounds is None:
|
||||
raise ValueError(
|
||||
@@ -73,7 +75,7 @@ def determine_available_inputs(
|
||||
teams: list[FullTeamWithPlayers],
|
||||
stages: list[StageWithStageItems],
|
||||
) -> list[StageItemInputOptionTentative | StageItemInputOptionFinal]:
|
||||
results_team_ids = [assert_some(team.id) for team in teams]
|
||||
results_team_ids = [team.id for team in teams]
|
||||
results_tentative = []
|
||||
|
||||
for stage in stages:
|
||||
|
||||
@@ -5,7 +5,6 @@ from bracket.sql.matches import sql_create_match
|
||||
from bracket.sql.rounds import get_rounds_for_stage_item
|
||||
from bracket.sql.tournaments import sql_get_tournament
|
||||
from bracket.utils.id_types import TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
def determine_matches_first_round(
|
||||
@@ -18,7 +17,7 @@ def determine_matches_first_round(
|
||||
second_input = stage_item.inputs[i + 1]
|
||||
suggestions.append(
|
||||
MatchCreateBody(
|
||||
round_id=assert_some(round_.id),
|
||||
round_id=round_.id,
|
||||
court_id=None,
|
||||
team1_id=first_input.team_id,
|
||||
team1_winner_from_stage_item_id=first_input.winner_from_stage_item_id,
|
||||
@@ -51,7 +50,7 @@ def determine_matches_subsequent_round(
|
||||
|
||||
suggestions.append(
|
||||
MatchCreateBody(
|
||||
round_id=assert_some(round_.id),
|
||||
round_id=round_.id,
|
||||
court_id=None,
|
||||
team1_id=None,
|
||||
team1_winner_from_stage_item_id=None,
|
||||
@@ -59,8 +58,8 @@ def determine_matches_subsequent_round(
|
||||
team2_id=None,
|
||||
team2_winner_from_stage_item_id=None,
|
||||
team2_winner_position=None,
|
||||
team1_winner_from_match_id=assert_some(first_match.id),
|
||||
team2_winner_from_match_id=assert_some(second_match.id),
|
||||
team1_winner_from_match_id=first_match.id,
|
||||
team2_winner_from_match_id=second_match.id,
|
||||
duration_minutes=tournament.duration_minutes,
|
||||
margin_minutes=tournament.margin_minutes,
|
||||
custom_duration_minutes=None,
|
||||
|
||||
@@ -62,7 +62,7 @@ async def set_team_ids_for_match(
|
||||
stage_item_x_team_rankings,
|
||||
)
|
||||
|
||||
await sql_update_team_ids_for_match(assert_some(match.id), team1_id, team2_id)
|
||||
await sql_update_team_ids_for_match(match.id, team1_id, team2_id)
|
||||
|
||||
|
||||
async def get_team_rankings_lookup_for_stage(
|
||||
|
||||
@@ -47,7 +47,7 @@ def get_number_of_teams_played_per_team(
|
||||
if isinstance(match, MatchWithDetailsDefinitive):
|
||||
for team in match.teams:
|
||||
if team.active and team.id not in excluded_team_ids:
|
||||
result[assert_some(team.id)] += 1
|
||||
result[team.id] += 1
|
||||
|
||||
return result
|
||||
|
||||
@@ -80,7 +80,7 @@ def get_possible_upcoming_matches_for_swiss(
|
||||
)
|
||||
for team in teams_to_schedule:
|
||||
if team.id not in times_played_per_team:
|
||||
times_played_per_team[assert_some(team.id)] = 0
|
||||
times_played_per_team[team.id] = 0
|
||||
|
||||
min_times_played = min(times_played_per_team.values()) if len(times_played_per_team) > 0 else 0
|
||||
|
||||
@@ -100,8 +100,8 @@ def get_possible_upcoming_matches_for_swiss(
|
||||
continue
|
||||
|
||||
times_played_min = min(
|
||||
times_played_per_team[assert_some(team1.id)],
|
||||
times_played_per_team[assert_some(team2.id)],
|
||||
times_played_per_team[team1.id],
|
||||
times_played_per_team[team2.id],
|
||||
)
|
||||
suggested_match = check_team_combination_adheres_to_filter(
|
||||
team1, team2, filter_, is_recommended=times_played_min <= min_times_played
|
||||
|
||||
@@ -5,7 +5,6 @@ from bracket.models.db.util import StageItemWithRounds
|
||||
from bracket.sql.matches import sql_create_match
|
||||
from bracket.sql.tournaments import sql_get_tournament
|
||||
from bracket.utils.id_types import TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
def get_round_robin_combinations(team_count: int) -> list[list[tuple[int, int]]]:
|
||||
@@ -48,7 +47,7 @@ async def build_round_robin_stage_item(
|
||||
team_1, team_2 = stage_item.inputs[team_1_id], stage_item.inputs[team_2_id]
|
||||
|
||||
match = MatchCreateBody(
|
||||
round_id=assert_some(round_.id),
|
||||
round_id=round_.id,
|
||||
team1_id=team_1.team_id,
|
||||
team1_winner_from_stage_item_id=team_1.winner_from_stage_item_id,
|
||||
team1_winner_position=team_1.winner_position,
|
||||
|
||||
@@ -9,7 +9,6 @@ from bracket.sql.rounds import get_rounds_for_stage_item
|
||||
from bracket.sql.stages import get_full_tournament_details
|
||||
from bracket.sql.teams import get_teams_with_members
|
||||
from bracket.utils.id_types import StageItemId, TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
async def get_draft_round_in_stage_item(
|
||||
@@ -40,7 +39,7 @@ async def get_upcoming_matches_for_swiss_round(
|
||||
if not round_.is_draft:
|
||||
raise HTTPException(400, "There is no draft round, so no matches can be scheduled.")
|
||||
|
||||
rounds = await get_rounds_for_stage_item(tournament_id, assert_some(stage_item.id))
|
||||
rounds = await get_rounds_for_stage_item(tournament_id, stage_item.id)
|
||||
teams = await get_teams_with_members(tournament_id, only_active_teams=True)
|
||||
|
||||
return get_possible_upcoming_matches_for_swiss(match_filter, rounds, teams)
|
||||
|
||||
@@ -14,7 +14,6 @@ from bracket.sql.clubs import create_club
|
||||
from bracket.sql.rankings import sql_create_ranking
|
||||
from bracket.sql.tournaments import sql_create_tournament
|
||||
from bracket.utils.id_types import UserId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bracket.models.db.user import UserBase
|
||||
@@ -80,7 +79,7 @@ async def setup_demo_account(user_id: UserId) -> None:
|
||||
|
||||
tournament = TournamentBody(
|
||||
name="Demo Tournament",
|
||||
club_id=assert_some(club_inserted.id),
|
||||
club_id=club_inserted.id,
|
||||
start_time=datetime_utc.future(hours=1),
|
||||
dashboard_public=False,
|
||||
players_can_be_in_multiple_teams=False,
|
||||
|
||||
@@ -9,7 +9,6 @@ from bracket.sql.stages import get_full_tournament_details, sql_delete_stage
|
||||
from bracket.sql.teams import sql_delete_teams_of_tournament
|
||||
from bracket.sql.tournaments import sql_delete_tournament, sql_get_tournament
|
||||
from bracket.utils.id_types import TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
async def get_tournament_logo_path(tournament_id: TournamentId) -> str | None:
|
||||
@@ -36,7 +35,7 @@ async def sql_delete_tournament_completely(tournament_id: TournamentId) -> None:
|
||||
for stage_item in stage.stage_items:
|
||||
await sql_delete_stage_item(stage_item.id)
|
||||
|
||||
await sql_delete_stage(tournament_id, assert_some(stage.id))
|
||||
await sql_delete_stage(tournament_id, stage.id)
|
||||
|
||||
for ranking in await get_all_rankings_in_tournament(tournament_id):
|
||||
await sql_delete_ranking(tournament_id, ranking.id)
|
||||
|
||||
@@ -4,12 +4,15 @@ from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import ClubId
|
||||
|
||||
|
||||
class Club(BaseModelORM):
|
||||
id: ClubId | None = None
|
||||
class ClubInsertable(BaseModelORM):
|
||||
name: str
|
||||
created: datetime_utc
|
||||
|
||||
|
||||
class Club(ClubInsertable):
|
||||
id: ClubId
|
||||
|
||||
|
||||
class ClubCreateBody(BaseModelORM):
|
||||
name: str
|
||||
|
||||
|
||||
@@ -4,13 +4,16 @@ from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import CourtId, TournamentId
|
||||
|
||||
|
||||
class Court(BaseModelORM):
|
||||
id: CourtId | None = None
|
||||
class CourtInsertable(BaseModelORM):
|
||||
name: str
|
||||
created: datetime_utc
|
||||
tournament_id: TournamentId
|
||||
|
||||
|
||||
class Court(CourtInsertable):
|
||||
id: CourtId
|
||||
|
||||
|
||||
class CourtBody(BaseModelORM):
|
||||
name: str
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ from bracket.utils.id_types import CourtId, MatchId, PlayerId, RoundId, StageIte
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
class MatchBase(BaseModelORM):
|
||||
id: MatchId | None = None
|
||||
class MatchBaseInsertable(BaseModelORM):
|
||||
created: datetime_utc
|
||||
start_time: datetime_utc | None = None
|
||||
duration_minutes: int
|
||||
@@ -32,7 +31,7 @@ class MatchBase(BaseModelORM):
|
||||
)
|
||||
|
||||
|
||||
class Match(MatchBase):
|
||||
class MatchInsertable(MatchBaseInsertable):
|
||||
team1_id: TeamId | None = None
|
||||
team2_id: TeamId | None = None
|
||||
team1_winner_position: int | None = None
|
||||
@@ -49,6 +48,10 @@ class Match(MatchBase):
|
||||
return 1 if self.team1_score > self.team2_score else 0
|
||||
|
||||
|
||||
class Match(MatchInsertable):
|
||||
id: MatchId
|
||||
|
||||
|
||||
class MatchWithDetails(Match):
|
||||
court: Court | None = None
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import PlayerId, TournamentId
|
||||
|
||||
|
||||
class Player(BaseModelORM):
|
||||
id: PlayerId | None = None
|
||||
class PlayerInsertable(BaseModelORM):
|
||||
active: bool
|
||||
name: str
|
||||
created: datetime_utc
|
||||
@@ -19,6 +18,10 @@ class Player(BaseModelORM):
|
||||
draws: int = 0
|
||||
losses: int = 0
|
||||
|
||||
|
||||
class Player(PlayerInsertable):
|
||||
id: PlayerId
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return self.id if self.id is not None else int(self.created.timestamp())
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import PlayerId, PlayerXTeamId, TeamId
|
||||
from bracket.utils.id_types import PlayerId, TeamId
|
||||
|
||||
|
||||
class PlayerXTeam(BaseModelORM):
|
||||
id: PlayerXTeamId | None = None
|
||||
class PlayerXTeamInsertable(BaseModelORM):
|
||||
player_id: PlayerId
|
||||
team_id: TeamId
|
||||
|
||||
@@ -4,15 +4,18 @@ from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import RoundId, StageItemId
|
||||
|
||||
|
||||
class Round(BaseModelORM):
|
||||
id: RoundId | None = None
|
||||
stage_item_id: StageItemId
|
||||
class RoundInsertable(BaseModelORM):
|
||||
created: datetime_utc
|
||||
stage_item_id: StageItemId
|
||||
is_draft: bool
|
||||
is_active: bool = False
|
||||
name: str
|
||||
|
||||
|
||||
class Round(RoundInsertable):
|
||||
id: RoundId
|
||||
|
||||
|
||||
class RoundUpdateBody(BaseModelORM):
|
||||
name: str
|
||||
is_draft: bool
|
||||
@@ -22,9 +25,3 @@ class RoundUpdateBody(BaseModelORM):
|
||||
class RoundCreateBody(BaseModelORM):
|
||||
name: str | None = None
|
||||
stage_item_id: StageItemId
|
||||
|
||||
|
||||
class RoundToInsert(RoundUpdateBody):
|
||||
stage_item_id: StageItemId
|
||||
is_draft: bool = False
|
||||
is_active: bool = False
|
||||
|
||||
@@ -6,14 +6,17 @@ from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import StageId, TournamentId
|
||||
|
||||
|
||||
class Stage(BaseModelORM):
|
||||
id: StageId | None = None
|
||||
class StageInsertable(BaseModelORM):
|
||||
tournament_id: TournamentId
|
||||
name: str
|
||||
created: datetime_utc
|
||||
is_active: bool
|
||||
|
||||
|
||||
class Stage(StageInsertable):
|
||||
id: StageId
|
||||
|
||||
|
||||
class StageUpdateBody(BaseModelORM):
|
||||
name: str
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@ class StageType(EnumAutoStr):
|
||||
return self in [StageType.SWISS]
|
||||
|
||||
|
||||
class StageItemToInsert(BaseModelORM):
|
||||
id: StageItemId | None = None
|
||||
class StageItemInsertable(BaseModelORM):
|
||||
stage_id: StageId
|
||||
name: str
|
||||
created: datetime_utc
|
||||
@@ -30,7 +29,7 @@ class StageItemToInsert(BaseModelORM):
|
||||
ranking_id: RankingId | None = None
|
||||
|
||||
|
||||
class StageItem(StageItemToInsert):
|
||||
class StageItem(StageItemInsertable):
|
||||
id: StageItemId
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from bracket.utils.id_types import MatchId, StageItemId, StageItemInputId, TeamI
|
||||
|
||||
|
||||
class StageItemInputBase(BaseModelORM):
|
||||
id: StageItemInputId | None = None
|
||||
id: StageItemInputId
|
||||
slot: int
|
||||
tournament_id: TournamentId
|
||||
stage_item_id: StageItemId | None = None
|
||||
|
||||
@@ -12,11 +12,9 @@ from bracket.logic.ranking.statistics import START_ELO
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.shared import BaseModelORM
|
||||
from bracket.utils.id_types import PlayerId, TeamId, TournamentId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
|
||||
class Team(BaseModelORM):
|
||||
id: TeamId | None = None
|
||||
class TeamInsertable(BaseModelORM):
|
||||
created: datetime_utc
|
||||
name: str
|
||||
tournament_id: TournamentId
|
||||
@@ -29,8 +27,12 @@ class Team(BaseModelORM):
|
||||
logo_path: str | None = None
|
||||
|
||||
|
||||
class Team(TeamInsertable):
|
||||
id: TeamId
|
||||
|
||||
|
||||
class TeamWithPlayers(BaseModel):
|
||||
id: TeamId | None = None
|
||||
id: TeamId
|
||||
players: list[Player]
|
||||
elo_score: Decimal = START_ELO
|
||||
swiss_score: Decimal = Decimal("0.0")
|
||||
@@ -42,7 +44,7 @@ class TeamWithPlayers(BaseModel):
|
||||
|
||||
@property
|
||||
def player_ids(self) -> list[PlayerId]:
|
||||
return [assert_some(player.id) for player in self.players]
|
||||
return [player.id for player in self.players]
|
||||
|
||||
@field_validator("players", mode="before")
|
||||
def handle_players(values: list[Player]) -> list[Player]: # type: ignore[misc]
|
||||
@@ -88,15 +90,3 @@ class TeamBody(BaseModelORM):
|
||||
class TeamMultiBody(BaseModelORM):
|
||||
names: str = Field(..., min_length=1)
|
||||
active: bool
|
||||
|
||||
|
||||
class TeamToInsert(BaseModelORM):
|
||||
created: datetime_utc
|
||||
name: str
|
||||
tournament_id: TournamentId
|
||||
active: bool
|
||||
elo_score: Decimal = Decimal("0.0")
|
||||
swiss_score: Decimal = Decimal("0.0")
|
||||
wins: int = 0
|
||||
draws: int = 0
|
||||
losses: int = 0
|
||||
|
||||
@@ -6,8 +6,7 @@ from bracket.utils.id_types import ClubId, TournamentId
|
||||
from bracket.utils.pydantic import EmptyStrToNone
|
||||
|
||||
|
||||
class Tournament(BaseModelORM):
|
||||
id: TournamentId | None = None
|
||||
class TournamentInsertable(BaseModelORM):
|
||||
club_id: ClubId
|
||||
name: str
|
||||
created: datetime_utc
|
||||
@@ -21,6 +20,10 @@ class Tournament(BaseModelORM):
|
||||
auto_assign_courts: bool
|
||||
|
||||
|
||||
class Tournament(TournamentInsertable):
|
||||
id: TournamentId
|
||||
|
||||
|
||||
class TournamentUpdateBody(BaseModelORM):
|
||||
start_time: datetime_utc
|
||||
name: str
|
||||
|
||||
@@ -14,7 +14,6 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class UserBase(BaseModelORM):
|
||||
id: UserId | None = None
|
||||
email: str
|
||||
name: str
|
||||
created: datetime_utc
|
||||
@@ -27,12 +26,16 @@ class UserBase(BaseModelORM):
|
||||
return subscription_lookup[self.account_type]
|
||||
|
||||
|
||||
class User(UserBase):
|
||||
class UserInsertable(UserBase):
|
||||
password_hash: str | None = None
|
||||
|
||||
|
||||
class User(UserInsertable):
|
||||
id: UserId
|
||||
|
||||
|
||||
class UserPublic(UserBase):
|
||||
pass
|
||||
id: UserId
|
||||
|
||||
|
||||
class UserToUpdate(BaseModel):
|
||||
|
||||
@@ -10,8 +10,11 @@ class UserXClubRelation(EnumAutoStr):
|
||||
COLLABORATOR = auto()
|
||||
|
||||
|
||||
class UserXClub(BaseModelORM):
|
||||
id: UserXClubId | None = None
|
||||
class UserXClubInsertable(BaseModelORM):
|
||||
user_id: UserId
|
||||
club_id: ClubId
|
||||
relation: UserXClubRelation
|
||||
|
||||
|
||||
class UserXClub(UserXClubInsertable):
|
||||
id: UserXClubId
|
||||
|
||||
@@ -103,7 +103,7 @@ async def user_authenticated_for_tournament(
|
||||
) -> UserPublic:
|
||||
user = await check_jwt_and_get_user(token)
|
||||
|
||||
if not user or not await get_user_access_to_tournament(tournament_id, assert_some(user.id)):
|
||||
if not user or not await get_user_access_to_tournament(tournament_id, user.id):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
@@ -118,7 +118,7 @@ async def user_authenticated_for_club(
|
||||
) -> UserPublic:
|
||||
user = await check_jwt_and_get_user(token)
|
||||
|
||||
if not user or not await get_user_access_to_club(club_id, assert_some(user.id)):
|
||||
if not user or not await get_user_access_to_club(club_id, user.id):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
@@ -134,9 +134,7 @@ async def user_authenticated_or_public_dashboard(
|
||||
try:
|
||||
token: str = assert_some(await oauth2_scheme(request))
|
||||
user = await check_jwt_and_get_user(token)
|
||||
if user is not None and await get_user_access_to_tournament(
|
||||
tournament_id, assert_some(user.id)
|
||||
):
|
||||
if user is not None and await get_user_access_to_tournament(tournament_id, user.id):
|
||||
return user
|
||||
except HTTPException:
|
||||
pass
|
||||
|
||||
@@ -8,23 +8,22 @@ from bracket.routes.models import ClubResponse, ClubsResponse, SuccessResponse
|
||||
from bracket.sql.clubs import create_club, get_clubs_for_user_id, sql_delete_club, sql_update_club
|
||||
from bracket.utils.errors import ForeignKey, check_foreign_key_violation
|
||||
from bracket.utils.id_types import ClubId
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/clubs", response_model=ClubsResponse)
|
||||
async def get_clubs(user: UserPublic = Depends(user_authenticated)) -> ClubsResponse:
|
||||
return ClubsResponse(data=await get_clubs_for_user_id(assert_some(user.id)))
|
||||
return ClubsResponse(data=await get_clubs_for_user_id(user.id))
|
||||
|
||||
|
||||
@router.post("/clubs", response_model=ClubResponse)
|
||||
async def create_new_club(
|
||||
club: ClubCreateBody, user: UserPublic = Depends(user_authenticated)
|
||||
) -> ClubResponse:
|
||||
existing_clubs = await get_clubs_for_user_id(assert_some(user.id))
|
||||
existing_clubs = await get_clubs_for_user_id(user.id)
|
||||
check_requirement(existing_clubs, user, "max_clubs")
|
||||
return ClubResponse(data=await create_club(club, assert_some(user.id)))
|
||||
return ClubResponse(data=await create_club(club, user.id))
|
||||
|
||||
|
||||
@router.delete("/clubs/{club_id}", response_model=SuccessResponse)
|
||||
|
||||
@@ -75,7 +75,7 @@ async def delete_match(
|
||||
) -> SuccessResponse:
|
||||
round_ = await get_round_by_id(tournament_id, match.round_id)
|
||||
|
||||
await sql_delete_match(assert_some(match.id))
|
||||
await sql_delete_match(match.id)
|
||||
|
||||
await recalculate_ranking_for_stage_item_id(tournament_id, assert_some(round_).stage_item_id)
|
||||
return SuccessResponse()
|
||||
|
||||
@@ -9,7 +9,7 @@ from bracket.logic.subscriptions import check_requirement
|
||||
from bracket.models.db.round import (
|
||||
Round,
|
||||
RoundCreateBody,
|
||||
RoundToInsert,
|
||||
RoundInsertable,
|
||||
RoundUpdateBody,
|
||||
)
|
||||
from bracket.models.db.user import UserPublic
|
||||
@@ -26,6 +26,7 @@ from bracket.sql.stage_items import get_stage_item
|
||||
from bracket.sql.stages import get_full_tournament_details
|
||||
from bracket.sql.validation import check_foreign_keys_belong_to_tournament
|
||||
from bracket.utils.id_types import RoundId, TournamentId
|
||||
from tests.integration_tests.mocks import MOCK_NOW
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -84,7 +85,9 @@ async def create_round(
|
||||
)
|
||||
|
||||
round_id = await sql_create_round(
|
||||
RoundToInsert(
|
||||
RoundInsertable(
|
||||
created=MOCK_NOW,
|
||||
is_draft=False,
|
||||
stage_item_id=round_body.stage_item_id,
|
||||
name=await get_next_round_name(tournament_id, round_body.stage_item_id),
|
||||
),
|
||||
|
||||
@@ -9,7 +9,13 @@ from heliclockter import datetime_utc
|
||||
from bracket.database import database
|
||||
from bracket.logic.subscriptions import check_requirement
|
||||
from bracket.logic.teams import get_team_logo_path
|
||||
from bracket.models.db.team import FullTeamWithPlayers, Team, TeamBody, TeamMultiBody, TeamToInsert
|
||||
from bracket.models.db.team import (
|
||||
FullTeamWithPlayers,
|
||||
Team,
|
||||
TeamBody,
|
||||
TeamInsertable,
|
||||
TeamMultiBody,
|
||||
)
|
||||
from bracket.models.db.user import UserPublic
|
||||
from bracket.routes.auth import (
|
||||
user_authenticated_for_tournament,
|
||||
@@ -91,7 +97,7 @@ async def update_team_by_id(
|
||||
),
|
||||
values=team_body.model_dump(exclude={"player_ids"}),
|
||||
)
|
||||
await update_team_members(assert_some(team.id), tournament_id, team_body.player_ids)
|
||||
await update_team_members(team.id, tournament_id, team_body.player_ids)
|
||||
|
||||
return SingleTeamResponse(
|
||||
data=assert_some(
|
||||
@@ -113,7 +119,7 @@ async def update_team_logo(
|
||||
_: UserPublic = Depends(user_authenticated_for_tournament),
|
||||
team: Team = Depends(team_dependency),
|
||||
) -> SingleTeamResponse:
|
||||
team_id = assert_some(team.id)
|
||||
team_id = team.id
|
||||
old_logo_path = await get_team_logo_path(tournament_id, team_id)
|
||||
filename: str | None = None
|
||||
new_logo_path: str | None = None
|
||||
@@ -157,7 +163,7 @@ async def delete_team(
|
||||
ForeignKey.matches_team2_id_fkey,
|
||||
}
|
||||
):
|
||||
await sql_delete_team(tournament_id, assert_some(team.id))
|
||||
await sql_delete_team(tournament_id, team.id)
|
||||
|
||||
return SuccessResponse()
|
||||
|
||||
@@ -175,7 +181,7 @@ async def create_team(
|
||||
|
||||
last_record_id = await database.execute(
|
||||
query=teams.insert(),
|
||||
values=TeamToInsert(
|
||||
values=TeamInsertable(
|
||||
**team_to_insert.model_dump(exclude={"player_ids"}),
|
||||
created=datetime_utc.now(),
|
||||
tournament_id=tournament_id,
|
||||
@@ -201,7 +207,7 @@ async def create_multiple_teams(
|
||||
for team_name in team_names:
|
||||
await database.execute(
|
||||
query=teams.insert(),
|
||||
values=TeamToInsert(
|
||||
values=TeamInsertable(
|
||||
name=team_name,
|
||||
active=team_body.active,
|
||||
created=datetime_utc.now(),
|
||||
|
||||
@@ -42,7 +42,6 @@ from bracket.utils.errors import (
|
||||
)
|
||||
from bracket.utils.id_types import TournamentId
|
||||
from bracket.utils.logging import logger
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
router = APIRouter()
|
||||
unauthorized_exception = HTTPException(
|
||||
@@ -84,7 +83,7 @@ async def get_tournaments(
|
||||
return TournamentsResponse(data=[tournament])
|
||||
|
||||
case _, _ if isinstance(user, UserPublic):
|
||||
user_club_ids = await get_which_clubs_has_user_access_to(assert_some(user.id))
|
||||
user_club_ids = await get_which_clubs_has_user_access_to(user.id)
|
||||
return TournamentsResponse(
|
||||
data=await sql_get_tournaments(tuple(user_club_ids), endpoint_name)
|
||||
)
|
||||
@@ -131,9 +130,7 @@ async def create_tournament(
|
||||
existing_tournaments = await sql_get_tournaments((tournament_to_insert.club_id,))
|
||||
check_requirement(existing_tournaments, user, "max_tournaments")
|
||||
|
||||
has_access_to_club = await get_user_access_to_club(
|
||||
tournament_to_insert.club_id, assert_some(user.id)
|
||||
)
|
||||
has_access_to_club = await get_user_access_to_club(tournament_to_insert.club_id, user.id)
|
||||
if not has_access_to_club:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
|
||||
@@ -9,7 +9,7 @@ from bracket.logic.subscriptions import setup_demo_account
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.user import (
|
||||
DemoUserToRegister,
|
||||
User,
|
||||
UserInsertable,
|
||||
UserPasswordToUpdate,
|
||||
UserPublic,
|
||||
UserToRegister,
|
||||
@@ -60,7 +60,7 @@ async def update_user_details(
|
||||
if user_public.id != user_id:
|
||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Can't change details of this user")
|
||||
|
||||
await update_user(assert_some(user_public.id), user_to_update)
|
||||
await update_user(user_public.id, user_to_update)
|
||||
user_updated = await get_user_by_id(user_id)
|
||||
return UserPublicResponse(data=assert_some(user_updated))
|
||||
|
||||
@@ -72,7 +72,7 @@ async def put_user_password(
|
||||
user_public: UserPublic = Depends(user_authenticated),
|
||||
) -> SuccessResponse:
|
||||
assert user_public.id == user_id
|
||||
await update_user_password(assert_some(user_public.id), hash_password(user_to_update.password))
|
||||
await update_user_password(user_public.id, hash_password(user_to_update.password))
|
||||
return SuccessResponse()
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ async def register_user(user_to_register: UserToRegister) -> TokenResponse:
|
||||
if not await verify_captcha_token(user_to_register.captcha_token):
|
||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Failed to validate captcha")
|
||||
|
||||
user = User(
|
||||
user = UserInsertable(
|
||||
email=user_to_register.email,
|
||||
password_hash=hash_password(user_to_register.password),
|
||||
name=user_to_register.name,
|
||||
@@ -100,9 +100,7 @@ async def register_user(user_to_register: UserToRegister) -> TokenResponse:
|
||||
data={"user": user_created.email}, expires_delta=access_token_expires
|
||||
)
|
||||
return TokenResponse(
|
||||
data=Token(
|
||||
access_token=access_token, token_type="bearer", user_id=assert_some(user_created.id)
|
||||
)
|
||||
data=Token(access_token=access_token, token_type="bearer", user_id=user_created.id)
|
||||
)
|
||||
|
||||
|
||||
@@ -117,7 +115,7 @@ async def register_demo_user(user_to_register: DemoUserToRegister) -> TokenRespo
|
||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Failed to validate captcha")
|
||||
|
||||
username = f"demo-{uuid4()}"
|
||||
user = User(
|
||||
user = UserInsertable(
|
||||
email=f"{username}@example.org",
|
||||
password_hash=hash_password(str(uuid4())),
|
||||
name=username,
|
||||
@@ -132,9 +130,7 @@ async def register_demo_user(user_to_register: DemoUserToRegister) -> TokenRespo
|
||||
access_token = create_access_token(
|
||||
data={"user": user_created.email}, expires_delta=access_token_expires
|
||||
)
|
||||
await setup_demo_account(assert_some(user_created.id))
|
||||
await setup_demo_account(user_created.id)
|
||||
return TokenResponse(
|
||||
data=Token(
|
||||
access_token=access_token, token_type="bearer", user_id=assert_some(user_created.id)
|
||||
)
|
||||
data=Token(access_token=access_token, token_type="bearer", user_id=user_created.id)
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ async def create_club(club: ClubCreateBody, user_id: UserId) -> Club:
|
||||
|
||||
club_created = Club.model_validate(dict(result._mapping))
|
||||
|
||||
await sql_give_user_access_to_club(user_id, assert_some(club_created.id))
|
||||
await sql_give_user_access_to_club(user_id, club_created.id)
|
||||
|
||||
return club_created
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from bracket.database import database
|
||||
from bracket.models.db.round import RoundToInsert
|
||||
from bracket.models.db.round import RoundInsertable
|
||||
from bracket.models.db.util import RoundWithMatches
|
||||
from bracket.sql.stage_items import get_stage_item
|
||||
from bracket.sql.stages import get_full_tournament_details
|
||||
from bracket.utils.id_types import RoundId, StageItemId, TournamentId
|
||||
|
||||
|
||||
async def sql_create_round(round_: RoundToInsert) -> RoundId:
|
||||
async def sql_create_round(round_: RoundInsertable) -> RoundId:
|
||||
query = """
|
||||
INSERT INTO rounds (created, is_draft, is_active, name, stage_item_id)
|
||||
VALUES (NOW(), :is_draft, :is_active, :name, :stage_item_id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from bracket.database import database
|
||||
from bracket.logic.tournaments import sql_delete_tournament_completely
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.user import User, UserInDB, UserPublic, UserToUpdate
|
||||
from bracket.models.db.user import User, UserInDB, UserInsertable, UserPublic, UserToUpdate
|
||||
from bracket.schema import users
|
||||
from bracket.sql.clubs import get_clubs_for_user_id, sql_delete_club
|
||||
from bracket.sql.tournaments import sql_get_tournaments
|
||||
@@ -87,7 +87,7 @@ async def get_expired_demo_users() -> list[UserPublic]:
|
||||
return [UserPublic.model_validate(demo_user) for demo_user in result]
|
||||
|
||||
|
||||
async def create_user(user: User) -> User:
|
||||
async def create_user(user: UserInsertable) -> User:
|
||||
query = """
|
||||
INSERT INTO users (email, name, password_hash, created, account_type)
|
||||
VALUES (:email, :name, :password_hash, :created, :account_type)
|
||||
@@ -130,10 +130,10 @@ async def get_user(email: str) -> UserInDB | None:
|
||||
|
||||
async def delete_user_and_owned_clubs(user_id: UserId) -> None:
|
||||
for club in await get_clubs_for_user_id(user_id):
|
||||
club_id = assert_some(club.id)
|
||||
club_id = club.id
|
||||
|
||||
for tournament in await sql_get_tournaments((club_id,), None):
|
||||
tournament_id = assert_some(tournament.id)
|
||||
tournament_id = tournament.id
|
||||
await sql_delete_tournament_completely(tournament_id)
|
||||
|
||||
await sql_delete_club(club_id)
|
||||
|
||||
@@ -10,23 +10,23 @@ from bracket.logic.ranking.elo import (
|
||||
)
|
||||
from bracket.logic.scheduling.builder import build_matches_for_stage_item
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.club import Club
|
||||
from bracket.models.db.court import Court
|
||||
from bracket.models.db.club import ClubInsertable
|
||||
from bracket.models.db.court import CourtInsertable
|
||||
from bracket.models.db.match import Match, MatchBody
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.player_x_team import PlayerXTeam
|
||||
from bracket.models.db.player import PlayerInsertable
|
||||
from bracket.models.db.player_x_team import PlayerXTeamInsertable
|
||||
from bracket.models.db.ranking import RankingInsertable
|
||||
from bracket.models.db.round import Round
|
||||
from bracket.models.db.stage import Stage
|
||||
from bracket.models.db.stage_item import StageItem, StageItemCreateBody
|
||||
from bracket.models.db.round import RoundInsertable
|
||||
from bracket.models.db.stage import StageInsertable
|
||||
from bracket.models.db.stage_item import StageItemCreateBody, StageItemInsertable
|
||||
from bracket.models.db.stage_item_inputs import (
|
||||
StageItemInputCreateBodyFinal,
|
||||
StageItemInputCreateBodyTentative,
|
||||
)
|
||||
from bracket.models.db.team import Team
|
||||
from bracket.models.db.tournament import Tournament
|
||||
from bracket.models.db.user import User
|
||||
from bracket.models.db.user_x_club import UserXClub, UserXClubRelation
|
||||
from bracket.models.db.team import TeamInsertable
|
||||
from bracket.models.db.tournament import TournamentInsertable
|
||||
from bracket.models.db.user import UserInsertable
|
||||
from bracket.models.db.user_x_club import UserXClubInsertable, UserXClubRelation
|
||||
from bracket.schema import (
|
||||
clubs,
|
||||
courts,
|
||||
@@ -102,7 +102,7 @@ async def create_admin_user() -> UserId:
|
||||
assert config.admin_password
|
||||
|
||||
user = await create_user(
|
||||
User(
|
||||
UserInsertable(
|
||||
name="Admin",
|
||||
email=config.admin_email,
|
||||
password_hash=hash_password(config.admin_password),
|
||||
@@ -110,7 +110,7 @@ async def create_admin_user() -> UserId:
|
||||
account_type=UserAccountType.REGULAR,
|
||||
)
|
||||
)
|
||||
return assert_some(user.id)
|
||||
return user.id
|
||||
|
||||
|
||||
async def init_db_when_empty() -> UserId | None:
|
||||
@@ -144,18 +144,18 @@ async def sql_create_dev_db() -> UserId:
|
||||
alembic_stamp_head()
|
||||
|
||||
table_lookup: dict[type, Table] = {
|
||||
User: users,
|
||||
Club: clubs,
|
||||
Stage: stages,
|
||||
Team: teams,
|
||||
UserXClub: users_x_clubs,
|
||||
PlayerXTeam: players_x_teams,
|
||||
Player: players,
|
||||
Round: rounds,
|
||||
UserInsertable: users,
|
||||
ClubInsertable: clubs,
|
||||
StageInsertable: stages,
|
||||
TeamInsertable: teams,
|
||||
UserXClubInsertable: users_x_clubs,
|
||||
PlayerXTeamInsertable: players_x_teams,
|
||||
PlayerInsertable: players,
|
||||
RoundInsertable: rounds,
|
||||
Match: matches,
|
||||
Tournament: tournaments,
|
||||
Court: courts,
|
||||
StageItem: stage_items,
|
||||
TournamentInsertable: tournaments,
|
||||
CourtInsertable: courts,
|
||||
StageItemInsertable: stage_items,
|
||||
RankingInsertable: rankings,
|
||||
}
|
||||
|
||||
@@ -174,12 +174,15 @@ async def sql_create_dev_db() -> UserId:
|
||||
club_id_1 = await insert_dummy(DUMMY_CLUB, ClubId)
|
||||
|
||||
await insert_dummy(
|
||||
UserXClub(user_id=user_id_1, club_id=club_id_1, relation=UserXClubRelation.OWNER), int
|
||||
UserXClubInsertable(user_id=user_id_1, club_id=club_id_1, relation=UserXClubRelation.OWNER),
|
||||
int,
|
||||
)
|
||||
|
||||
if real_user_id is not None:
|
||||
await insert_dummy(
|
||||
UserXClub(user_id=real_user_id, club_id=club_id_1, relation=UserXClubRelation.OWNER),
|
||||
UserXClubInsertable(
|
||||
user_id=real_user_id, club_id=club_id_1, relation=UserXClubRelation.OWNER
|
||||
),
|
||||
int,
|
||||
)
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@ from zoneinfo import ZoneInfo
|
||||
from heliclockter import datetime_utc
|
||||
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.club import Club
|
||||
from bracket.models.db.court import Court
|
||||
from bracket.models.db.match import Match
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.player_x_team import PlayerXTeam
|
||||
from bracket.models.db.club import ClubInsertable
|
||||
from bracket.models.db.court import CourtInsertable
|
||||
from bracket.models.db.match import MatchInsertable
|
||||
from bracket.models.db.player import PlayerInsertable
|
||||
from bracket.models.db.player_x_team import PlayerXTeamInsertable
|
||||
from bracket.models.db.ranking import RankingInsertable
|
||||
from bracket.models.db.round import Round
|
||||
from bracket.models.db.stage import Stage
|
||||
from bracket.models.db.stage_item import StageItemToInsert, StageType
|
||||
from bracket.models.db.team import Team
|
||||
from bracket.models.db.tournament import Tournament
|
||||
from bracket.models.db.user import User
|
||||
from bracket.models.db.round import RoundInsertable
|
||||
from bracket.models.db.stage import StageInsertable
|
||||
from bracket.models.db.stage_item import StageItemInsertable, StageType
|
||||
from bracket.models.db.team import TeamInsertable
|
||||
from bracket.models.db.tournament import TournamentInsertable
|
||||
from bracket.models.db.user import UserInsertable
|
||||
from bracket.utils.id_types import (
|
||||
ClubId,
|
||||
CourtId,
|
||||
@@ -34,12 +34,12 @@ DUMMY_MOCK_TIME = datetime_utc(2022, 1, 11, 4, 32, 11, tzinfo=ZoneInfo("UTC"))
|
||||
# We don't know any db IDs here, so we use a placeholder for foreign keys.
|
||||
DB_PLACEHOLDER_ID = -42
|
||||
|
||||
DUMMY_CLUB = Club(
|
||||
DUMMY_CLUB = ClubInsertable(
|
||||
name="Some Cool Club",
|
||||
created=DUMMY_MOCK_TIME,
|
||||
)
|
||||
|
||||
DUMMY_TOURNAMENT = Tournament(
|
||||
DUMMY_TOURNAMENT = TournamentInsertable(
|
||||
club_id=ClubId(DB_PLACEHOLDER_ID),
|
||||
name="Some Cool Tournament",
|
||||
created=DUMMY_MOCK_TIME,
|
||||
@@ -53,21 +53,21 @@ DUMMY_TOURNAMENT = Tournament(
|
||||
margin_minutes=5,
|
||||
)
|
||||
|
||||
DUMMY_STAGE1 = Stage(
|
||||
DUMMY_STAGE1 = StageInsertable(
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_active=True,
|
||||
name="Group Stage",
|
||||
)
|
||||
|
||||
DUMMY_STAGE2 = Stage(
|
||||
DUMMY_STAGE2 = StageInsertable(
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_active=False,
|
||||
name="Knockout Stage",
|
||||
)
|
||||
|
||||
DUMMY_STAGE_ITEM1 = StageItemToInsert(
|
||||
DUMMY_STAGE_ITEM1 = StageItemInsertable(
|
||||
stage_id=StageId(DB_PLACEHOLDER_ID),
|
||||
ranking_id=RankingId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
@@ -76,7 +76,7 @@ DUMMY_STAGE_ITEM1 = StageItemToInsert(
|
||||
name="Group A",
|
||||
)
|
||||
|
||||
DUMMY_STAGE_ITEM2 = StageItemToInsert(
|
||||
DUMMY_STAGE_ITEM2 = StageItemInsertable(
|
||||
stage_id=StageId(DB_PLACEHOLDER_ID),
|
||||
ranking_id=RankingId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
@@ -85,7 +85,7 @@ DUMMY_STAGE_ITEM2 = StageItemToInsert(
|
||||
name="Group B",
|
||||
)
|
||||
|
||||
DUMMY_STAGE_ITEM3 = StageItemToInsert(
|
||||
DUMMY_STAGE_ITEM3 = StageItemInsertable(
|
||||
stage_id=StageId(DB_PLACEHOLDER_ID),
|
||||
ranking_id=RankingId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
@@ -94,28 +94,28 @@ DUMMY_STAGE_ITEM3 = StageItemToInsert(
|
||||
name="Bracket A",
|
||||
)
|
||||
|
||||
DUMMY_ROUND1 = Round(
|
||||
DUMMY_ROUND1 = RoundInsertable(
|
||||
stage_item_id=StageItemId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_draft=False,
|
||||
name="Round 1",
|
||||
)
|
||||
|
||||
DUMMY_ROUND2 = Round(
|
||||
DUMMY_ROUND2 = RoundInsertable(
|
||||
stage_item_id=StageItemId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_draft=True,
|
||||
name="Round 2",
|
||||
)
|
||||
|
||||
DUMMY_ROUND3 = Round(
|
||||
DUMMY_ROUND3 = RoundInsertable(
|
||||
stage_item_id=StageItemId(DB_PLACEHOLDER_ID),
|
||||
created=DUMMY_MOCK_TIME,
|
||||
is_draft=False,
|
||||
name="Round 3",
|
||||
)
|
||||
|
||||
DUMMY_MATCH1 = Match(
|
||||
DUMMY_MATCH1 = MatchInsertable(
|
||||
created=DUMMY_MOCK_TIME,
|
||||
start_time=DUMMY_MOCK_TIME,
|
||||
round_id=RoundId(DB_PLACEHOLDER_ID),
|
||||
@@ -137,7 +137,7 @@ DUMMY_MATCH1 = Match(
|
||||
position_in_schedule=1,
|
||||
)
|
||||
|
||||
DUMMY_USER = User(
|
||||
DUMMY_USER = UserInsertable(
|
||||
email="admin@example.com",
|
||||
name="Admin",
|
||||
password_hash=hash_password("adminadmin"),
|
||||
@@ -145,28 +145,28 @@ DUMMY_USER = User(
|
||||
account_type=UserAccountType.REGULAR,
|
||||
)
|
||||
|
||||
DUMMY_TEAM1 = Team(
|
||||
DUMMY_TEAM1 = TeamInsertable(
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name="Team 1",
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM2 = Team(
|
||||
DUMMY_TEAM2 = TeamInsertable(
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name="Team 2",
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM3 = Team(
|
||||
DUMMY_TEAM3 = TeamInsertable(
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name="Team 3",
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
active=True,
|
||||
)
|
||||
|
||||
DUMMY_TEAM4 = Team(
|
||||
DUMMY_TEAM4 = TeamInsertable(
|
||||
created=DUMMY_MOCK_TIME,
|
||||
name="Team 4",
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
@@ -174,74 +174,74 @@ DUMMY_TEAM4 = Team(
|
||||
)
|
||||
|
||||
|
||||
DUMMY_PLAYER1 = Player(
|
||||
DUMMY_PLAYER1 = PlayerInsertable(
|
||||
name="Player 01",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER2 = Player(
|
||||
DUMMY_PLAYER2 = PlayerInsertable(
|
||||
name="Player 02",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER3 = Player(
|
||||
DUMMY_PLAYER3 = PlayerInsertable(
|
||||
name="Player 03",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER4 = Player(
|
||||
DUMMY_PLAYER4 = PlayerInsertable(
|
||||
name="Player 04",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER5 = Player(
|
||||
DUMMY_PLAYER5 = PlayerInsertable(
|
||||
name="Player 05",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER6 = Player(
|
||||
DUMMY_PLAYER6 = PlayerInsertable(
|
||||
name="Player 06",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER7 = Player(
|
||||
DUMMY_PLAYER7 = PlayerInsertable(
|
||||
name="Player 07",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER8 = Player(
|
||||
DUMMY_PLAYER8 = PlayerInsertable(
|
||||
name="Player 08",
|
||||
active=True,
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_PLAYER_X_TEAM = PlayerXTeam(
|
||||
DUMMY_PLAYER_X_TEAM = PlayerXTeamInsertable(
|
||||
player_id=PlayerId(DB_PLACEHOLDER_ID),
|
||||
team_id=TeamId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_COURT1 = Court(
|
||||
DUMMY_COURT1 = CourtInsertable(
|
||||
name="Court 1",
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
)
|
||||
|
||||
DUMMY_COURT2 = Court(
|
||||
DUMMY_COURT2 = CourtInsertable(
|
||||
name="Court 2",
|
||||
created=DUMMY_MOCK_TIME,
|
||||
tournament_id=TournamentId(DB_PLACEHOLDER_ID),
|
||||
|
||||
@@ -10,14 +10,13 @@ from bracket.config import config
|
||||
from bracket.database import database
|
||||
from bracket.logger import get_logger
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.user import User
|
||||
from bracket.models.db.user import UserInsertable
|
||||
from bracket.sql.users import (
|
||||
check_whether_email_is_in_use,
|
||||
create_user,
|
||||
)
|
||||
from bracket.utils.db_init import sql_create_dev_db
|
||||
from bracket.utils.security import hash_password
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
logger = get_logger("cli")
|
||||
|
||||
@@ -72,7 +71,7 @@ async def create_dev_db() -> None:
|
||||
@click.option("--name", prompt="Name", help="The name associated with the account.")
|
||||
@run_async
|
||||
async def register_user(email: str, password: str, name: str) -> None:
|
||||
user = User(
|
||||
user = UserInsertable(
|
||||
email=email,
|
||||
password_hash=hash_password(password),
|
||||
name=name,
|
||||
@@ -83,7 +82,6 @@ async def register_user(email: str, password: str, name: str) -> None:
|
||||
logger.error("Email address already in use")
|
||||
raise SystemExit(1)
|
||||
user_created = await create_user(user)
|
||||
assert_some(user_created.id)
|
||||
logger.info(f"Created user with id: {user_created.id}")
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM1,
|
||||
)
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import SUCCESS_RESPONSE, send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import (
|
||||
@@ -55,30 +54,30 @@ async def test_activate_next_stage(
|
||||
DUMMY_TEAM1.model_copy(update={"tournament_id": auth_context.tournament.id})
|
||||
) as team_inserted_4,
|
||||
):
|
||||
tournament_id = assert_some(auth_context.tournament.id)
|
||||
tournament_id = auth_context.tournament.id
|
||||
stage_item_1 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_1.id),
|
||||
stage_id=stage_inserted_1.id,
|
||||
name=DUMMY_STAGE_ITEM1.name,
|
||||
team_count=DUMMY_STAGE_ITEM1.team_count,
|
||||
type=DUMMY_STAGE_ITEM1.type,
|
||||
inputs=[
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=1,
|
||||
team_id=assert_some(team_inserted_1.id),
|
||||
team_id=team_inserted_1.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=2,
|
||||
team_id=assert_some(team_inserted_2.id),
|
||||
team_id=team_inserted_2.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=3,
|
||||
team_id=assert_some(team_inserted_3.id),
|
||||
team_id=team_inserted_3.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=4,
|
||||
team_id=assert_some(team_inserted_4.id),
|
||||
team_id=team_inserted_4.id,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -86,7 +85,7 @@ async def test_activate_next_stage(
|
||||
stage_item_2 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_2.id),
|
||||
stage_id=stage_inserted_2.id,
|
||||
name=DUMMY_STAGE_ITEM3.name,
|
||||
team_count=2,
|
||||
type=DUMMY_STAGE_ITEM3.type,
|
||||
@@ -108,12 +107,12 @@ async def test_activate_next_stage(
|
||||
await build_matches_for_stage_item(stage_item_2, tournament_id)
|
||||
|
||||
# Set match score to get a winner (team 2) that goes to the next round
|
||||
[prev_stage, _] = await get_full_tournament_details(assert_some(auth_context.tournament.id))
|
||||
[prev_stage, _] = await get_full_tournament_details(auth_context.tournament.id)
|
||||
match1 = prev_stage.stage_items[0].rounds[0].matches[0]
|
||||
assert isinstance(match1, MatchWithDetailsDefinitive)
|
||||
assert match1.team2.id == team_inserted_2.id
|
||||
await sql_update_match(
|
||||
assert_some(match1.id),
|
||||
match1.id,
|
||||
MatchBody(**match1.model_copy(update={"team2_score": 42}).model_dump()),
|
||||
auth_context.tournament,
|
||||
)
|
||||
@@ -121,7 +120,7 @@ async def test_activate_next_stage(
|
||||
response = await send_tournament_request(
|
||||
HTTPMethod.POST, "stages/activate?direction=next", auth_context, json={}
|
||||
)
|
||||
[_, next_stage] = await get_full_tournament_details(assert_some(auth_context.tournament.id))
|
||||
[_, next_stage] = await get_full_tournament_details(auth_context.tournament.id)
|
||||
|
||||
await sql_delete_stage_item_with_foreign_keys(stage_item_2.id)
|
||||
await sql_delete_stage_item_with_foreign_keys(stage_item_1.id)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from heliclockter import datetime_utc
|
||||
|
||||
from bracket.models.db.round import RoundToInsert
|
||||
from bracket.models.db.round import RoundInsertable
|
||||
from bracket.models.db.stage_item import StageItemCreateBody, StageType
|
||||
from bracket.models.db.stage_item_inputs import (
|
||||
StageItemInputCreateBodyFinal,
|
||||
@@ -21,6 +21,7 @@ from tests.integration_tests.api.shared import (
|
||||
SUCCESS_RESPONSE,
|
||||
send_tournament_request,
|
||||
)
|
||||
from tests.integration_tests.mocks import MOCK_NOW
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import (
|
||||
inserted_court,
|
||||
@@ -46,28 +47,34 @@ async def test_schedule_matches_auto(
|
||||
DUMMY_TEAM1.model_copy(update={"tournament_id": auth_context.tournament.id})
|
||||
) as team_inserted_2,
|
||||
):
|
||||
tournament_id = assert_some(auth_context.tournament.id)
|
||||
tournament_id = auth_context.tournament.id
|
||||
stage_item_1 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_1.id),
|
||||
stage_id=stage_inserted_1.id,
|
||||
name=DUMMY_STAGE_ITEM1.name,
|
||||
team_count=2,
|
||||
type=StageType.SWISS,
|
||||
inputs=[
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=1,
|
||||
team_id=assert_some(team_inserted_1.id),
|
||||
team_id=team_inserted_1.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=2,
|
||||
team_id=assert_some(team_inserted_2.id),
|
||||
team_id=team_inserted_2.id,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
await sql_create_round(
|
||||
RoundToInsert(stage_item_id=stage_item_1.id, name="", is_draft=True, is_active=False),
|
||||
RoundInsertable(
|
||||
stage_item_id=stage_item_1.id,
|
||||
name="",
|
||||
is_draft=True,
|
||||
is_active=False,
|
||||
created=MOCK_NOW,
|
||||
),
|
||||
)
|
||||
|
||||
response = await send_tournament_request(
|
||||
@@ -103,31 +110,43 @@ async def test_start_next_round(
|
||||
DUMMY_TEAM1.model_copy(update={"tournament_id": auth_context.tournament.id})
|
||||
) as team_inserted_2,
|
||||
):
|
||||
tournament_id = assert_some(auth_context.tournament.id)
|
||||
tournament_id = auth_context.tournament.id
|
||||
stage_item_1 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_1.id),
|
||||
stage_id=stage_inserted_1.id,
|
||||
name=DUMMY_STAGE_ITEM1.name,
|
||||
team_count=2,
|
||||
type=StageType.SWISS,
|
||||
inputs=[
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=1,
|
||||
team_id=assert_some(team_inserted_1.id),
|
||||
team_id=team_inserted_1.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=2,
|
||||
team_id=assert_some(team_inserted_2.id),
|
||||
team_id=team_inserted_2.id,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
round_1_id = await sql_create_round(
|
||||
RoundToInsert(stage_item_id=stage_item_1.id, name="", is_draft=True, is_active=False),
|
||||
RoundInsertable(
|
||||
stage_item_id=stage_item_1.id,
|
||||
name="",
|
||||
is_draft=True,
|
||||
is_active=False,
|
||||
created=MOCK_NOW,
|
||||
),
|
||||
)
|
||||
round_2_id = await sql_create_round(
|
||||
RoundToInsert(stage_item_id=stage_item_1.id, name="", is_draft=True, is_active=False),
|
||||
RoundInsertable(
|
||||
stage_item_id=stage_item_1.id,
|
||||
name="",
|
||||
is_draft=True,
|
||||
is_active=False,
|
||||
created=MOCK_NOW,
|
||||
),
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
from bracket.models.db.user_x_club import UserXClub, UserXClubRelation
|
||||
from bracket.models.db.user_x_club import UserXClubInsertable, UserXClubRelation
|
||||
from bracket.sql.clubs import get_clubs_for_user_id, sql_delete_club
|
||||
from bracket.utils.dummy_records import DUMMY_CLUB, DUMMY_MOCK_TIME
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import send_auth_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_club, inserted_user_x_club
|
||||
@@ -27,7 +26,7 @@ async def test_create_club(
|
||||
) -> None:
|
||||
payload = {"name": "Some Cool Club"}
|
||||
response = await send_auth_request(HTTPMethod.POST, "clubs", auth_context, json=payload)
|
||||
user_id = assert_some(auth_context.user.id)
|
||||
user_id = auth_context.user.id
|
||||
|
||||
clubs = await get_clubs_for_user_id(user_id)
|
||||
club_id = response["data"]["id"]
|
||||
@@ -43,9 +42,9 @@ async def test_delete_club(
|
||||
) -> None:
|
||||
async with inserted_club(DUMMY_CLUB) as club_inserted:
|
||||
async with inserted_user_x_club(
|
||||
UserXClub(
|
||||
user_id=assert_some(auth_context.user.id),
|
||||
club_id=assert_some(club_inserted.id),
|
||||
UserXClubInsertable(
|
||||
user_id=auth_context.user.id,
|
||||
club_id=club_inserted.id,
|
||||
relation=UserXClubRelation.OWNER,
|
||||
)
|
||||
):
|
||||
|
||||
@@ -19,7 +19,6 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM2,
|
||||
)
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import SUCCESS_RESPONSE, send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import (
|
||||
@@ -286,25 +285,25 @@ async def test_upcoming_matches_endpoint(
|
||||
DUMMY_PLAYER1.model_copy(
|
||||
update={"elo_score": Decimal("1100.0"), "tournament_id": auth_context.tournament.id}
|
||||
),
|
||||
assert_some(team1_inserted.id),
|
||||
team1_inserted.id,
|
||||
) as player_inserted_1,
|
||||
inserted_player_in_team(
|
||||
DUMMY_PLAYER2.model_copy(
|
||||
update={"elo_score": Decimal("1300.0"), "tournament_id": auth_context.tournament.id}
|
||||
),
|
||||
assert_some(team2_inserted.id),
|
||||
team2_inserted.id,
|
||||
) as player_inserted_2,
|
||||
inserted_player_in_team(
|
||||
DUMMY_PLAYER3.model_copy(
|
||||
update={"elo_score": Decimal("1200.0"), "tournament_id": auth_context.tournament.id}
|
||||
),
|
||||
assert_some(team1_inserted.id),
|
||||
team1_inserted.id,
|
||||
) as player_inserted_3,
|
||||
inserted_player_in_team(
|
||||
DUMMY_PLAYER4.model_copy(
|
||||
update={"elo_score": Decimal("1400.0"), "tournament_id": auth_context.tournament.id}
|
||||
),
|
||||
assert_some(team2_inserted.id),
|
||||
team2_inserted.id,
|
||||
) as player_inserted_4,
|
||||
):
|
||||
json_response = await send_tournament_request(
|
||||
|
||||
@@ -11,7 +11,6 @@ from bracket.sql.rankings import (
|
||||
from bracket.utils.db import fetch_one_parsed_certain
|
||||
from bracket.utils.dummy_records import DUMMY_RANKING1, DUMMY_TEAM1
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import SUCCESS_RESPONSE, send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import inserted_ranking, inserted_team
|
||||
@@ -45,7 +44,7 @@ async def test_create_ranking(
|
||||
response = await send_tournament_request(HTTPMethod.POST, "rankings", auth_context, json={})
|
||||
assert response.get("success") is True, response
|
||||
|
||||
tournament_id = assert_some(auth_context.tournament.id)
|
||||
tournament_id = auth_context.tournament.id
|
||||
for ranking in await get_all_rankings_in_tournament(tournament_id):
|
||||
if ranking.position != 0:
|
||||
await sql_delete_ranking(tournament_id, ranking.id)
|
||||
|
||||
@@ -12,7 +12,6 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM2,
|
||||
)
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import SUCCESS_RESPONSE, send_tournament_request
|
||||
from tests.integration_tests.models import AuthContext
|
||||
from tests.integration_tests.sql import (
|
||||
@@ -65,9 +64,9 @@ async def test_reschedule_match(
|
||||
) as match_inserted,
|
||||
):
|
||||
body = MatchRescheduleBody(
|
||||
old_court_id=assert_some(court1_inserted.id),
|
||||
old_court_id=court1_inserted.id,
|
||||
old_position=1,
|
||||
new_court_id=assert_some(court2_inserted.id),
|
||||
new_court_id=court2_inserted.id,
|
||||
new_position=2,
|
||||
)
|
||||
assert (
|
||||
@@ -79,7 +78,7 @@ async def test_reschedule_match(
|
||||
)
|
||||
== SUCCESS_RESPONSE
|
||||
)
|
||||
match = await sql_get_match(assert_some(match_inserted.id))
|
||||
match = await sql_get_match(match_inserted.id)
|
||||
await assert_row_count_and_clear(matches, 0)
|
||||
|
||||
assert match.court_id == body.new_court_id
|
||||
|
||||
@@ -15,7 +15,6 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM1,
|
||||
)
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import (
|
||||
SUCCESS_RESPONSE,
|
||||
send_tournament_request,
|
||||
@@ -51,30 +50,30 @@ async def test_schedule_all_matches(
|
||||
DUMMY_TEAM1.model_copy(update={"tournament_id": auth_context.tournament.id})
|
||||
) as team_inserted_4,
|
||||
):
|
||||
tournament_id = assert_some(auth_context.tournament.id)
|
||||
tournament_id = auth_context.tournament.id
|
||||
stage_item_1 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_1.id),
|
||||
stage_id=stage_inserted_1.id,
|
||||
name=DUMMY_STAGE_ITEM1.name,
|
||||
team_count=DUMMY_STAGE_ITEM1.team_count,
|
||||
type=DUMMY_STAGE_ITEM1.type,
|
||||
inputs=[
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=1,
|
||||
team_id=assert_some(team_inserted_1.id),
|
||||
team_id=team_inserted_1.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=2,
|
||||
team_id=assert_some(team_inserted_2.id),
|
||||
team_id=team_inserted_2.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=3,
|
||||
team_id=assert_some(team_inserted_3.id),
|
||||
team_id=team_inserted_3.id,
|
||||
),
|
||||
StageItemInputCreateBodyFinal(
|
||||
slot=4,
|
||||
team_id=assert_some(team_inserted_4.id),
|
||||
team_id=team_inserted_4.id,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -82,7 +81,7 @@ async def test_schedule_all_matches(
|
||||
stage_item_2 = await sql_create_stage_item(
|
||||
tournament_id,
|
||||
StageItemCreateBody(
|
||||
stage_id=assert_some(stage_inserted_1.id),
|
||||
stage_id=stage_inserted_1.id,
|
||||
name=DUMMY_STAGE_ITEM3.name,
|
||||
team_count=2,
|
||||
type=DUMMY_STAGE_ITEM3.type,
|
||||
|
||||
@@ -11,7 +11,6 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM1,
|
||||
)
|
||||
from bracket.utils.http import HTTPMethod
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.api.shared import (
|
||||
SUCCESS_RESPONSE,
|
||||
send_request,
|
||||
@@ -147,7 +146,7 @@ async def test_update_stage(
|
||||
)
|
||||
== SUCCESS_RESPONSE
|
||||
)
|
||||
[updated_stage] = await get_full_tournament_details(assert_some(auth_context.tournament.id))
|
||||
[updated_stage] = await get_full_tournament_details(auth_context.tournament.id)
|
||||
assert len(updated_stage.stage_items) == 1
|
||||
assert updated_stage.name == body["name"]
|
||||
|
||||
@@ -173,9 +172,7 @@ async def test_activate_stage(
|
||||
)
|
||||
== SUCCESS_RESPONSE
|
||||
)
|
||||
[prev_stage, next_stage] = await get_full_tournament_details(
|
||||
assert_some(auth_context.tournament.id)
|
||||
)
|
||||
[prev_stage, next_stage] = await get_full_tournament_details(auth_context.tournament.id)
|
||||
assert prev_stage.is_active is False
|
||||
assert next_stage.is_active is True
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ async def test_create_tournament(
|
||||
|
||||
# Cleanup
|
||||
tournament = assert_some(await sql_get_tournament_by_endpoint_name(dashboard_endpoint))
|
||||
await sql_delete_tournament_completely(assert_some(tournament.id))
|
||||
await sql_delete_tournament_completely(tournament.id)
|
||||
|
||||
|
||||
async def test_update_tournament(
|
||||
@@ -133,7 +133,7 @@ async def test_delete_tournament(
|
||||
== SUCCESS_RESPONSE
|
||||
)
|
||||
|
||||
await sql_delete_tournament(assert_some(tournament_inserted.id))
|
||||
await sql_delete_tournament(tournament_inserted.id)
|
||||
|
||||
|
||||
async def test_tournament_upload_and_remove_logo(
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
from bracket.cronjobs.scheduling import delete_demo_accounts
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.sql.users import get_user_by_id, update_user_account_type
|
||||
from bracket.utils.types import assert_some
|
||||
from tests.integration_tests.sql import inserted_auth_context
|
||||
|
||||
|
||||
async def test_delete_demo_accounts() -> None:
|
||||
async with inserted_auth_context() as auth_context:
|
||||
user_id = assert_some(auth_context.user.id)
|
||||
user_id = auth_context.user.id
|
||||
await update_user_account_type(user_id, UserAccountType.DEMO)
|
||||
|
||||
assert await get_user_by_id(user_id) is not None
|
||||
|
||||
@@ -4,7 +4,7 @@ from zoneinfo import ZoneInfo
|
||||
from heliclockter import datetime_utc, timedelta
|
||||
|
||||
from bracket.models.db.account import UserAccountType
|
||||
from bracket.models.db.user import User
|
||||
from bracket.models.db.user import UserInsertable
|
||||
from bracket.routes.auth import ACCESS_TOKEN_EXPIRE_MINUTES, create_access_token
|
||||
|
||||
MOCK_NOW = datetime_utc(
|
||||
@@ -16,8 +16,8 @@ def generate_email() -> str:
|
||||
return f"donald_duck-{uuid4()}"
|
||||
|
||||
|
||||
def get_mock_user() -> User:
|
||||
return User(
|
||||
def get_mock_user() -> UserInsertable:
|
||||
return UserInsertable(
|
||||
email=generate_email(),
|
||||
name="Donald Duck",
|
||||
# hash of 'mypassword'
|
||||
@@ -27,7 +27,7 @@ def get_mock_user() -> User:
|
||||
)
|
||||
|
||||
|
||||
def get_mock_token(mock_user: User) -> str:
|
||||
def get_mock_token(mock_user: UserInsertable) -> str:
|
||||
return create_access_token(
|
||||
data={"user": mock_user.email},
|
||||
expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES),
|
||||
|
||||
@@ -5,19 +5,19 @@ from typing import cast
|
||||
from sqlalchemy import Table
|
||||
|
||||
from bracket.database import database
|
||||
from bracket.models.db.club import Club
|
||||
from bracket.models.db.court import Court
|
||||
from bracket.models.db.match import Match
|
||||
from bracket.models.db.player import Player
|
||||
from bracket.models.db.player_x_team import PlayerXTeam
|
||||
from bracket.models.db.club import Club, ClubInsertable
|
||||
from bracket.models.db.court import Court, CourtInsertable
|
||||
from bracket.models.db.match import Match, MatchInsertable
|
||||
from bracket.models.db.player import Player, PlayerInsertable
|
||||
from bracket.models.db.player_x_team import PlayerXTeamInsertable
|
||||
from bracket.models.db.ranking import Ranking, RankingInsertable
|
||||
from bracket.models.db.round import Round
|
||||
from bracket.models.db.stage import Stage
|
||||
from bracket.models.db.stage_item import StageItem, StageItemToInsert
|
||||
from bracket.models.db.team import Team
|
||||
from bracket.models.db.tournament import Tournament
|
||||
from bracket.models.db.user import User, UserInDB
|
||||
from bracket.models.db.user_x_club import UserXClub, UserXClubRelation
|
||||
from bracket.models.db.round import Round, RoundInsertable
|
||||
from bracket.models.db.stage import Stage, StageInsertable
|
||||
from bracket.models.db.stage_item import StageItem, StageItemInsertable
|
||||
from bracket.models.db.team import Team, TeamInsertable
|
||||
from bracket.models.db.tournament import Tournament, TournamentInsertable
|
||||
from bracket.models.db.user import UserInDB, UserInsertable
|
||||
from bracket.models.db.user_x_club import UserXClub, UserXClubInsertable, UserXClubRelation
|
||||
from bracket.schema import (
|
||||
clubs,
|
||||
courts,
|
||||
@@ -36,7 +36,7 @@ from bracket.schema import (
|
||||
from bracket.utils.db import insert_generic
|
||||
from bracket.utils.dummy_records import DUMMY_CLUB, DUMMY_RANKING1, DUMMY_TOURNAMENT
|
||||
from bracket.utils.id_types import TeamId
|
||||
from bracket.utils.types import BaseModelT, assert_some
|
||||
from bracket.utils.types import BaseModelT
|
||||
from tests.integration_tests.mocks import get_mock_token, get_mock_user
|
||||
from tests.integration_tests.models import AuthContext
|
||||
|
||||
@@ -59,33 +59,33 @@ async def inserted_generic(
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_user(user: User) -> AsyncIterator[UserInDB]:
|
||||
async def inserted_user(user: UserInsertable) -> AsyncIterator[UserInDB]:
|
||||
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 def inserted_club(club: ClubInsertable) -> AsyncIterator[Club]:
|
||||
async with inserted_generic(club, clubs, Club) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Club, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_tournament(tournament: Tournament) -> AsyncIterator[Tournament]:
|
||||
async def inserted_tournament(tournament: TournamentInsertable) -> AsyncIterator[Tournament]:
|
||||
async with inserted_generic(tournament, tournaments, Tournament) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Tournament, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_team(team: Team) -> AsyncIterator[Team]:
|
||||
async def inserted_team(team: TeamInsertable) -> AsyncIterator[Team]:
|
||||
async with inserted_generic(team, teams, Team) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Team, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_court(court: Court) -> AsyncIterator[Court]:
|
||||
async def inserted_court(court: CourtInsertable) -> AsyncIterator[Court]:
|
||||
async with inserted_generic(court, courts, Court) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Court, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@@ -95,50 +95,52 @@ async def inserted_ranking(ranking: RankingInsertable) -> AsyncIterator[Ranking]
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_player(player: Player) -> AsyncIterator[Player]:
|
||||
async def inserted_player(player: PlayerInsertable) -> AsyncIterator[Player]:
|
||||
async with inserted_generic(player, players, Player) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Player, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_player_in_team(player: Player, team_id: TeamId) -> AsyncIterator[Player]:
|
||||
async def inserted_player_in_team(
|
||||
player: PlayerInsertable, team_id: TeamId
|
||||
) -> AsyncIterator[Player]:
|
||||
async with inserted_generic(player, players, Player) as row_inserted:
|
||||
async with inserted_generic(
|
||||
PlayerXTeam(player_id=assert_some(row_inserted.id), team_id=team_id),
|
||||
PlayerXTeamInsertable(player_id=cast(Player, row_inserted).id, team_id=team_id),
|
||||
players_x_teams,
|
||||
PlayerXTeam,
|
||||
PlayerXTeamInsertable,
|
||||
):
|
||||
yield row_inserted
|
||||
yield cast(Player, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_stage(stage: Stage) -> AsyncIterator[Stage]:
|
||||
async def inserted_stage(stage: StageInsertable) -> AsyncIterator[Stage]:
|
||||
async with inserted_generic(stage, stages, Stage) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Stage, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_stage_item(stage_item: StageItemToInsert) -> AsyncIterator[StageItem]:
|
||||
async def inserted_stage_item(stage_item: StageItemInsertable) -> AsyncIterator[StageItem]:
|
||||
async with inserted_generic(stage_item, stage_items, StageItem) as row_inserted:
|
||||
yield StageItem(**row_inserted.model_dump())
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_round(round_: Round) -> AsyncIterator[Round]:
|
||||
async def inserted_round(round_: RoundInsertable) -> AsyncIterator[Round]:
|
||||
async with inserted_generic(round_, rounds, Round) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Round, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_match(match: Match) -> AsyncIterator[Match]:
|
||||
async def inserted_match(match: MatchInsertable) -> AsyncIterator[Match]:
|
||||
async with inserted_generic(match, matches, Match) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(Match, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def inserted_user_x_club(user_x_club: UserXClub) -> AsyncIterator[UserXClub]:
|
||||
async def inserted_user_x_club(user_x_club: UserXClubInsertable) -> AsyncIterator[UserXClub]:
|
||||
async with inserted_generic(user_x_club, users_x_clubs, UserXClub) as row_inserted:
|
||||
yield row_inserted
|
||||
yield cast(UserXClub, row_inserted)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@@ -155,9 +157,9 @@ async def inserted_auth_context() -> AsyncIterator[AuthContext]:
|
||||
DUMMY_RANKING1.model_copy(update={"tournament_id": tournament_inserted.id})
|
||||
) as ranking_inserted,
|
||||
inserted_user_x_club(
|
||||
UserXClub(
|
||||
UserXClubInsertable(
|
||||
user_id=user_inserted.id,
|
||||
club_id=assert_some(club_inserted.id),
|
||||
club_id=club_inserted.id,
|
||||
relation=UserXClubRelation.OWNER,
|
||||
)
|
||||
) as user_x_club_inserted,
|
||||
|
||||
@@ -11,7 +11,16 @@ from bracket.models.db.stage_item_inputs import StageItemInputFinal
|
||||
from bracket.models.db.team import FullTeamWithPlayers
|
||||
from bracket.models.db.util import RoundWithMatches, StageItemWithRounds
|
||||
from bracket.utils.dummy_records import DUMMY_TEAM1, DUMMY_TEAM2
|
||||
from bracket.utils.id_types import RankingId, RoundId, StageId, StageItemId, TeamId, TournamentId
|
||||
from bracket.utils.id_types import (
|
||||
MatchId,
|
||||
RankingId,
|
||||
RoundId,
|
||||
StageId,
|
||||
StageItemId,
|
||||
StageItemInputId,
|
||||
TeamId,
|
||||
TournamentId,
|
||||
)
|
||||
|
||||
|
||||
def test_determine_ranking_for_stage_item_elimination() -> None:
|
||||
@@ -21,8 +30,10 @@ def test_determine_ranking_for_stage_item_elimination() -> None:
|
||||
StageItemWithRounds(
|
||||
rounds=[
|
||||
RoundWithMatches(
|
||||
id=RoundId(-1),
|
||||
matches=[
|
||||
MatchWithDetailsDefinitive(
|
||||
id=MatchId(-1),
|
||||
team1=FullTeamWithPlayers(
|
||||
**DUMMY_TEAM1.model_dump(), players=[], id=TeamId(-1)
|
||||
),
|
||||
@@ -37,6 +48,7 @@ def test_determine_ranking_for_stage_item_elimination() -> None:
|
||||
team2_score=0,
|
||||
),
|
||||
MatchWithDetailsDefinitive(
|
||||
id=MatchId(-1),
|
||||
team1=FullTeamWithPlayers(
|
||||
**DUMMY_TEAM1.model_dump(), players=[], id=TeamId(-1)
|
||||
),
|
||||
@@ -51,6 +63,7 @@ def test_determine_ranking_for_stage_item_elimination() -> None:
|
||||
team2_score=2,
|
||||
),
|
||||
MatchWithDetails( # This gets ignored in ranking calculation
|
||||
id=MatchId(-1),
|
||||
created=now,
|
||||
duration_minutes=90,
|
||||
margin_minutes=15,
|
||||
@@ -66,8 +79,12 @@ def test_determine_ranking_for_stage_item_elimination() -> None:
|
||||
)
|
||||
],
|
||||
inputs=[
|
||||
StageItemInputFinal(team_id=TeamId(-1), slot=1, tournament_id=tournament_id),
|
||||
StageItemInputFinal(team_id=TeamId(-2), slot=2, tournament_id=tournament_id),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-1), team_id=TeamId(-1), slot=1, tournament_id=tournament_id
|
||||
),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-2), team_id=TeamId(-2), slot=2, tournament_id=tournament_id
|
||||
),
|
||||
],
|
||||
type_name="Single Elimination",
|
||||
team_count=4,
|
||||
@@ -103,8 +120,10 @@ def test_determine_ranking_for_stage_item_swiss() -> None:
|
||||
StageItemWithRounds(
|
||||
rounds=[
|
||||
RoundWithMatches(
|
||||
id=RoundId(-1),
|
||||
matches=[
|
||||
MatchWithDetailsDefinitive(
|
||||
id=MatchId(-1),
|
||||
team1=FullTeamWithPlayers(
|
||||
**DUMMY_TEAM1.model_dump(), players=[], id=TeamId(-1)
|
||||
),
|
||||
@@ -119,6 +138,7 @@ def test_determine_ranking_for_stage_item_swiss() -> None:
|
||||
team2_score=0,
|
||||
),
|
||||
MatchWithDetailsDefinitive(
|
||||
id=MatchId(-2),
|
||||
team1=FullTeamWithPlayers(
|
||||
**DUMMY_TEAM1.model_dump(), players=[], id=TeamId(-1)
|
||||
),
|
||||
@@ -133,6 +153,7 @@ def test_determine_ranking_for_stage_item_swiss() -> None:
|
||||
team2_score=2,
|
||||
),
|
||||
MatchWithDetails( # This gets ignored in ranking calculation
|
||||
id=MatchId(-3),
|
||||
created=now,
|
||||
duration_minutes=90,
|
||||
margin_minutes=15,
|
||||
@@ -148,8 +169,12 @@ def test_determine_ranking_for_stage_item_swiss() -> None:
|
||||
)
|
||||
],
|
||||
inputs=[
|
||||
StageItemInputFinal(team_id=TeamId(-1), slot=1, tournament_id=tournament_id),
|
||||
StageItemInputFinal(team_id=TeamId(-2), slot=2, tournament_id=tournament_id),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-1), team_id=TeamId(-1), slot=1, tournament_id=tournament_id
|
||||
),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-2), team_id=TeamId(-2), slot=2, tournament_id=tournament_id
|
||||
),
|
||||
],
|
||||
type_name="Swiss",
|
||||
team_count=4,
|
||||
@@ -185,6 +210,7 @@ def test_determine_ranking_for_stage_item_swiss_no_matches() -> None:
|
||||
StageItemWithRounds(
|
||||
rounds=[
|
||||
RoundWithMatches(
|
||||
id=RoundId(-1),
|
||||
matches=[],
|
||||
stage_item_id=StageItemId(-1),
|
||||
created=now,
|
||||
@@ -193,8 +219,12 @@ def test_determine_ranking_for_stage_item_swiss_no_matches() -> None:
|
||||
)
|
||||
],
|
||||
inputs=[
|
||||
StageItemInputFinal(team_id=TeamId(-1), slot=1, tournament_id=tournament_id),
|
||||
StageItemInputFinal(team_id=TeamId(-2), slot=2, tournament_id=tournament_id),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-1), team_id=TeamId(-1), slot=1, tournament_id=tournament_id
|
||||
),
|
||||
StageItemInputFinal(
|
||||
id=StageItemInputId(-2), team_id=TeamId(-2), slot=2, tournament_id=tournament_id
|
||||
),
|
||||
],
|
||||
type_name="Swiss",
|
||||
team_count=4,
|
||||
|
||||
@@ -5,7 +5,7 @@ from fastapi import HTTPException
|
||||
|
||||
from bracket.logic.scheduling.ladder_teams import get_possible_upcoming_matches_for_swiss
|
||||
from bracket.models.db.match import Match, MatchFilter, MatchWithDetailsDefinitive, SuggestedMatch
|
||||
from bracket.models.db.team import FullTeamWithPlayers, Team
|
||||
from bracket.models.db.team import FullTeamWithPlayers, TeamInsertable
|
||||
from bracket.models.db.util import RoundWithMatches
|
||||
from bracket.utils.dummy_records import (
|
||||
DUMMY_MATCH1,
|
||||
@@ -14,7 +14,7 @@ from bracket.utils.dummy_records import (
|
||||
DUMMY_TEAM3,
|
||||
DUMMY_TEAM4,
|
||||
)
|
||||
from bracket.utils.id_types import StageItemId, TeamId
|
||||
from bracket.utils.id_types import MatchId, RoundId, StageItemId, TeamId
|
||||
from tests.integration_tests.mocks import MOCK_NOW
|
||||
|
||||
MATCH_FILTER = MatchFilter(elo_diff_threshold=50, iterations=100, limit=20, only_recommended=False)
|
||||
@@ -25,7 +25,7 @@ def test_no_draft_round() -> None:
|
||||
get_possible_upcoming_matches_for_swiss(MATCH_FILTER, [], [])
|
||||
|
||||
|
||||
def get_team(team: Team, team_id: TeamId) -> FullTeamWithPlayers:
|
||||
def get_team(team: TeamInsertable, team_id: TeamId) -> FullTeamWithPlayers:
|
||||
return FullTeamWithPlayers(
|
||||
id=team_id,
|
||||
**team.model_dump(exclude={"id"}),
|
||||
@@ -60,14 +60,26 @@ def test_constraints() -> None:
|
||||
|
||||
rounds = [
|
||||
RoundWithMatches(
|
||||
matches=[get_match(DUMMY_MATCH1, team1, team2)],
|
||||
id=RoundId(-1),
|
||||
matches=[
|
||||
get_match(
|
||||
Match.model_validate(DUMMY_MATCH1.model_dump() | {"id": MatchId(-1)}),
|
||||
team1,
|
||||
team2,
|
||||
)
|
||||
],
|
||||
is_draft=False,
|
||||
stage_item_id=StageItemId(-1),
|
||||
name="R1",
|
||||
created=MOCK_NOW,
|
||||
),
|
||||
RoundWithMatches(
|
||||
matches=[], is_draft=True, stage_item_id=StageItemId(-1), name="R2", created=MOCK_NOW
|
||||
id=RoundId(-1),
|
||||
matches=[],
|
||||
is_draft=True,
|
||||
stage_item_id=StageItemId(-1),
|
||||
name="R2",
|
||||
created=MOCK_NOW,
|
||||
),
|
||||
]
|
||||
teams = [team1, team2, team3, team4]
|
||||
|
||||
Reference in New Issue
Block a user