From fb883af9beab5576e44c01d2a3777b9b429d6d4f Mon Sep 17 00:00:00 2001 From: Alexandre Harano Date: Tue, 23 Jan 2024 17:20:45 -0300 Subject: [PATCH] chore: adjustments after running "pre-commit run --all-files" --- .gitignore | 3 - .../decisions/0003-data-modeling.md | 6 +- migrations/README | 2 +- migrations/env.py | 13 +- .../versions/ad6bf02d324d_initial_tables.py | 187 ++-- src/matamata/VERSION | 2 +- src/matamata/__init__.py | 4 +- src/matamata/database.py | 1 - src/matamata/main.py | 7 +- src/matamata/models/__init__.py | 13 +- src/matamata/models/competitor.py | 18 +- src/matamata/models/constants.py | 24 +- src/matamata/models/match.py | 110 +- src/matamata/models/tournament.py | 51 +- src/matamata/models/tournament_competitor.py | 18 +- src/matamata/routers/competitor.py | 59 +- src/matamata/routers/match.py | 28 +- src/matamata/routers/tournament.py | 163 ++- src/matamata/schemas.py | 28 +- src/matamata/services/__init__.py | 5 + .../services/register_match_result.py | 29 +- src/matamata/services/start_tournament.py | 44 +- src/matamata/settings.py | 4 +- tests/models/factories.py | 4 +- tests/models/test_competitor.py | 21 +- tests/models/test_match.py | 28 +- tests/models/test_tournament.py | 40 +- tests/models/test_tournament_competitor.py | 15 +- tests/routers/test_competitor.py | 159 +-- tests/routers/test_match.py | 388 ++++--- tests/routers/test_tournament.py | 983 ++++++++++-------- tests/services/test_register_match_result.py | 63 +- tests/services/test_start_tournament.py | 125 ++- tests/test_app.py | 4 +- tests/test_schemas.py | 392 ++++--- tests/utils.py | 14 +- 36 files changed, 1684 insertions(+), 1371 deletions(-) diff --git a/.gitignore b/.gitignore index fe7c070..414a61b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,9 +22,6 @@ .AppleDouble .LSOverride -# Icon must end with two \r -Icon - # Thumbnails ._* diff --git a/docs/architecture/decisions/0003-data-modeling.md b/docs/architecture/decisions/0003-data-modeling.md index 4c4d45b..67bc547 100644 --- a/docs/architecture/decisions/0003-data-modeling.md +++ b/docs/architecture/decisions/0003-data-modeling.md @@ -86,7 +86,7 @@ erDiagram int finalMatch FK "Reference to the final match" int thirdPlaceMatch FK "Reference to the third place match" } - + Match { int id PK "Internal identifier" uuid uuid UK "External identifier using UUID" @@ -103,13 +103,13 @@ erDiagram int winner FK "Reference to the winner competitor" int loser FK "Reference to the loser competitor" } - + TournamentCompetitor { int tournament PK, FK int competitor PK, FK timestamp created "Internal timestamp to track an instance creation" timestamp updated "Internal timestamp to track an instance creation" - int nextMatch FK "Reference to the next match the competitor will compete in the tournament" + int nextMatch FK "Reference to the next match the competitor will compete in the tournament" } Competitor only one -- zero or more TournamentCompetitor : is diff --git a/migrations/README b/migrations/README index 98e4f9c..2500aa1 100644 --- a/migrations/README +++ b/migrations/README @@ -1 +1 @@ -Generic single-database configuration. \ No newline at end of file +Generic single-database configuration. diff --git a/migrations/env.py b/migrations/env.py index e6e1fd8..c5793bc 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,18 +1,15 @@ from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - from alembic import context +from sqlalchemy import engine_from_config, pool -from matamata.settings import settings from matamata.models import Base - +from matamata.settings import settings # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config -config.set_main_option('sqlalchemy.url', settings.DATABASE_URL) +config.set_main_option("sqlalchemy.url", settings.DATABASE_URL) # Interpret the config file for Python logging. # This line sets up loggers basically. @@ -69,9 +66,7 @@ def run_migrations_online() -> None: ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/migrations/versions/ad6bf02d324d_initial_tables.py b/migrations/versions/ad6bf02d324d_initial_tables.py index f7f954b..108a13e 100644 --- a/migrations/versions/ad6bf02d324d_initial_tables.py +++ b/migrations/versions/ad6bf02d324d_initial_tables.py @@ -1,18 +1,17 @@ """initial tables Revision ID: ad6bf02d324d -Revises: +Revises: Create Date: 2024-01-11 12:28:20.802398 """ from typing import Sequence, Union -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. -revision: str = 'ad6bf02d324d' +revision: str = "ad6bf02d324d" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -20,76 +19,130 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.create_table('competitor', - sa.Column('label', sa.String(length=255), nullable=False), - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uuid', sa.Uuid(), nullable=False), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('updated', sa.DateTime(), nullable=False), - sa.CheckConstraint("NOT(TRIM(label) LIKE '')", name='competitor_label_not_empty_nor_whitespace_only'), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('uuid') + op.create_table( + "competitor", + sa.Column("label", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("uuid", sa.Uuid(), nullable=False), + sa.Column("created", sa.DateTime(), nullable=False), + sa.Column("updated", sa.DateTime(), nullable=False), + sa.CheckConstraint( + "NOT(TRIM(label) LIKE '')", + name="competitor_label_not_empty_nor_whitespace_only", + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("uuid"), ) - op.create_table('tournament', - sa.Column('label', sa.String(length=255), nullable=False), - sa.Column('matches_creation', sa.DateTime(), nullable=True), - sa.Column('number_competitors', sa.Integer(), nullable=True), - sa.Column('starting_round', sa.Integer(), nullable=True), - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uuid', sa.Uuid(), nullable=False), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('updated', sa.DateTime(), nullable=False), - sa.CheckConstraint("NOT(TRIM(label) LIKE '')", name='tournament_label_not_empty_nor_whitespace_only'), - sa.CheckConstraint('( matches_creation IS NULL AND number_competitors IS NULL AND starting_round IS NULL) OR ( matches_creation IS NOT NULL AND number_competitors IS NOT NULL AND starting_round IS NOT NULL AND number_competitors >= 1 AND starting_round >= 0)', name='tournament_all_null_or_all_set_under_conditions'), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('uuid') + op.create_table( + "tournament", + sa.Column("label", sa.String(length=255), nullable=False), + sa.Column("matches_creation", sa.DateTime(), nullable=True), + sa.Column("number_competitors", sa.Integer(), nullable=True), + sa.Column("starting_round", sa.Integer(), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("uuid", sa.Uuid(), nullable=False), + sa.Column("created", sa.DateTime(), nullable=False), + sa.Column("updated", sa.DateTime(), nullable=False), + sa.CheckConstraint( + "NOT(TRIM(label) LIKE '')", + name="tournament_label_not_empty_nor_whitespace_only", + ), + sa.CheckConstraint( + "( matches_creation IS NULL AND number_competitors IS NULL AND starting_round IS NULL) OR ( matches_creation IS NOT NULL AND number_competitors IS NOT NULL AND starting_round IS NOT NULL AND number_competitors >= 1 AND starting_round >= 0)", + name="tournament_all_null_or_all_set_under_conditions", + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("uuid"), ) - op.create_table('match', - sa.Column('tournament_id', sa.Integer(), nullable=False), - sa.Column('round', sa.Integer(), nullable=False), - sa.Column('position', sa.Integer(), nullable=False), - sa.Column('competitor_a_id', sa.Integer(), nullable=True), - sa.Column('competitor_b_id', sa.Integer(), nullable=True), - sa.Column('result_registration', sa.DateTime(), nullable=True), - sa.Column('winner_id', sa.Integer(), nullable=True), - sa.Column('loser_id', sa.Integer(), nullable=True), - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uuid', sa.Uuid(), nullable=False), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('updated', sa.DateTime(), nullable=False), - sa.CheckConstraint('( competitor_a_id IS NULL AND competitor_b_id IS NULL) OR ( competitor_a_id <> competitor_b_id)', name='match_non_null_competitors_cannot_be_the_same'), - sa.CheckConstraint('( result_registration IS NULL AND loser_id is NULL) OR ( result_registration IS NOT NULL AND loser_id is NULL) OR ( result_registration IS NOT NULL AND loser_id IS NOT NULL)', name='match_result_registration_loser'), - sa.CheckConstraint('( result_registration IS NULL AND winner_id is NULL) OR ( result_registration IS NOT NULL AND winner_id IS NOT NULL)', name='match_result_registration_winner'), - sa.CheckConstraint('( round = 0 AND position < 2) OR ( round > 0 AND position < pow(2, round))', name='match_round_position_values'), - sa.CheckConstraint('position >= 0', name='match_position_non_negative'), - sa.CheckConstraint('round >= 0', name='match_round_non_negative'), - sa.ForeignKeyConstraint(['competitor_a_id'], ['competitor.id'], ), - sa.ForeignKeyConstraint(['competitor_b_id'], ['competitor.id'], ), - sa.ForeignKeyConstraint(['loser_id'], ['competitor.id'], ), - sa.ForeignKeyConstraint(['tournament_id'], ['tournament.id'], ), - sa.ForeignKeyConstraint(['winner_id'], ['competitor.id'], ), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('tournament_id', 'round', 'position', name='match_tournament_round_position_unique'), - sa.UniqueConstraint('uuid') + op.create_table( + "match", + sa.Column("tournament_id", sa.Integer(), nullable=False), + sa.Column("round", sa.Integer(), nullable=False), + sa.Column("position", sa.Integer(), nullable=False), + sa.Column("competitor_a_id", sa.Integer(), nullable=True), + sa.Column("competitor_b_id", sa.Integer(), nullable=True), + sa.Column("result_registration", sa.DateTime(), nullable=True), + sa.Column("winner_id", sa.Integer(), nullable=True), + sa.Column("loser_id", sa.Integer(), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("uuid", sa.Uuid(), nullable=False), + sa.Column("created", sa.DateTime(), nullable=False), + sa.Column("updated", sa.DateTime(), nullable=False), + sa.CheckConstraint( + "( competitor_a_id IS NULL AND competitor_b_id IS NULL) OR ( competitor_a_id <> competitor_b_id)", + name="match_non_null_competitors_cannot_be_the_same", + ), + sa.CheckConstraint( + "( result_registration IS NULL AND loser_id is NULL) OR ( result_registration IS NOT NULL AND loser_id is NULL) OR ( result_registration IS NOT NULL AND loser_id IS NOT NULL)", + name="match_result_registration_loser", + ), + sa.CheckConstraint( + "( result_registration IS NULL AND winner_id is NULL) OR ( result_registration IS NOT NULL AND winner_id IS NOT NULL)", + name="match_result_registration_winner", + ), + sa.CheckConstraint( + "( round = 0 AND position < 2) OR ( round > 0 AND position < pow(2, round))", + name="match_round_position_values", + ), + sa.CheckConstraint("position >= 0", name="match_position_non_negative"), + sa.CheckConstraint("round >= 0", name="match_round_non_negative"), + sa.ForeignKeyConstraint( + ["competitor_a_id"], + ["competitor.id"], + ), + sa.ForeignKeyConstraint( + ["competitor_b_id"], + ["competitor.id"], + ), + sa.ForeignKeyConstraint( + ["loser_id"], + ["competitor.id"], + ), + sa.ForeignKeyConstraint( + ["tournament_id"], + ["tournament.id"], + ), + sa.ForeignKeyConstraint( + ["winner_id"], + ["competitor.id"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint( + "tournament_id", + "round", + "position", + name="match_tournament_round_position_unique", + ), + sa.UniqueConstraint("uuid"), ) - op.create_table('tournament_competitor', - sa.Column('tournament_id', sa.Integer(), nullable=False), - sa.Column('competitor_id', sa.Integer(), nullable=False), - sa.Column('next_match_id', sa.Integer(), nullable=True), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('updated', sa.DateTime(), nullable=False), - sa.ForeignKeyConstraint(['competitor_id'], ['competitor.id'], ), - sa.ForeignKeyConstraint(['next_match_id'], ['match.id'], ), - sa.ForeignKeyConstraint(['tournament_id'], ['tournament.id'], ), - sa.PrimaryKeyConstraint('tournament_id', 'competitor_id') + op.create_table( + "tournament_competitor", + sa.Column("tournament_id", sa.Integer(), nullable=False), + sa.Column("competitor_id", sa.Integer(), nullable=False), + sa.Column("next_match_id", sa.Integer(), nullable=True), + sa.Column("created", sa.DateTime(), nullable=False), + sa.Column("updated", sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint( + ["competitor_id"], + ["competitor.id"], + ), + sa.ForeignKeyConstraint( + ["next_match_id"], + ["match.id"], + ), + sa.ForeignKeyConstraint( + ["tournament_id"], + ["tournament.id"], + ), + sa.PrimaryKeyConstraint("tournament_id", "competitor_id"), ) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('tournament_competitor') - op.drop_table('match') - op.drop_table('tournament') - op.drop_table('competitor') + op.drop_table("tournament_competitor") + op.drop_table("match") + op.drop_table("tournament") + op.drop_table("competitor") # ### end Alembic commands ### diff --git a/src/matamata/VERSION b/src/matamata/VERSION index 9d2fb09..b8af7d7 100644 --- a/src/matamata/VERSION +++ b/src/matamata/VERSION @@ -1 +1 @@ -2024.1.1 \ No newline at end of file +2024.1.1 diff --git a/src/matamata/__init__.py b/src/matamata/__init__.py index b628f48..86e2e71 100644 --- a/src/matamata/__init__.py +++ b/src/matamata/__init__.py @@ -1,3 +1,3 @@ __version__ = ( - __import__('pathlib').Path(__file__).parent / 'VERSION' -).read_text().strip() + (__import__("pathlib").Path(__file__).parent / "VERSION").read_text().strip() +) diff --git a/src/matamata/database.py b/src/matamata/database.py index bb2d15a..58525ae 100644 --- a/src/matamata/database.py +++ b/src/matamata/database.py @@ -3,7 +3,6 @@ from matamata.settings import settings - engine = create_engine(settings.DATABASE_URL) diff --git a/src/matamata/main.py b/src/matamata/main.py index d3cc358..dc16a36 100644 --- a/src/matamata/main.py +++ b/src/matamata/main.py @@ -3,12 +3,9 @@ from . import __version__ as VERSION from .routers import competitor, match, tournament - app = FastAPI( - title='matamata', - summary=( - 'REST API for single-elimination tournament management' - ), + title="matamata", + summary=("REST API for single-elimination tournament management"), version=VERSION, ) diff --git a/src/matamata/models/__init__.py b/src/matamata/models/__init__.py index 6fff49e..9c813a3 100644 --- a/src/matamata/models/__init__.py +++ b/src/matamata/models/__init__.py @@ -1,5 +1,16 @@ -from .base import Base, TimestampedBase, IdUuidBase, IdUuidTimestampedBase +from .base import Base, IdUuidBase, IdUuidTimestampedBase, TimestampedBase from .competitor import Competitor from .match import Match from .tournament import Tournament from .tournament_competitor import TournamentCompetitor + +__all__ = [ + "Base", + "Competitor", + "IdUuidBase", + "IdUuidTimestampedBase", + "Match", + "TimestampedBase", + "Tournament", + "TournamentCompetitor", +] diff --git a/src/matamata/models/competitor.py b/src/matamata/models/competitor.py index 0634e07..7bcb8c9 100644 --- a/src/matamata/models/competitor.py +++ b/src/matamata/models/competitor.py @@ -12,7 +12,7 @@ @generic_repr class Competitor(IdUuidTimestampedBase): - __tablename__ = 'competitor' + __tablename__ = "competitor" __table_args__ = ( CheckConstraint( "NOT(TRIM(label) LIKE '')", @@ -23,15 +23,15 @@ class Competitor(IdUuidTimestampedBase): label: Mapped[str] = mapped_column(String(255)) tournament_associations: Mapped[list[TournamentCompetitor]] = relationship( - cascade='all, delete-orphan', - overlaps='competitor', + cascade="all, delete-orphan", + overlaps="competitor", ) - tournaments: AssociationProxy[list['Tournament']] = association_proxy( - 'tournament_associations', - 'tournament', + tournaments: AssociationProxy[list["Tournament"]] = association_proxy( # noqa: F821 + "tournament_associations", + "tournament", creator=lambda tournament_: TournamentCompetitor(tournament=tournament_), ) - next_matches: AssociationProxy[list['Match']] = association_proxy( - 'tournament_associations', - 'next_match', + next_matches: AssociationProxy[list["Match"]] = association_proxy( # noqa: F821 + "tournament_associations", + "next_match", ) diff --git a/src/matamata/models/constants.py b/src/matamata/models/constants.py index 358033f..796da55 100644 --- a/src/matamata/models/constants.py +++ b/src/matamata/models/constants.py @@ -1,10 +1,14 @@ -COMPETITOR_LABEL_CONSTRAINT = 'competitor_label_not_empty_nor_whitespace_only' -MATCH_ROUND_CONSTRAINT = 'match_round_non_negative' -MATCH_ROUND_POSITION_CONSTRAINT = 'match_round_position_values' -MATCH_POSITION_CONSTRAINT = 'match_position_non_negative' -MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT = 'match_tournament_round_position_unique' -MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME = 'match_non_null_competitors_cannot_be_the_same' -MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER = 'match_result_registration_winner' -MATCH_RESULT_REGISTRATION_MIGHT_REGISTER_A_LOSER = 'match_result_registration_loser' -TOURNAMENT_LABEL_CONSTRAINT = 'tournament_label_not_empty_nor_whitespace_only' -TOURNAMENT_START_ATTRS_CONSTRAINT = 'tournament_all_null_or_all_set_under_conditions' +COMPETITOR_LABEL_CONSTRAINT = "competitor_label_not_empty_nor_whitespace_only" +MATCH_ROUND_CONSTRAINT = "match_round_non_negative" +MATCH_ROUND_POSITION_CONSTRAINT = "match_round_position_values" +MATCH_POSITION_CONSTRAINT = "match_position_non_negative" +MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT = ( + "match_tournament_round_position_unique" +) +MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME = ( + "match_non_null_competitors_cannot_be_the_same" +) +MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER = "match_result_registration_winner" +MATCH_RESULT_REGISTRATION_MIGHT_REGISTER_A_LOSER = "match_result_registration_loser" +TOURNAMENT_LABEL_CONSTRAINT = "tournament_label_not_empty_nor_whitespace_only" +TOURNAMENT_START_ATTRS_CONSTRAINT = "tournament_all_null_or_all_set_under_conditions" diff --git a/src/matamata/models/match.py b/src/matamata/models/match.py index 0003654..4225d1b 100644 --- a/src/matamata/models/match.py +++ b/src/matamata/models/match.py @@ -7,92 +7,102 @@ from .base import IdUuidTimestampedBase from .constants import ( - MATCH_ROUND_CONSTRAINT, + MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME, MATCH_POSITION_CONSTRAINT, + MATCH_RESULT_REGISTRATION_MIGHT_REGISTER_A_LOSER, + MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER, + MATCH_ROUND_CONSTRAINT, MATCH_ROUND_POSITION_CONSTRAINT, MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT, - MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME, - MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER, - MATCH_RESULT_REGISTRATION_MIGHT_REGISTER_A_LOSER, ) from .tournament import Tournament @generic_repr class Match(IdUuidTimestampedBase): - __tablename__ = 'match' + __tablename__ = "match" __table_args__ = ( UniqueConstraint( - 'tournament_id', - 'round', - 'position', + "tournament_id", + "round", + "position", name=MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT, ), CheckConstraint( - 'round >= 0', + "round >= 0", name=MATCH_ROUND_CONSTRAINT, ), CheckConstraint( - 'position >= 0', + "position >= 0", name=MATCH_POSITION_CONSTRAINT, ), CheckConstraint( - '(' - ' round = 0' - ' AND position < 2' - ') OR (' - ' round > 0' - ' AND position < pow(2, round)' - ')', + "(" + " round = 0" + " AND position < 2" + ") OR (" + " round > 0" + " AND position < pow(2, round)" + ")", name=MATCH_ROUND_POSITION_CONSTRAINT, ), CheckConstraint( - '(' - ' competitor_a_id IS NULL' - ' AND competitor_b_id IS NULL' - ') OR (' - ' competitor_a_id <> competitor_b_id' - ')', + "(" + " competitor_a_id IS NULL" + " AND competitor_b_id IS NULL" + ") OR (" + " competitor_a_id <> competitor_b_id" + ")", name=MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME, ), CheckConstraint( - '(' - ' result_registration IS NULL' - ' AND winner_id is NULL' - ') OR (' - ' result_registration IS NOT NULL' - ' AND winner_id IS NOT NULL' - ')', + "(" + " result_registration IS NULL" + " AND winner_id is NULL" + ") OR (" + " result_registration IS NOT NULL" + " AND winner_id IS NOT NULL" + ")", name=MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER, ), CheckConstraint( - '(' - ' result_registration IS NULL' - ' AND loser_id is NULL' - ') OR (' - ' result_registration IS NOT NULL' - ' AND loser_id is NULL' - ') OR (' - ' result_registration IS NOT NULL' - ' AND loser_id IS NOT NULL' - ')', + "(" + " result_registration IS NULL" + " AND loser_id is NULL" + ") OR (" + " result_registration IS NOT NULL" + " AND loser_id is NULL" + ") OR (" + " result_registration IS NOT NULL" + " AND loser_id IS NOT NULL" + ")", name=MATCH_RESULT_REGISTRATION_MIGHT_REGISTER_A_LOSER, ), ) - tournament_id: Mapped[int] = mapped_column(ForeignKey('tournament.id')) - tournament: Mapped[Tournament] = relationship(foreign_keys='Match.tournament_id', back_populates='matches') + tournament_id: Mapped[int] = mapped_column(ForeignKey("tournament.id")) + tournament: Mapped[Tournament] = relationship( + foreign_keys="Match.tournament_id", back_populates="matches" + ) round: Mapped[int] = mapped_column() position: Mapped[int] = mapped_column() - competitor_a_id: Mapped[int | None] = mapped_column(ForeignKey('competitor.id')) - competitor_b_id: Mapped[int | None] = mapped_column(ForeignKey('competitor.id')) - competitor_a: Mapped[Optional['Competitor']] = relationship(foreign_keys='Match.competitor_a_id') - competitor_b: Mapped[Optional['Competitor']] = relationship(foreign_keys='Match.competitor_b_id') + competitor_a_id: Mapped[int | None] = mapped_column(ForeignKey("competitor.id")) + competitor_b_id: Mapped[int | None] = mapped_column(ForeignKey("competitor.id")) + competitor_a: Mapped[Optional["Competitor"]] = relationship( # noqa: F821 + foreign_keys="Match.competitor_a_id" + ) + competitor_b: Mapped[Optional["Competitor"]] = relationship( # noqa: F821 + foreign_keys="Match.competitor_b_id" + ) result_registration: Mapped[datetime | None] = mapped_column() - winner_id: Mapped[int | None] = mapped_column(ForeignKey('competitor.id')) - loser_id: Mapped[int | None] = mapped_column(ForeignKey('competitor.id')) - winner: Mapped[Optional['Competitor']] = relationship(foreign_keys='Match.winner_id') - loser: Mapped[Optional['Competitor']] = relationship(foreign_keys='Match.loser_id') + winner_id: Mapped[int | None] = mapped_column(ForeignKey("competitor.id")) + loser_id: Mapped[int | None] = mapped_column(ForeignKey("competitor.id")) + winner: Mapped[Optional["Competitor"]] = relationship( # noqa: F821 + foreign_keys="Match.winner_id" + ) + loser: Mapped[Optional["Competitor"]] = relationship( # noqa: F821 + foreign_keys="Match.loser_id" + ) diff --git a/src/matamata/models/tournament.py b/src/matamata/models/tournament.py index 16e4834..9e3ce5d 100644 --- a/src/matamata/models/tournament.py +++ b/src/matamata/models/tournament.py @@ -11,30 +11,29 @@ from .exceptions import CannotUpdateTournamentDataAfterStartError from .tournament_competitor import TournamentCompetitor - -SET_AFTER_START_ATTRS = {'matches_creation', 'number_competitors', 'starting_round'} +SET_AFTER_START_ATTRS = {"matches_creation", "number_competitors", "starting_round"} @generic_repr class Tournament(IdUuidTimestampedBase): - __tablename__ = 'tournament' + __tablename__ = "tournament" __table_args__ = ( CheckConstraint( "NOT(TRIM(label) LIKE '')", name=TOURNAMENT_LABEL_CONSTRAINT, ), CheckConstraint( - '(' - ' matches_creation IS NULL' - ' AND number_competitors IS NULL' - ' AND starting_round IS NULL' - ') OR (' - ' matches_creation IS NOT NULL' - ' AND number_competitors IS NOT NULL' - ' AND starting_round IS NOT NULL' - ' AND number_competitors >= 1' - ' AND starting_round >= 0' - ')', + "(" + " matches_creation IS NULL" + " AND number_competitors IS NULL" + " AND starting_round IS NULL" + ") OR (" + " matches_creation IS NOT NULL" + " AND number_competitors IS NOT NULL" + " AND starting_round IS NOT NULL" + " AND number_competitors >= 1" + " AND starting_round >= 0" + ")", name=TOURNAMENT_START_ATTRS_CONSTRAINT, ), ) @@ -44,25 +43,27 @@ class Tournament(IdUuidTimestampedBase): number_competitors: Mapped[int | None] = mapped_column() starting_round: Mapped[int | None] = mapped_column() - matches: Mapped[list['Match']] = relationship(back_populates='tournament') + matches: Mapped[list["Match"]] = relationship( # noqa: F821 + back_populates="tournament" + ) competitor_associations: Mapped[list[TournamentCompetitor]] = relationship( - cascade='all, delete-orphan', - overlaps='tournament', + cascade="all, delete-orphan", + overlaps="tournament", ) - competitors: AssociationProxy[list['Competitor']] = association_proxy( - 'competitor_associations', - 'competitor', + competitors: AssociationProxy[list["Competitor"]] = association_proxy( # noqa: F821 + "competitor_associations", + "competitor", creator=lambda competitor_: TournamentCompetitor(competitor=competitor_), ) # column-targeted association proxy - next_matches: AssociationProxy[list['Match']] = association_proxy( - 'competitor_associations', - 'next_match', + next_matches: AssociationProxy[list["Match"]] = association_proxy( # noqa: F821 + "competitor_associations", + "next_match", ) -@listens_for(Tournament, 'before_update') +@listens_for(Tournament, "before_update") def prevent_tournament_update_after_start(mapper, connection, target): inspected_target = inspect(target) allowed_deleted_values = [[None], tuple()] @@ -71,5 +72,5 @@ def prevent_tournament_update_after_start(mapper, connection, target): attribute = getattr(inspected_target.attrs, attribute_name) if attribute.history.deleted not in allowed_deleted_values: raise CannotUpdateTournamentDataAfterStartError( - f'{attribute_name} is not allowed to be updated after Tournament start' + f"{attribute_name} is not allowed to be updated after Tournament start" ) diff --git a/src/matamata/models/tournament_competitor.py b/src/matamata/models/tournament_competitor.py index bc112e9..da8c517 100644 --- a/src/matamata/models/tournament_competitor.py +++ b/src/matamata/models/tournament_competitor.py @@ -11,12 +11,16 @@ @generic_repr class TournamentCompetitor(TimestampedBase): - __tablename__ = 'tournament_competitor' + __tablename__ = "tournament_competitor" - tournament_id: Mapped[int] = mapped_column(ForeignKey('tournament.id'), primary_key=True) - competitor_id: Mapped[int] = mapped_column(ForeignKey('competitor.id'), primary_key=True) - next_match_id: Mapped[int | None] = mapped_column(ForeignKey('match.id')) + tournament_id: Mapped[int] = mapped_column( + ForeignKey("tournament.id"), primary_key=True + ) + competitor_id: Mapped[int] = mapped_column( + ForeignKey("competitor.id"), primary_key=True + ) + next_match_id: Mapped[int | None] = mapped_column(ForeignKey("match.id")) - tournament: Mapped['Tournament'] = relationship() - competitor: Mapped['Competitor'] = relationship() - next_match: Mapped[Optional['Match']] = relationship() + tournament: Mapped["Tournament"] = relationship() # noqa: F821 + competitor: Mapped["Competitor"] = relationship() # noqa: F821 + next_match: Mapped[Optional["Match"]] = relationship() # noqa: F821 diff --git a/src/matamata/routers/competitor.py b/src/matamata/routers/competitor.py index 924fcb4..fe414a3 100644 --- a/src/matamata/routers/competitor.py +++ b/src/matamata/routers/competitor.py @@ -13,11 +13,10 @@ CompetitorSchema, ) +router = APIRouter(prefix="/competitor", tags=["competitor"]) -router = APIRouter(prefix='/competitor', tags=['competitor']) - -@router.post('/', response_model=CompetitorSchema, status_code=201) +@router.post("/", response_model=CompetitorSchema, status_code=201) def create_competitor( competitor_payload: CompetitorPayloadSchema, session: Session = Depends(get_session), @@ -32,33 +31,32 @@ def create_competitor( return competitor -@router.get('/', response_model=CompetitorListSchema, status_code=200) +@router.get("/", response_model=CompetitorListSchema, status_code=200) def list_competitors( session: Session = Depends(get_session), ): - competitors = session.scalars( - select(Competitor) - ).all() + competitors = session.scalars(select(Competitor)).all() data = { - 'competitors': competitors, + "competitors": competitors, } return data -@router.get('/{competitor_uuid}', response_model=CompetitorDetailSchema, status_code=200) +@router.get( + "/{competitor_uuid}", response_model=CompetitorDetailSchema, status_code=200 +) def get_competitor_data( competitor_uuid: UUID, session: Session = Depends(get_session), ): competitor = session.scalar( - select(Competitor) - .where(Competitor.uuid == competitor_uuid) + select(Competitor).where(Competitor.uuid == competitor_uuid) ) if not competitor: - raise HTTPException(status_code=404, detail='Target Competitor does not exist') + raise HTTPException(status_code=404, detail="Target Competitor does not exist") base_tournament_query = ( select(Tournament) @@ -67,25 +65,16 @@ def get_competitor_data( .where(TournamentCompetitor.competitor_id == competitor.id) ) - past_tournaments_query = ( - base_tournament_query - .where( - Tournament.starting_round.is_not(None), - TournamentCompetitor.next_match_id.is_(None), - ) + past_tournaments_query = base_tournament_query.where( + Tournament.starting_round.is_not(None), + TournamentCompetitor.next_match_id.is_(None), ) - ongoing_tournaments_query = ( - base_tournament_query - .where( - Tournament.starting_round.is_not(None), - TournamentCompetitor.next_match_id.is_not(None), - ) + ongoing_tournaments_query = base_tournament_query.where( + Tournament.starting_round.is_not(None), + TournamentCompetitor.next_match_id.is_not(None), ) - upcoming_tournaments_query = ( - base_tournament_query - .where( - Tournament.starting_round.is_(None), - ) + upcoming_tournaments_query = base_tournament_query.where( + Tournament.starting_round.is_(None), ) past_tournaments = session.scalars(past_tournaments_query).all() @@ -93,12 +82,12 @@ def get_competitor_data( upcoming_tournaments = session.scalars(upcoming_tournaments_query).all() data = { - 'competitor': competitor, - 'tournaments': { - 'past': past_tournaments, - 'ongoing': ongoing_tournaments, - 'upcoming': upcoming_tournaments, - } + "competitor": competitor, + "tournaments": { + "past": past_tournaments, + "ongoing": ongoing_tournaments, + "upcoming": upcoming_tournaments, + }, } return data diff --git a/src/matamata/routers/match.py b/src/matamata/routers/match.py index 8e807fb..f7ffc36 100644 --- a/src/matamata/routers/match.py +++ b/src/matamata/routers/match.py @@ -6,10 +6,7 @@ from matamata.database import get_session from matamata.models import Match -from matamata.schemas import ( - MatchSchema, - WinnerPayloadSchema, -) +from matamata.schemas import MatchSchema, WinnerPayloadSchema from matamata.services import register_match_result as register_match_result_service from matamata.services.exceptions import ( MatchAlreadyRegisteredResult, @@ -18,11 +15,10 @@ MatchTargetCompetitorIsNotMatchCompetitor, ) - -router = APIRouter(prefix='/match', tags=['match']) +router = APIRouter(prefix="/match", tags=["match"]) -@router.get('/{match_uuid}', response_model=MatchSchema, status_code=200) +@router.get("/{match_uuid}", response_model=MatchSchema, status_code=200) def get_match_detail( match_uuid: UUID, session: Session = Depends(get_session), @@ -38,12 +34,12 @@ def get_match_detail( ) if not match: - raise HTTPException(status_code=404, detail='Target Match does not exist') + raise HTTPException(status_code=404, detail="Target Match does not exist") return match -@router.post('/{match_uuid}', response_model=MatchSchema, status_code=200) +@router.post("/{match_uuid}", response_model=MatchSchema, status_code=200) def register_match_result( match_uuid: UUID, winner_payload: WinnerPayloadSchema, @@ -60,7 +56,7 @@ def register_match_result( ) if not match: - raise HTTPException(status_code=404, detail='Target Match does not exist') + raise HTTPException(status_code=404, detail="Target Match does not exist") try: match = register_match_result_service( @@ -71,27 +67,25 @@ def register_match_result( except MatchAlreadyRegisteredResult: raise HTTPException( status_code=409, - detail='Target Match has already registered its result', + detail="Target Match has already registered its result", ) except MatchShouldHaveAutomaticWinner: raise HTTPException( status_code=409, - detail=( - 'Target Match should have elected an automatic winner' - ), + detail=("Target Match should have elected an automatic winner"), ) except MatchMissingCompetitorFromPreviousMatch: raise HTTPException( status_code=422, detail=( - 'Target Match is not ready to register a result due to' - ' registered previous Matches but missing Competitor' + "Target Match is not ready to register a result due to" + " registered previous Matches but missing Competitor" ), ) except MatchTargetCompetitorIsNotMatchCompetitor: raise HTTPException( status_code=409, - detail='Target Competitor is not a target Match competitor', + detail="Target Competitor is not a target Match competitor", ) return match diff --git a/src/matamata/routers/tournament.py b/src/matamata/routers/tournament.py index cd49083..e559dbf 100644 --- a/src/matamata/routers/tournament.py +++ b/src/matamata/routers/tournament.py @@ -21,11 +21,10 @@ ) from matamata.services import start_tournament as start_tournament_service +router = APIRouter(prefix="/tournament", tags=["tournament"]) -router = APIRouter(prefix='/tournament', tags=['tournament']) - -@router.post('/', response_model=TournamentSchema, status_code=201) +@router.post("/", response_model=TournamentSchema, status_code=201) def create_tournament( tournament_payload: TournamentPayloadSchema, session: Session = Depends(get_session), @@ -40,48 +39,48 @@ def create_tournament( return tournament -@router.get('/', response_model=TournamentListSchema, status_code=200) +@router.get("/", response_model=TournamentListSchema, status_code=200) def list_tournaments( session: Session = Depends(get_session), ): - tournaments = session.scalars( - select(Tournament) - ).all() + tournaments = session.scalars(select(Tournament)).all() data = { - 'tournaments': tournaments, + "tournaments": tournaments, } return data -@router.post('/{tournament_uuid}/competitor', response_model=TournamentCompetitorSchema, status_code=201) +@router.post( + "/{tournament_uuid}/competitor", + response_model=TournamentCompetitorSchema, + status_code=201, +) def register_competitor_in_tournament( tournament_uuid: UUID, competitor_payload: TournamentCompetitorPayloadSchema, session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") if tournament.matches_creation: raise HTTPException( status_code=409, - detail='Target Tournament has already created its matches and does not allow new Competitors registration', + detail="Target Tournament has already created its matches and does not allow new Competitors registration", ) competitor = session.scalar( - select(Competitor) - .where(Competitor.uuid == competitor_payload.competitor_uuid) + select(Competitor).where(Competitor.uuid == competitor_payload.competitor_uuid) ) if not competitor: - raise HTTPException(status_code=404, detail='Target Competitor does not exist') + raise HTTPException(status_code=404, detail="Target Competitor does not exist") tournament_competitor = TournamentCompetitor( tournament=tournament, @@ -94,7 +93,7 @@ def register_competitor_in_tournament( session.rollback() raise HTTPException( status_code=409, - detail='Target Competitor is already registered in target Tournament', + detail="Target Competitor is already registered in target Tournament", ) session.refresh(tournament_competitor) @@ -103,7 +102,7 @@ def register_competitor_in_tournament( @router.get( - '/{tournament_uuid}/competitor', + "/{tournament_uuid}/competitor", response_model=TournamentCompetitorListSchema, status_code=200, ) @@ -112,12 +111,11 @@ def list_competitors_in_tournament( session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") competitors = session.scalars( select(Competitor) @@ -129,15 +127,15 @@ def list_competitors_in_tournament( ).all() data = { - 'tournament': tournament, - 'competitors': competitors, + "tournament": tournament, + "competitors": competitors, } return data @router.get( - '/{tournament_uuid}/competitor/{competitor_uuid}', + "/{tournament_uuid}/competitor/{competitor_uuid}", response_model=TournamentCompetitorMatchesSchema, status_code=200, ) @@ -147,24 +145,21 @@ def list_matches_for_competitor_in_tournament( session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") competitor = session.scalar( - select(Competitor) - .where(Competitor.uuid == competitor_uuid) + select(Competitor).where(Competitor.uuid == competitor_uuid) ) if not competitor: - raise HTTPException(status_code=404, detail='Target Competitor does not exist') + raise HTTPException(status_code=404, detail="Target Competitor does not exist") tournament_competitor = session.scalar( - select(TournamentCompetitor) - .where( + select(TournamentCompetitor).where( TournamentCompetitor.tournament_id == tournament.id, TournamentCompetitor.competitor_id == competitor.id, ) @@ -174,18 +169,18 @@ def list_matches_for_competitor_in_tournament( if tournament.matches_creation: raise HTTPException( status_code=409, - detail='Target Competitor is not registered for started target Tournament', + detail="Target Competitor is not registered for started target Tournament", ) else: raise HTTPException( status_code=422, - detail='Target Competitor is not registered for unstarted target Tournament', + detail="Target Competitor is not registered for unstarted target Tournament", ) if not tournament.matches_creation: raise HTTPException( status_code=422, - detail='Target Tournament has not created its matches yet', + detail="Target Tournament has not created its matches yet", ) base_match_query = ( @@ -195,7 +190,7 @@ def list_matches_for_competitor_in_tournament( ( (Match.competitor_a_id == competitor.id) | (Match.competitor_b_id == competitor.id) - ) + ), ) .order_by( Match.round.desc(), @@ -204,15 +199,13 @@ def list_matches_for_competitor_in_tournament( ) bare_past_matches = session.scalars( - base_match_query - .where( + base_match_query.where( Match.result_registration.is_not(None), Match.winner_id.is_not(None), ) ).all() bare_upcoming_matches = session.scalars( - base_match_query - .where( + base_match_query.where( Match.result_registration.is_(None), Match.winner_id.is_(None), ) @@ -229,34 +222,35 @@ def list_matches_for_competitor_in_tournament( upcoming_matches.append(current_match) data = { - 'tournament': tournament, - 'competitor': competitor, - 'matches': { - 'past': past_matches, - 'upcoming': upcoming_matches, - } + "tournament": tournament, + "competitor": competitor, + "matches": { + "past": past_matches, + "upcoming": upcoming_matches, + }, } return data -@router.post('/{tournament_uuid}/start', response_model=TournamentStartSchema, status_code=201) +@router.post( + "/{tournament_uuid}/start", response_model=TournamentStartSchema, status_code=201 +) def start_tournament( tournament_uuid: UUID, session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") if tournament.matches_creation: raise HTTPException( status_code=409, - detail='Target Tournament has already created its matches', + detail="Target Tournament has already created its matches", ) # Reload Tournament this time to load eagerly its Competitors @@ -264,15 +258,16 @@ def start_tournament( select(Tournament) .where(Tournament.uuid == tournament_uuid) .options( - joinedload(Tournament.competitor_associations) - .subqueryload(TournamentCompetitor.competitor) + joinedload(Tournament.competitor_associations).subqueryload( + TournamentCompetitor.competitor + ) ) ) if not tournament.competitor_associations: raise HTTPException( status_code=422, - detail='Target Tournament does not have one Competitor registered yet', + detail="Target Tournament does not have one Competitor registered yet", ) matches = start_tournament_service( @@ -282,31 +277,32 @@ def start_tournament( ) data = { - 'tournament': tournament, - 'competitors': tournament.competitors, - 'matches': matches, + "tournament": tournament, + "competitors": tournament.competitors, + "matches": matches, } return data -@router.get('/{tournament_uuid}/match', response_model=TournamentMatchesSchema, status_code=200) +@router.get( + "/{tournament_uuid}/match", response_model=TournamentMatchesSchema, status_code=200 +) def list_tournament_matches( tournament_uuid: UUID, session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") if not tournament.matches_creation: raise HTTPException( status_code=422, - detail='Target Tournament has not created its matches yet', + detail="Target Tournament has not created its matches yet", ) base_match_query = ( @@ -318,50 +314,45 @@ def list_tournament_matches( ) ) - past_matches_query = ( - base_match_query - .where( - Match.result_registration.is_not(None), - Match.winner_id.is_not(None), - ) + past_matches_query = base_match_query.where( + Match.result_registration.is_not(None), + Match.winner_id.is_not(None), ) - upcoming_matches_query = ( - base_match_query - .where( - Match.result_registration.is_(None), - Match.winner_id.is_(None), - ) + upcoming_matches_query = base_match_query.where( + Match.result_registration.is_(None), + Match.winner_id.is_(None), ) past_matches = session.scalars(past_matches_query).all() upcoming_matches = session.scalars(upcoming_matches_query).all() data = { - 'tournament': tournament, - 'past': past_matches, - 'upcoming': upcoming_matches, + "tournament": tournament, + "past": past_matches, + "upcoming": upcoming_matches, } return data -@router.get('/{tournament_uuid}/result', response_model=TournamentResultSchema, status_code=200) +@router.get( + "/{tournament_uuid}/result", response_model=TournamentResultSchema, status_code=200 +) def get_tournament_top4( tournament_uuid: UUID, session: Session = Depends(get_session), ): tournament = session.scalar( - select(Tournament) - .where(Tournament.uuid == tournament_uuid) + select(Tournament).where(Tournament.uuid == tournament_uuid) ) if not tournament: - raise HTTPException(status_code=404, detail='Target Tournament does not exist') + raise HTTPException(status_code=404, detail="Target Tournament does not exist") if not tournament.matches_creation: raise HTTPException( status_code=422, - detail='Target Tournament has not created its matches yet', + detail="Target Tournament has not created its matches yet", ) round0_matches = session.scalars( @@ -385,13 +376,13 @@ def get_tournament_top4( if len(round0_matches) != 1: raise HTTPException( status_code=422, - detail='Target Tournament is not ready to display the top 4 competitors', + detail="Target Tournament is not ready to display the top 4 competitors", ) else: if len(round0_matches) != 2: raise HTTPException( status_code=422, - detail='Target Tournament is not ready to display the top 4 competitors', + detail="Target Tournament is not ready to display the top 4 competitors", ) top4[2] = round0_matches[1].winner top4[3] = round0_matches[1].loser @@ -400,8 +391,8 @@ def get_tournament_top4( top4[1] = round0_matches[0].loser data = { - 'tournament': tournament, - 'top4': top4, + "tournament": tournament, + "top4": top4, } return data diff --git a/src/matamata/schemas.py b/src/matamata/schemas.py index eedfe5a..c0970b9 100644 --- a/src/matamata/schemas.py +++ b/src/matamata/schemas.py @@ -11,24 +11,26 @@ def strip_string(raw: str) -> str: def non_empty_trimmed_string(trimmed: str) -> str: - if trimmed == '': - raise ValueError('must not be empty or contain only whitespace characters') + if trimmed == "": + raise ValueError("must not be empty or contain only whitespace characters") return trimmed TrimmedString = Annotated[str, AfterValidator(strip_string)] -NonEmptyTrimmedString = Annotated[TrimmedString, AfterValidator(non_empty_trimmed_string)] +NonEmptyTrimmedString = Annotated[ + TrimmedString, AfterValidator(non_empty_trimmed_string) +] def non_negative(value: int) -> int: if value < 0: - raise ValueError('must not a non-negative value') + raise ValueError("must not a non-negative value") return value def positive(value: int) -> int: if value <= 0: - raise ValueError('must not a positive value') + raise ValueError("must not a positive value") return value @@ -90,16 +92,20 @@ class TournamentCompetitorListSchema(CompetitorListSchema): class TournamentAfterStartSchema(UuidLabelSchema): - startingRound: NonNegativeInt = Field(validation_alias='starting_round') - numberCompetitors: PositiveInt = Field(validation_alias='number_competitors') + startingRound: NonNegativeInt = Field(validation_alias="starting_round") + numberCompetitors: PositiveInt = Field(validation_alias="number_competitors") class MatchForTournamentListingWithOtherCompetitor(BaseModel): uuid: UUID round: NonNegativeInt position: NonNegativeInt - competitorA: CompetitorSchema | None = Field(exclude=True, validation_alias='competitor_a') - competitorB: CompetitorSchema | None = Field(exclude=True, validation_alias='competitor_b') + competitorA: CompetitorSchema | None = Field( + exclude=True, validation_alias="competitor_a" + ) + competitorB: CompetitorSchema | None = Field( + exclude=True, validation_alias="competitor_b" + ) currentCompetitor: CompetitorSchema | None = Field(exclude=True) @computed_field @@ -124,8 +130,8 @@ class MatchSchemaForTournamentListing(BaseModel): uuid: UUID round: NonNegativeInt position: NonNegativeInt - competitorA: CompetitorSchema | None = Field(validation_alias='competitor_a') - competitorB: CompetitorSchema | None = Field(validation_alias='competitor_b') + competitorA: CompetitorSchema | None = Field(validation_alias="competitor_a") + competitorB: CompetitorSchema | None = Field(validation_alias="competitor_b") winner: CompetitorSchema | None loser: CompetitorSchema | None diff --git a/src/matamata/services/__init__.py b/src/matamata/services/__init__.py index 3ce5c6f..0f98988 100644 --- a/src/matamata/services/__init__.py +++ b/src/matamata/services/__init__.py @@ -1,2 +1,7 @@ from .register_match_result import register_match_result from .start_tournament import start_tournament + +__all__ = [ + "register_match_result", + "start_tournament", +] diff --git a/src/matamata/services/register_match_result.py b/src/matamata/services/register_match_result.py index a6e355d..d31f816 100644 --- a/src/matamata/services/register_match_result.py +++ b/src/matamata/services/register_match_result.py @@ -4,13 +4,14 @@ from sqlalchemy import Update, select, update from sqlalchemy.orm import Session +from matamata.models import Competitor, Match, TournamentCompetitor + from .exceptions import ( MatchAlreadyRegisteredResult, MatchMissingCompetitorFromPreviousMatch, MatchShouldHaveAutomaticWinner, MatchTargetCompetitorIsNotMatchCompetitor, ) -from matamata.models import Competitor, Match, TournamentCompetitor def store_competitor_data( @@ -37,8 +38,7 @@ def validate_match_to_register_result( ) -> tuple[Competitor, Competitor]: is_starting_round = ( match_with_tournament_and_competitors.round - == - match_with_tournament_and_competitors.tournament.starting_round + == match_with_tournament_and_competitors.tournament.starting_round ) competitor_uuid_set: set[UUID] = set() @@ -85,9 +85,9 @@ def get_tournament_id_and_competitor_key( tournament_id = match_with_tournament_and_competitors.tournament_id if match_with_tournament_and_competitors.position % 2 == 0: - competitor_key = 'competitor_a_id' + competitor_key = "competitor_a_id" else: - competitor_key = 'competitor_b_id' + competitor_key = "competitor_b_id" return tournament_id, competitor_key @@ -114,8 +114,8 @@ def update_winner_next_match_data( select(Match.id) .where( Match.tournament_id == tournament_id, - Match.round == winner_next_match_parameters['round'], - Match.position == winner_next_match_parameters['position'], + Match.round == winner_next_match_parameters["round"], + Match.position == winner_next_match_parameters["position"], ) .scalar_subquery() ) @@ -186,8 +186,8 @@ def adjust_third_place_match_for_loser( select(Match.id) .where( Match.tournament_id == tournament_id, - Match.round == loser_next_match_parameters['round'], - Match.position == loser_next_match_parameters['position'], + Match.round == loser_next_match_parameters["round"], + Match.position == loser_next_match_parameters["position"], ) .scalar_subquery() ) @@ -202,8 +202,8 @@ def adjust_third_place_match_for_loser( # it is an automatic winner of the next match next_match_id_value = None additional_parameters = { - 'winner_id': loser.id, - 'result_registration': datetime.utcnow(), + "winner_id": loser.id, + "result_registration": datetime.utcnow(), } update_loser_tournamentcompetitor_next_match = ( @@ -226,7 +226,8 @@ def adjust_third_place_match_for_loser( **( { competitor_key: loser.id, - } | additional_parameters + } + | additional_parameters ) ) ) @@ -261,9 +262,7 @@ def update_loser_next_match_data( update_loser_next_match_competitor = None # There will be a next match if the current match was a semifinal one - will_compete_third_place_match = ( - match_with_tournament_and_competitors.round == 1 - ) + will_compete_third_place_match = match_with_tournament_and_competitors.round == 1 if will_compete_third_place_match: ( diff --git a/src/matamata/services/start_tournament.py b/src/matamata/services/start_tournament.py index 57f09f0..c3888b0 100644 --- a/src/matamata/services/start_tournament.py +++ b/src/matamata/services/start_tournament.py @@ -7,7 +7,7 @@ from sqlalchemy.orm import Session from matamata.database import get_session -from matamata.models import Match, Tournament, TournamentCompetitor, Competitor +from matamata.models import Competitor, Match, Tournament, TournamentCompetitor def calculate_tournament_parameters(competitors: Sized) -> tuple[int, int, int]: @@ -18,17 +18,17 @@ def calculate_tournament_parameters(competitors: Sized) -> tuple[int, int, int]: number_of_entry_matches = 1 else: starting_round = int(floor(log2(number_of_competitors - 1))) - number_of_entry_matches = 2 ** starting_round + number_of_entry_matches = 2**starting_round return number_of_competitors, starting_round, number_of_entry_matches def calculate_match_index(*, starting_round, match_round, match_position): if match_round > starting_round: - raise ValueError('invalid round values combination') + raise ValueError("invalid round values combination") if match_position >= 2**match_round: - raise ValueError('invalid round/position values combination') + raise ValueError("invalid round/position values combination") offset = 0 for current_round in range(starting_round, match_round, -1): @@ -47,9 +47,7 @@ def process_automatic_winning( number_of_competitors, starting_round, number_of_entry_matches, - ) = calculate_tournament_parameters( - map_competitor_next_match_index - ) + ) = calculate_tournament_parameters(map_competitor_next_match_index) if number_of_competitors // 2 == number_of_entry_matches: # No automatic winning @@ -57,13 +55,13 @@ def process_automatic_winning( for match_index in range(number_of_entry_matches): current_match = match_data[match_index] - if 'competitor_b' in current_match: + if "competitor_b" in current_match: continue # automatic winning found - competitor = current_match['competitor_a'] + competitor = current_match["competitor_a"] current_match |= { - 'result_registration': datetime.utcnow(), - 'winner': competitor, + "result_registration": datetime.utcnow(), + "winner": competitor, } # need to set competitor as next match competitor @@ -82,7 +80,9 @@ def process_automatic_winning( ) next_match_data = match_data[next_match_index_in_match_data] - next_match_key_name = 'competitor_a' if next_match_competitor_index == 0 else 'competitor_b' + next_match_key_name = ( + "competitor_a" if next_match_competitor_index == 0 else "competitor_b" + ) next_match_data[next_match_key_name] = competitor map_competitor_next_match_index[competitor] = next_match_index_in_match_data @@ -97,9 +97,9 @@ def prepare_match_data_as_list_of_dict( # We populate entry matches, then intermediate matches and final and third place matches last match_data = [ { - 'tournament_id': tournament.id, - 'round': round_, - 'position': position, + "tournament_id": tournament.id, + "round": round_, + "position": position, } for round_ in range(starting_round, -1, -1) for position in range(2**round_) @@ -107,7 +107,7 @@ def prepare_match_data_as_list_of_dict( if number_of_competitors > 2: # The only match that doesn't follow the previous rule is the third place match - match_data.append({'round': 0, 'position': 1}) + match_data.append({"round": 0, "position": 1}) return match_data @@ -135,7 +135,7 @@ def inline_random_pair_of_entry_match_competitors( for index, competitor in enumerate(shuffled_competitors): competitor_index, match_index = divmod(index, number_of_entry_matches) - key_name = 'competitor_a' if competitor_index == 0 else 'competitor_b' + key_name = "competitor_a" if competitor_index == 0 else "competitor_b" match_data[match_index][key_name] = competitor map_competitor_next_match_index[competitor] = match_index @@ -148,10 +148,7 @@ def insert_and_refresh_match_data_as_match_instances( starting_round: int, session: Session, ) -> list[Match]: - new_matches = [ - Match(**current_match_data) - for current_match_data in match_data - ] + new_matches = [Match(**current_match_data) for current_match_data in match_data] tournament.matches.extend(new_matches) tournament.matches_creation = datetime.utcnow() tournament.number_competitors = number_of_competitors @@ -191,8 +188,7 @@ def start_tournament( raise ValueError("No competitors to start tournament") map_competitor_association = { - association.competitor: association - for association in competitor_associations + association.competitor: association for association in competitor_associations } map_competitor_next_match_index: dict[Competitor, int | None] = {} @@ -209,7 +205,7 @@ def start_tournament( starting_round=starting_round, number_of_competitors=number_of_competitors, ) - + inline_random_pair_of_entry_match_competitors( competitors=map_competitor_association, number_of_entry_matches=number_of_entry_matches, diff --git a/src/matamata/settings.py b/src/matamata/settings.py index a9e01b7..80aeaaf 100644 --- a/src/matamata/settings.py +++ b/src/matamata/settings.py @@ -2,9 +2,7 @@ class Settings(BaseSettings): - model_config = SettingsConfigDict( - env_file='.env', env_file_encoding='utf-8' - ) + model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8") DATABASE_URL: str diff --git a/tests/models/factories.py b/tests/models/factories.py index ca28b27..82c70b6 100644 --- a/tests/models/factories.py +++ b/tests/models/factories.py @@ -14,14 +14,14 @@ class CompetitorFactory(TimestampedFactory): class Meta: model = Competitor - label = factory.Faker('name') + label = factory.Faker("name") class TournamentFactory(TimestampedFactory): class Meta: model = Tournament - label = factory.Faker('company') + label = factory.Faker("company") matches_creation = None number_competitors = None starting_round = None diff --git a/tests/models/test_competitor.py b/tests/models/test_competitor.py index dfb1c7b..a7ecfaf 100644 --- a/tests/models/test_competitor.py +++ b/tests/models/test_competitor.py @@ -11,26 +11,25 @@ def test_create_and_retrieve_competitor(session): before_new_competitor = datetime.utcnow() new_competitor = Competitor( - label='South Korea', + label="South Korea", ) session.add(new_competitor) session.commit() competitor_ = session.scalar( - select(Competitor) - .where( - Competitor.label == 'South Korea', + select(Competitor).where( + Competitor.label == "South Korea", ) ) - assert competitor_.label == 'South Korea' + assert competitor_.label == "South Korea" assert competitor_.created > before_new_competitor assert competitor_.updated > competitor_.created def test_cannot_create_competitor_with_empty_label(session): empty_label_competitor = Competitor( - label='', # empty + label="", # empty ) session.add(empty_label_competitor) with pytest.raises( @@ -42,7 +41,7 @@ def test_cannot_create_competitor_with_empty_label(session): def test_cannot_create_competitor_with_whitespace_only_label(session): whitespace_label_competitor = Competitor( - label=' ', # whitespaces + label=" ", # whitespaces ) session.add(whitespace_label_competitor) with pytest.raises( @@ -54,24 +53,24 @@ def test_cannot_create_competitor_with_whitespace_only_label(session): def test_can_create_duplicate_competitor(session): first_competitor = Competitor( - label='Brazil', + label="Brazil", ) session.add(first_competitor) session.commit() session.refresh(first_competitor) second_competitor = Competitor( - label='Brazil', + label="Brazil", ) session.add(second_competitor) session.commit() session.refresh(second_competitor) count = session.scalar( - select(func.count('*')) + select(func.count("*")) .select_from(Competitor) .where( - Competitor.label == 'Brazil', + Competitor.label == "Brazil", ) ) diff --git a/tests/models/test_match.py b/tests/models/test_match.py index 70ae4a0..f6724d0 100644 --- a/tests/models/test_match.py +++ b/tests/models/test_match.py @@ -5,16 +5,14 @@ from matamata.models import Match from matamata.models.constants import ( - MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT, - MATCH_ROUND_CONSTRAINT, - MATCH_POSITION_CONSTRAINT, - MATCH_ROUND_POSITION_CONSTRAINT, MATCH_NON_NULL_COMPETITORS_CANNOT_BE_THE_SAME, + MATCH_POSITION_CONSTRAINT, MATCH_RESULT_REGISTRATION_MUST_REGISTER_A_WINNER, + MATCH_ROUND_CONSTRAINT, + MATCH_ROUND_POSITION_CONSTRAINT, + MATCH_TOURNAMENT_ROUND_POSITION_UNIQUE_CONSTRAINT, ) -from tests.utils import ( - retrieve_match_with_competitors_by_tournament_round_position, -) +from tests.utils import retrieve_match_with_competitors_by_tournament_round_position def test_create_and_retrieve_match(session, tournament, competitor1, competitor2): @@ -75,7 +73,9 @@ def test_cannot_create_duplicate_match(session, tournament, competitor1, competi session.commit() -def test_match_round_must_be_non_negative(session, tournament, competitor1, competitor2): +def test_match_round_must_be_non_negative( + session, tournament, competitor1, competitor2 +): match = Match( tournament_id=tournament.id, round=-1, @@ -92,7 +92,9 @@ def test_match_round_must_be_non_negative(session, tournament, competitor1, comp session.commit() -def test_match_position_must_be_non_negative(session, tournament, competitor1, competitor2): +def test_match_position_must_be_non_negative( + session, tournament, competitor1, competitor2 +): match = Match( tournament_id=tournament.id, round=0, @@ -109,7 +111,9 @@ def test_match_position_must_be_non_negative(session, tournament, competitor1, c session.commit() -def test_match_position_cannot_be_greater_or_equal_round_power_2(session, tournament, competitor1, competitor2): +def test_match_position_cannot_be_greater_or_equal_round_power_2( + session, tournament, competitor1, competitor2 +): match = Match( tournament_id=tournament.id, round=1, @@ -180,7 +184,9 @@ def test_match_resultregistration_must_register_winner(session, tournament, comp session.commit() -def test_tournament_can_access_matches(session, tournament, competitor, competitor1, competitor2): +def test_tournament_can_access_matches( + session, tournament, competitor, competitor1, competitor2 +): final_match = Match( tournament_id=tournament.id, round=0, diff --git a/tests/models/test_tournament.py b/tests/models/test_tournament.py index a94c5cd..58aa0ed 100644 --- a/tests/models/test_tournament.py +++ b/tests/models/test_tournament.py @@ -5,26 +5,28 @@ from sqlalchemy.exc import IntegrityError from matamata.models import Tournament -from matamata.models.constants import TOURNAMENT_LABEL_CONSTRAINT, TOURNAMENT_START_ATTRS_CONSTRAINT +from matamata.models.constants import ( + TOURNAMENT_LABEL_CONSTRAINT, + TOURNAMENT_START_ATTRS_CONSTRAINT, +) from matamata.models.exceptions import CannotUpdateTournamentDataAfterStartError def test_create_and_retrieve_tournament(session): before_new_tournament = datetime.utcnow() new_tournament = Tournament( - label='2022 FIFA World Cup', + label="2022 FIFA World Cup", ) session.add(new_tournament) session.commit() tournament_ = session.scalar( - select(Tournament) - .where( - Tournament.label == '2022 FIFA World Cup', + select(Tournament).where( + Tournament.label == "2022 FIFA World Cup", ) ) - assert tournament_.label == '2022 FIFA World Cup' + assert tournament_.label == "2022 FIFA World Cup" assert tournament_.created > before_new_tournament assert tournament_.updated > tournament_.created assert tournament_.matches_creation is None @@ -34,7 +36,7 @@ def test_create_and_retrieve_tournament(session): def test_cannot_create_tournament_with_empty_label(session): empty_label_tournament = Tournament( - label='', # empty + label="", # empty ) session.add(empty_label_tournament) with pytest.raises( @@ -46,7 +48,7 @@ def test_cannot_create_tournament_with_empty_label(session): def test_cannot_create_tournament_with_whitespace_only_label(session): whitespace_label_tournament = Tournament( - label=' ', # whitespaces + label=" ", # whitespaces ) session.add(whitespace_label_tournament) with pytest.raises( @@ -58,33 +60,35 @@ def test_cannot_create_tournament_with_whitespace_only_label(session): def test_can_create_duplicate_tournament(session): first_tournament = Tournament( - label='2022 FIFA World Cup', + label="2022 FIFA World Cup", ) session.add(first_tournament) session.commit() session.refresh(first_tournament) second_tournament = Tournament( - label='2022 FIFA World Cup', + label="2022 FIFA World Cup", ) session.add(second_tournament) session.commit() session.refresh(second_tournament) count = session.scalar( - select(func.count('*')) + select(func.count("*")) .select_from(Tournament) .where( - Tournament.label == '2022 FIFA World Cup', + Tournament.label == "2022 FIFA World Cup", ) ) assert count == 2 -def test_tournament_matches_creation_must_be_non_null_with_positive_number_competitors(session): +def test_tournament_matches_creation_must_be_non_null_with_positive_number_competitors( + session, +): tournament_ = Tournament( - label='2022 FIFA World Cup', + label="2022 FIFA World Cup", ) session.add(tournament_) session.commit() @@ -124,7 +128,7 @@ def test_tournament_matches_creation_must_be_non_null_with_positive_number_compe def test_tournament_does_not_allow_changing_attrs_after_start(session): tournament_ = Tournament( - label='2022 FIFA World Cup', + label="2022 FIFA World Cup", ) session.add(tournament_) session.commit() @@ -143,7 +147,7 @@ def test_tournament_does_not_allow_changing_attrs_after_start(session): session.add(tournament_) with pytest.raises( CannotUpdateTournamentDataAfterStartError, - match='matches_creation is not allowed to be updated after Tournament start', + match="matches_creation is not allowed to be updated after Tournament start", ): session.commit() session.rollback() @@ -154,7 +158,7 @@ def test_tournament_does_not_allow_changing_attrs_after_start(session): session.add(tournament_) with pytest.raises( CannotUpdateTournamentDataAfterStartError, - match='number_competitors is not allowed to be updated after Tournament start', + match="number_competitors is not allowed to be updated after Tournament start", ): session.commit() session.rollback() @@ -165,7 +169,7 @@ def test_tournament_does_not_allow_changing_attrs_after_start(session): session.add(tournament_) with pytest.raises( CannotUpdateTournamentDataAfterStartError, - match='starting_round is not allowed to be updated after Tournament start', + match="starting_round is not allowed to be updated after Tournament start", ): session.commit() session.rollback() diff --git a/tests/models/test_tournament_competitor.py b/tests/models/test_tournament_competitor.py index 35fe649..30e2154 100644 --- a/tests/models/test_tournament_competitor.py +++ b/tests/models/test_tournament_competitor.py @@ -18,8 +18,7 @@ def test_create_and_retrieve_tournamentcompetitor(session, competitor, tournamen session.commit() tournament_competitor = session.scalar( - select(TournamentCompetitor) - .where( + select(TournamentCompetitor).where( TournamentCompetitor.tournament == tournament, ) ) @@ -51,14 +50,16 @@ def test_cannot_create_duplicate_tournament_competitor(session, competitor, tour session.commit() -def test_tournament_can_access_competitors(session, tournament, competitor1, competitor2): +def test_tournament_can_access_competitors( + session, tournament, competitor1, competitor2 +): tournament.competitors.append(competitor1) tournament.competitors.append(competitor2) session.commit() session.refresh(tournament) count = session.scalar( - select(func.count('*')) + select(func.count("*")) .select_from(TournamentCompetitor) .where( TournamentCompetitor.tournament == tournament, @@ -70,14 +71,16 @@ def test_tournament_can_access_competitors(session, tournament, competitor1, com assert tournament.competitors == [competitor1, competitor2] -def test_competitor_can_access_tournaments(session, competitor, tournament1, tournament2): +def test_competitor_can_access_tournaments( + session, competitor, tournament1, tournament2 +): competitor.tournaments.append(tournament1) competitor.tournaments.append(tournament2) session.commit() session.refresh(competitor) count = session.scalar( - select(func.count('*')) + select(func.count("*")) .select_from(TournamentCompetitor) .where( TournamentCompetitor.competitor == competitor, diff --git a/tests/routers/test_competitor.py b/tests/routers/test_competitor.py index de6d328..4c2d207 100644 --- a/tests/routers/test_competitor.py +++ b/tests/routers/test_competitor.py @@ -1,37 +1,44 @@ from tests.utils import start_tournament_util - -BASE_URL = '/competitor' +BASE_URL = "/competitor" def test_create_competitor(client): response = client.post( BASE_URL, json={ - 'label': '\t\nSouth Korea\n ', + "label": "\t\nSouth Korea\n ", }, ) response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - response_uuid = response_json['uuid'] + response_uuid = response_json["uuid"] assert response.status_code == 201 assert response.json() == { - 'uuid': response_uuid, - 'label': 'South Korea', + "uuid": response_uuid, + "label": "South Korea", } -def test_list_competitors(client, competitor1, competitor2, competitor3, competitor4, competitor5): +def test_list_competitors( + client, competitor1, competitor2, competitor3, competitor4, competitor5 +): expected_data = { - 'competitors': [ + "competitors": [ { - 'uuid': str(competitor_.uuid), - 'label': competitor_.label, + "uuid": str(competitor_.uuid), + "label": competitor_.label, } - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5] + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ] ], } @@ -43,11 +50,17 @@ def test_list_competitors(client, competitor1, competitor2, competitor3, competi assert response.json() == expected_data -GET_COMPETITOR_DETAIL_URL_TEMPLATE = BASE_URL + '/{competitor_uuid}' +GET_COMPETITOR_DETAIL_URL_TEMPLATE = BASE_URL + "/{competitor_uuid}" def test_200_get_competitor_detail_for_competitor_in_past_ongoing_upcoming_tournaments( - session, client, competitor1, competitor2, tournament1, tournament2, tournament3, + session, + client, + competitor1, + competitor2, + tournament1, + tournament2, + tournament3, ): # past competitor1.tournaments.append(tournament1) @@ -85,30 +98,30 @@ def test_200_get_competitor_detail_for_competitor_in_past_ongoing_upcoming_tourn assert response.status_code == 200 assert response.json() == { - 'competitor': { - 'uuid': str(competitor1.uuid), - 'label': competitor1.label, + "competitor": { + "uuid": str(competitor1.uuid), + "label": competitor1.label, }, - 'tournaments': { - 'past': [ + "tournaments": { + "past": [ { - 'uuid': str(tournament1.uuid), - 'label': tournament1.label, + "uuid": str(tournament1.uuid), + "label": tournament1.label, }, ], - 'ongoing': [ + "ongoing": [ { - 'uuid': str(tournament2.uuid), - 'label': tournament2.label, + "uuid": str(tournament2.uuid), + "label": tournament2.label, }, ], - 'upcoming': [ + "upcoming": [ { - 'uuid': str(tournament3.uuid), - 'label': tournament3.label, + "uuid": str(tournament3.uuid), + "label": tournament3.label, }, ], - } + }, } @@ -119,19 +132,21 @@ def test_200_get_competitor_detail_for_competitor_in_no_tournament(client, compe assert response.status_code == 200 assert response.json() == { - 'competitor': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitor": { + "uuid": str(competitor.uuid), + "label": competitor.label, + }, + "tournaments": { + "past": [], + "ongoing": [], + "upcoming": [], }, - 'tournaments': { - 'past': [], - 'ongoing': [], - 'upcoming': [], - } } -def test_200_get_competitor_detail_for_competitor_in_a_past_tournament(session, client, competitor, tournament): +def test_200_get_competitor_detail_for_competitor_in_a_past_tournament( + session, client, competitor, tournament +): competitor.tournaments.append(tournament) session.add(competitor) session.commit() @@ -148,24 +163,26 @@ def test_200_get_competitor_detail_for_competitor_in_a_past_tournament(session, assert response.status_code == 200 assert response.json() == { - 'competitor': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitor": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'tournaments': { - 'past': [ + "tournaments": { + "past": [ { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "uuid": str(tournament.uuid), + "label": tournament.label, }, ], - 'ongoing': [], - 'upcoming': [], - } + "ongoing": [], + "upcoming": [], + }, } -def test_200_get_competitor_detail_for_competitor_in_an_ongoing_tournament(session, client, competitor1, competitor2, tournament): +def test_200_get_competitor_detail_for_competitor_in_an_ongoing_tournament( + session, client, competitor1, competitor2, tournament +): tournament.competitors.append(competitor1) tournament.competitors.append(competitor2) session.add(tournament) @@ -185,24 +202,26 @@ def test_200_get_competitor_detail_for_competitor_in_an_ongoing_tournament(sessi assert response.status_code == 200 assert response.json() == { - 'competitor': { - 'uuid': str(competitor2.uuid), - 'label': competitor2.label, + "competitor": { + "uuid": str(competitor2.uuid), + "label": competitor2.label, }, - 'tournaments': { - 'past': [], - 'ongoing': [ + "tournaments": { + "past": [], + "ongoing": [ { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "uuid": str(tournament.uuid), + "label": tournament.label, }, ], - 'upcoming': [], - } + "upcoming": [], + }, } -def test_200_get_competitor_detail_for_competitor_in_an_unstarted_tournament(session, client, competitor, tournament): +def test_200_get_competitor_detail_for_competitor_in_an_unstarted_tournament( + session, client, competitor, tournament +): competitor.tournaments.append(tournament) session.add(competitor) session.commit() @@ -214,31 +233,31 @@ def test_200_get_competitor_detail_for_competitor_in_an_unstarted_tournament(ses assert response.status_code == 200 assert response.json() == { - 'competitor': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitor": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'tournaments': { - 'past': [], - 'ongoing': [], - 'upcoming': [ + "tournaments": { + "past": [], + "ongoing": [], + "upcoming": [ { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "uuid": str(tournament.uuid), + "label": tournament.label, }, ], - } + }, } def test_404_for_missing_competitor_during_get_competitor_detail(client): response = client.get( GET_COMPETITOR_DETAIL_URL_TEMPLATE.format( - competitor_uuid='01234567-89ab-cdef-0123-456789abcdef', + competitor_uuid="01234567-89ab-cdef-0123-456789abcdef", ) ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Competitor does not exist', + "detail": "Target Competitor does not exist", } diff --git a/tests/routers/test_match.py b/tests/routers/test_match.py index a36047f..e897558 100644 --- a/tests/routers/test_match.py +++ b/tests/routers/test_match.py @@ -1,20 +1,20 @@ from datetime import datetime from matamata.models import Match -from tests.utils import ( - retrieve_tournament_competitor, - start_tournament_util, -) +from tests.utils import retrieve_tournament_competitor, start_tournament_util +BASE_URL = "/match" -BASE_URL = '/match' - -GET_MATCH_DETAIL_URL_TEMPLATE = BASE_URL + '/{match_uuid}' -REGISTER_MATCH_RESULT_URL_TEMPLATE = BASE_URL + '/{match_uuid}' +GET_MATCH_DETAIL_URL_TEMPLATE = BASE_URL + "/{match_uuid}" +REGISTER_MATCH_RESULT_URL_TEMPLATE = BASE_URL + "/{match_uuid}" def test_200_for_get_match_detail_with_result_not_registered_yet( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): for competitor_ in [competitor1, competitor2]: tournament.competitors.append(competitor_) @@ -44,30 +44,33 @@ def test_200_for_get_match_detail_with_result_not_registered_yet( assert response.status_code == 200 assert response.json() == { - 'uuid': str(final.uuid), - 'round': 0, - 'position': 0, - 'competitorA': { - 'uuid': str(final.competitor_a.uuid), - 'label': final.competitor_a.label, - }, - 'competitorB': { - 'uuid': str(final.competitor_b.uuid), - 'label': final.competitor_b.label, - }, - 'winner': None, - 'loser': None, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(final.uuid), + "round": 0, + "position": 0, + "competitorA": { + "uuid": str(final.competitor_a.uuid), + "label": final.competitor_a.label, + }, + "competitorB": { + "uuid": str(final.competitor_b.uuid), + "label": final.competitor_b.label, + }, + "winner": None, + "loser": None, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } def test_200_for_get_match_detail_with_result_registered_with_one_competitor_only( - session, client, tournament, competitor, + session, + client, + tournament, + competitor, ): tournament.competitors.append(competitor) session.add(tournament) @@ -96,24 +99,24 @@ def test_200_for_get_match_detail_with_result_registered_with_one_competitor_onl assert response.status_code == 200 assert response.json() == { - 'uuid': str(final.uuid), - 'round': 0, - 'position': 0, - 'competitorA': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, - }, - 'competitorB': None, - 'winner': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, - }, - 'loser': None, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(final.uuid), + "round": 0, + "position": 0, + "competitorA": { + "uuid": str(competitor.uuid), + "label": competitor.label, + }, + "competitorB": None, + "winner": { + "uuid": str(competitor.uuid), + "label": competitor.label, + }, + "loser": None, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } @@ -121,18 +124,22 @@ def test_200_for_get_match_detail_with_result_registered_with_one_competitor_onl def test_404_for_missing_match_during_get_match_detail(client, competitor): response = client.get( GET_MATCH_DETAIL_URL_TEMPLATE.format( - match_uuid='01234567-89ab-cdef-0123-456789abcdef', + match_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Match does not exist', + "detail": "Target Match does not exist", } def test_200_for_register_match_result_for_final_match( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): for competitor_ in [competitor1, competitor2]: tournament.competitors.append(competitor_) @@ -174,36 +181,36 @@ def test_200_for_register_match_result_for_final_match( response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=final.uuid), json={ - 'winner_uuid': str(final.competitor_b.uuid), + "winner_uuid": str(final.competitor_b.uuid), }, ) assert response.status_code == 200 assert response.json() == { - 'uuid': str(final.uuid), - 'round': 0, - 'position': 0, - 'competitorA': { - 'uuid': str(final.competitor_a.uuid), - 'label': final.competitor_a.label, - }, - 'competitorB': { - 'uuid': str(final.competitor_b.uuid), - 'label': final.competitor_b.label, - }, - 'winner': { - 'uuid': str(final.competitor_b.uuid), - 'label': final.competitor_b.label, - }, - 'loser': { - 'uuid': str(final.competitor_a.uuid), - 'label': final.competitor_a.label, - }, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(final.uuid), + "round": 0, + "position": 0, + "competitorA": { + "uuid": str(final.competitor_a.uuid), + "label": final.competitor_a.label, + }, + "competitorB": { + "uuid": str(final.competitor_b.uuid), + "label": final.competitor_b.label, + }, + "winner": { + "uuid": str(final.competitor_b.uuid), + "label": final.competitor_b.label, + }, + "loser": { + "uuid": str(final.competitor_a.uuid), + "label": final.competitor_a.label, + }, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } @@ -216,7 +223,12 @@ def test_200_for_register_match_result_for_final_match( def test_200_for_register_match_result_for_semifinal_match_for_three_competitors( - session, client, tournament, competitor1, competitor2, competitor3, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, ): for competitor_ in [competitor1, competitor2, competitor3]: tournament.competitors.append(competitor_) @@ -271,36 +283,36 @@ def test_200_for_register_match_result_for_semifinal_match_for_three_competitors response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=semifinal_r1p0.uuid), json={ - 'winner_uuid': str(semifinal_r1p0.competitor_b.uuid), + "winner_uuid": str(semifinal_r1p0.competitor_b.uuid), }, ) assert response.status_code == 200 assert response.json() == { - 'uuid': str(semifinal_r1p0.uuid), - 'round': 1, - 'position': 0, - 'competitorA': { - 'uuid': str(semifinal_r1p0.competitor_a.uuid), - 'label': semifinal_r1p0.competitor_a.label, - }, - 'competitorB': { - 'uuid': str(semifinal_r1p0.competitor_b.uuid), - 'label': semifinal_r1p0.competitor_b.label, - }, - 'winner': { - 'uuid': str(semifinal_r1p0.competitor_b.uuid), - 'label': semifinal_r1p0.competitor_b.label, - }, - 'loser': { - 'uuid': str(semifinal_r1p0.competitor_a.uuid), - 'label': semifinal_r1p0.competitor_a.label, - }, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(semifinal_r1p0.uuid), + "round": 1, + "position": 0, + "competitorA": { + "uuid": str(semifinal_r1p0.competitor_a.uuid), + "label": semifinal_r1p0.competitor_a.label, + }, + "competitorB": { + "uuid": str(semifinal_r1p0.competitor_b.uuid), + "label": semifinal_r1p0.competitor_b.label, + }, + "winner": { + "uuid": str(semifinal_r1p0.competitor_b.uuid), + "label": semifinal_r1p0.competitor_b.label, + }, + "loser": { + "uuid": str(semifinal_r1p0.competitor_a.uuid), + "label": semifinal_r1p0.competitor_a.label, + }, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } @@ -319,9 +331,22 @@ def test_200_for_register_match_result_for_semifinal_match_for_three_competitors def test_200_for_register_match_result_for_round_1_match( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -371,36 +396,36 @@ def test_200_for_register_match_result_for_round_1_match( response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=semifinal_r1p1.uuid), json={ - 'winner_uuid': str(semifinal_r1p1.competitor_a.uuid), + "winner_uuid": str(semifinal_r1p1.competitor_a.uuid), }, ) assert response.status_code == 200 assert response.json() == { - 'uuid': str(semifinal_r1p1.uuid), - 'round': 1, - 'position': 1, - 'competitorA': { - 'uuid': str(semifinal_r1p1.competitor_a.uuid), - 'label': semifinal_r1p1.competitor_a.label, - }, - 'competitorB': { - 'uuid': str(semifinal_r1p1.competitor_b.uuid), - 'label': semifinal_r1p1.competitor_b.label, - }, - 'winner': { - 'uuid': str(semifinal_r1p1.competitor_a.uuid), - 'label': semifinal_r1p1.competitor_a.label, - }, - 'loser': { - 'uuid': str(semifinal_r1p1.competitor_b.uuid), - 'label': semifinal_r1p1.competitor_b.label, - }, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(semifinal_r1p1.uuid), + "round": 1, + "position": 1, + "competitorA": { + "uuid": str(semifinal_r1p1.competitor_a.uuid), + "label": semifinal_r1p1.competitor_a.label, + }, + "competitorB": { + "uuid": str(semifinal_r1p1.competitor_b.uuid), + "label": semifinal_r1p1.competitor_b.label, + }, + "winner": { + "uuid": str(semifinal_r1p1.competitor_a.uuid), + "label": semifinal_r1p1.competitor_a.label, + }, + "loser": { + "uuid": str(semifinal_r1p1.competitor_b.uuid), + "label": semifinal_r1p1.competitor_b.label, + }, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } @@ -417,9 +442,22 @@ def test_200_for_register_match_result_for_round_1_match( def test_200_for_register_match_result_for_round_greater_than_1_entry_match( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -464,36 +502,36 @@ def test_200_for_register_match_result_for_round_greater_than_1_entry_match( response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=entry_match.uuid), json={ - 'winner_uuid': str(entry_match.competitor_a.uuid), + "winner_uuid": str(entry_match.competitor_a.uuid), }, ) assert response.status_code == 200 assert response.json() == { - 'uuid': str(entry_match.uuid), - 'round': 2, - 'position': 0, - 'competitorA': { - 'uuid': str(entry_match.competitor_a.uuid), - 'label': entry_match.competitor_a.label, - }, - 'competitorB': { - 'uuid': str(entry_match.competitor_b.uuid), - 'label': entry_match.competitor_b.label, - }, - 'winner': { - 'uuid': str(entry_match.competitor_a.uuid), - 'label': entry_match.competitor_a.label, - }, - 'loser': { - 'uuid': str(entry_match.competitor_b.uuid), - 'label': entry_match.competitor_b.label, - }, - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'numberCompetitors': tournament.number_competitors, - 'startingRound': tournament.starting_round, + "uuid": str(entry_match.uuid), + "round": 2, + "position": 0, + "competitorA": { + "uuid": str(entry_match.competitor_a.uuid), + "label": entry_match.competitor_a.label, + }, + "competitorB": { + "uuid": str(entry_match.competitor_b.uuid), + "label": entry_match.competitor_b.label, + }, + "winner": { + "uuid": str(entry_match.competitor_a.uuid), + "label": entry_match.competitor_a.label, + }, + "loser": { + "uuid": str(entry_match.competitor_b.uuid), + "label": entry_match.competitor_b.label, + }, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "numberCompetitors": tournament.number_competitors, + "startingRound": tournament.starting_round, }, } @@ -511,20 +549,22 @@ def test_200_for_register_match_result_for_round_greater_than_1_entry_match( def test_404_for_missing_match_during_register_match_result(client, competitor): response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format( - match_uuid='01234567-89ab-cdef-0123-456789abcdef', + match_uuid="01234567-89ab-cdef-0123-456789abcdef", ), json={ - 'winner_uuid': str(competitor.uuid), + "winner_uuid": str(competitor.uuid), }, ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Match does not exist', + "detail": "Target Match does not exist", } -def test_409_for_match_with_registered_result_during_register_match_result(client, session, tournament, competitor): +def test_409_for_match_with_registered_result_during_register_match_result( + client, session, tournament, competitor +): tournament.matchesCreation = datetime(year=2024, month=1, day=1) tournament.numberCompetitors = 1 tournament.startingRound = 0 @@ -545,17 +585,19 @@ def test_409_for_match_with_registered_result_during_register_match_result(clien response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=final_match.uuid), json={ - 'winner_uuid': str(competitor.uuid), + "winner_uuid": str(competitor.uuid), }, ) assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Match has already registered its result', + "detail": "Target Match has already registered its result", } -def test_409_for_match_that_should_have_automatic_winner_during_register_match_result(client, session, tournament, competitor): +def test_409_for_match_that_should_have_automatic_winner_during_register_match_result( + client, session, tournament, competitor +): tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 1 tournament.starting_round = 0 @@ -574,17 +616,19 @@ def test_409_for_match_that_should_have_automatic_winner_during_register_match_r response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=final_match.uuid), json={ - 'winner_uuid': str(competitor.uuid), + "winner_uuid": str(competitor.uuid), }, ) assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Match should have elected an automatic winner', + "detail": "Target Match should have elected an automatic winner", } -def test_422_for_missing_competitor_during_register_match_result(client, session, tournament, competitor1, competitor2, competitor3): +def test_422_for_missing_competitor_during_register_match_result( + client, session, tournament, competitor1, competitor2, competitor3 +): tournament.matchesCreation = datetime(year=2024, month=1, day=1) tournament.numberCompetitors = 3 tournament.startingRound = 1 @@ -603,20 +647,22 @@ def test_422_for_missing_competitor_during_register_match_result(client, session response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=final_match.uuid), json={ - 'winner_uuid': str(competitor3.uuid), + "winner_uuid": str(competitor3.uuid), }, ) assert response.status_code == 422 assert response.json() == { - 'detail': ( - 'Target Match is not ready to register a result due to' - ' registered previous Matches but missing Competitor' + "detail": ( + "Target Match is not ready to register a result due to" + " registered previous Matches but missing Competitor" ) } -def test_409_for_competitor_not_match_competitor_during_register_match_result(client, session, tournament, competitor1, competitor2, competitor3): +def test_409_for_competitor_not_match_competitor_during_register_match_result( + client, session, tournament, competitor1, competitor2, competitor3 +): tournament.matchesCreation = datetime(year=2024, month=1, day=1) tournament.numberCompetitors = 3 tournament.startingRound = 1 @@ -637,11 +683,11 @@ def test_409_for_competitor_not_match_competitor_during_register_match_result(cl response = client.post( REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=final_match.uuid), json={ - 'winner_uuid': str(competitor3.uuid), + "winner_uuid": str(competitor3.uuid), }, ) assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Competitor is not a target Match competitor', + "detail": "Target Competitor is not a target Match competitor", } diff --git a/tests/routers/test_tournament.py b/tests/routers/test_tournament.py index ea57fbc..99c428c 100644 --- a/tests/routers/test_tournament.py +++ b/tests/routers/test_tournament.py @@ -1,40 +1,36 @@ from datetime import datetime -from tests.utils import ( - register_match_result_util, - start_tournament_util, -) - +from tests.utils import register_match_result_util, start_tournament_util -BASE_URL = '/tournament' +BASE_URL = "/tournament" def test_create_tournament(client): response = client.post( BASE_URL, json={ - 'label': '\n 2002 FIFA World Cup\t\n', + "label": "\n 2002 FIFA World Cup\t\n", }, ) response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - response_uuid = response_json['uuid'] + response_uuid = response_json["uuid"] assert response.status_code == 201 assert response.json() == { - 'uuid': response_uuid, - 'label': '2002 FIFA World Cup', + "uuid": response_uuid, + "label": "2002 FIFA World Cup", } def test_list_tournaments(client, tournament1, tournament2, tournament3): expected_data = { - 'tournaments': [ + "tournaments": [ { - 'uuid': str(tournament_.uuid), - 'label': tournament_.label, + "uuid": str(tournament_.uuid), + "label": tournament_.label, } for tournament_ in [tournament1, tournament2, tournament3] ], @@ -48,48 +44,56 @@ def test_list_tournaments(client, tournament1, tournament2, tournament3): assert response.json() == expected_data -REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/competitor' -LIST_COMPETITORS_IN_TOURNAMENT_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/competitor' +REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE = ( + BASE_URL + "/{tournament_uuid}/competitor" +) +LIST_COMPETITORS_IN_TOURNAMENT_URL_TEMPLATE = BASE_URL + "/{tournament_uuid}/competitor" def test_201_for_register_competitor_in_tournament(client, tournament, competitor): response = client.post( - REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format(tournament_uuid=tournament.uuid), + REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( + tournament_uuid=tournament.uuid + ), json={ - 'competitor_uuid': str(competitor.uuid), + "competitor_uuid": str(competitor.uuid), }, ) assert response.status_code == 201 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, }, - 'competitor': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitor": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, } -def test_404_for_missing_tournament_during_register_competitor_in_tournament(client, competitor): +def test_404_for_missing_tournament_during_register_competitor_in_tournament( + client, competitor +): response = client.post( REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", ), json={ - 'competitor_uuid': str(competitor.uuid), + "competitor_uuid": str(competitor.uuid), }, ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -def test_409_for_started_tournament_during_register_competitor_in_tournament(client, session, tournament, competitor): +def test_409_for_started_tournament_during_register_competitor_in_tournament( + client, session, tournament, competitor +): # Already started tournament tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 1 @@ -99,53 +103,70 @@ def test_409_for_started_tournament_during_register_competitor_in_tournament(cli session.refresh(tournament) response = client.post( - REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format(tournament_uuid=tournament.uuid), + REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( + tournament_uuid=tournament.uuid + ), json={ - 'competitor_uuid': str(competitor.uuid), + "competitor_uuid": str(competitor.uuid), }, ) assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Tournament has already created its matches and does not allow new Competitors registration', + "detail": "Target Tournament has already created its matches and does not allow new Competitors registration", } -def test_404_for_missing_competitor_during_register_competitor_in_tournament(client, tournament): +def test_404_for_missing_competitor_during_register_competitor_in_tournament( + client, tournament +): response = client.post( - REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format(tournament_uuid=tournament.uuid), + REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( + tournament_uuid=tournament.uuid + ), json={ - 'competitor_uuid': '01234567-89ab-cdef-0123-456789abcdef', + "competitor_uuid": "01234567-89ab-cdef-0123-456789abcdef", }, ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Competitor does not exist', + "detail": "Target Competitor does not exist", } -def test_409_for_already_registered_competitor_during_register_competitor_in_tournament(client, session, tournament, competitor): +def test_409_for_already_registered_competitor_during_register_competitor_in_tournament( + client, session, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() session.refresh(tournament) response = client.post( - REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format(tournament_uuid=tournament.uuid), + REGISTER_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( + tournament_uuid=tournament.uuid + ), json={ - 'competitor_uuid': str(competitor.uuid), + "competitor_uuid": str(competitor.uuid), }, ) assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Competitor is already registered in target Tournament', + "detail": "Target Competitor is already registered in target Tournament", } def test_list_competitors_in_tournament( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): competitor_list = [competitor1, competitor2, competitor3, competitor4, competitor5] for competitor_ in competitor_list: @@ -155,14 +176,14 @@ def test_list_competitors_in_tournament( session.refresh(tournament) expected_data = { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, }, - 'competitors': [ + "competitors": [ { - 'uuid': str(competitor_.uuid), - 'label': competitor_.label, + "uuid": str(competitor_.uuid), + "label": competitor_.label, } for competitor_ in competitor_list ], @@ -181,21 +202,29 @@ def test_list_competitors_in_tournament( def test_404_for_missing_tournament_during_list_competitors_in_tournament(client): response = client.get( LIST_COMPETITORS_IN_TOURNAMENT_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -LIST_MATCHES_FOR_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/competitor/{competitor_uuid}' +LIST_MATCHES_FOR_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE = ( + BASE_URL + "/{tournament_uuid}/competitor/{competitor_uuid}" +) def test_list_matches_for_competitor_in_tournament( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, ): competitor_list = [competitor1, competitor2, competitor3, competitor4] for competitor_ in competitor_list: @@ -236,68 +265,74 @@ def test_list_matches_for_competitor_in_tournament( assert response.status_code == 200 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, }, - 'competitor': { - 'uuid': str(target_competitor.uuid), - 'label': target_competitor.label, + "competitor": { + "uuid": str(target_competitor.uuid), + "label": target_competitor.label, }, - 'matches': { - 'past': [ + "matches": { + "past": [ { - 'uuid': str(past_match.uuid), - 'round': 1, - 'position': 1, - 'otherCompetitor': { - 'uuid': str(past_match_other_competitor.uuid), - 'label': past_match_other_competitor.label, + "uuid": str(past_match.uuid), + "round": 1, + "position": 1, + "otherCompetitor": { + "uuid": str(past_match_other_competitor.uuid), + "label": past_match_other_competitor.label, }, } ], - 'upcoming': [ + "upcoming": [ { - 'uuid': str(next_match.uuid), - 'round': 0, - 'position': 0, - 'otherCompetitor': None, + "uuid": str(next_match.uuid), + "round": 0, + "position": 0, + "otherCompetitor": None, } ], }, } -def test_404_for_missing_tournament_during_list_matches_for_competitor_in_tournament(client, competitor): +def test_404_for_missing_tournament_during_list_matches_for_competitor_in_tournament( + client, competitor +): response = client.get( LIST_MATCHES_FOR_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", competitor_uuid=competitor.uuid, ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -def test_404_for_missing_competitor_during_list_matches_for_competitor_in_tournament(client, tournament): +def test_404_for_missing_competitor_during_list_matches_for_competitor_in_tournament( + client, tournament +): response = client.get( LIST_MATCHES_FOR_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( tournament_uuid=tournament.uuid, - competitor_uuid='01234567-89ab-cdef-0123-456789abcdef', + competitor_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Competitor does not exist', + "detail": "Target Competitor does not exist", } def test_422_for_unregistered_competitor_in_unstarted_tournament_list_matches_for_competitor_in_tournament( - client, tournament, competitor, + client, + tournament, + competitor, ): response = client.get( LIST_MATCHES_FOR_COMPETITOR_IN_TOURNAMENT_URL_TEMPLATE.format( @@ -308,12 +343,16 @@ def test_422_for_unregistered_competitor_in_unstarted_tournament_list_matches_fo assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Competitor is not registered for unstarted target Tournament', + "detail": "Target Competitor is not registered for unstarted target Tournament", } def test_409_for_unregistered_competitor_in_started_tournament_list_matches_for_competitor_in_tournament( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): tournament.competitors.append(competitor2) session.add(tournament) @@ -333,12 +372,15 @@ def test_409_for_unregistered_competitor_in_started_tournament_list_matches_for_ assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Competitor is not registered for started target Tournament', + "detail": "Target Competitor is not registered for started target Tournament", } def test_422_for_registered_competitor_in_unstarted_tournament_list_matches_for_competitor_in_tournament( - session, client, tournament, competitor, + session, + client, + tournament, + competitor, ): tournament.competitors.append(competitor) session.add(tournament) @@ -353,14 +395,16 @@ def test_422_for_registered_competitor_in_unstarted_tournament_list_matches_for_ assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament has not created its matches yet', + "detail": "Target Tournament has not created its matches yet", } -START_TOURNAMENT_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/start' +START_TOURNAMENT_URL_TEMPLATE = BASE_URL + "/{tournament_uuid}/start" -def test_201_for_start_tournament_for_one_competitor(session, client, tournament, competitor): +def test_201_for_start_tournament_for_one_competitor( + session, client, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() @@ -373,49 +417,59 @@ def test_201_for_start_tournament_for_one_competitor(session, client, tournament response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - matches_uuid = [ - match_data['uuid'] - for match_data in response_json['matches'] - ] + matches_uuid = [match_data["uuid"] for match_data in response_json["matches"]] assert response.status_code == 201 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 0, - 'numberCompetitors': 1, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 0, + "numberCompetitors": 1, }, - 'competitors': [ + "competitors": [ { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "uuid": str(competitor.uuid), + "label": competitor.label, }, ], - 'matches': [ + "matches": [ { - 'uuid': matches_uuid[0], - 'round': 0, - 'position': 0, - 'competitorA': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "uuid": matches_uuid[0], + "round": 0, + "position": 0, + "competitorA": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'competitorB': None, - 'winner': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitorB": None, + "winner": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'loser': None, + "loser": None, }, ], } def test_201_for_start_tournament_for_five_competitors( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -428,122 +482,119 @@ def test_201_for_start_tournament_for_five_competitors( response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - matches_uuid = [ - match_data['uuid'] - for match_data in response_json['matches'] - ] + matches_uuid = [match_data["uuid"] for match_data in response_json["matches"]] # as the competitors are randomly chosen, we will collect them to do the assertion competitor_dict = { - 'r2p0cA': response_json['matches'][0]['competitorA'], - 'r2p0cB': response_json['matches'][0]['competitorB'], - 'r2p1cA': response_json['matches'][1]['competitorA'], - 'r2p2cA': response_json['matches'][2]['competitorA'], - 'r2p3cA': response_json['matches'][3]['competitorA'], + "r2p0cA": response_json["matches"][0]["competitorA"], + "r2p0cB": response_json["matches"][0]["competitorB"], + "r2p1cA": response_json["matches"][1]["competitorA"], + "r2p2cA": response_json["matches"][2]["competitorA"], + "r2p3cA": response_json["matches"][3]["competitorA"], } assert response.status_code == 201 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 2, - 'numberCompetitors': 5, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 2, + "numberCompetitors": 5, }, - 'competitors': [ + "competitors": [ { - 'uuid': str(competitor1.uuid), - 'label': competitor1.label, + "uuid": str(competitor1.uuid), + "label": competitor1.label, }, { - 'uuid': str(competitor2.uuid), - 'label': competitor2.label, + "uuid": str(competitor2.uuid), + "label": competitor2.label, }, { - 'uuid': str(competitor3.uuid), - 'label': competitor3.label, + "uuid": str(competitor3.uuid), + "label": competitor3.label, }, { - 'uuid': str(competitor4.uuid), - 'label': competitor4.label, + "uuid": str(competitor4.uuid), + "label": competitor4.label, }, { - 'uuid': str(competitor5.uuid), - 'label': competitor5.label, + "uuid": str(competitor5.uuid), + "label": competitor5.label, }, ], - 'matches': [ + "matches": [ { - 'uuid': matches_uuid[0], - 'round': 2, - 'position': 0, - 'competitorA': competitor_dict['r2p0cA'], - 'competitorB': competitor_dict['r2p0cB'], - 'winner': None, - 'loser': None, + "uuid": matches_uuid[0], + "round": 2, + "position": 0, + "competitorA": competitor_dict["r2p0cA"], + "competitorB": competitor_dict["r2p0cB"], + "winner": None, + "loser": None, }, { - 'uuid': matches_uuid[1], - 'round': 2, - 'position': 1, - 'competitorA': competitor_dict['r2p1cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p1cA'], - 'loser': None, + "uuid": matches_uuid[1], + "round": 2, + "position": 1, + "competitorA": competitor_dict["r2p1cA"], + "competitorB": None, + "winner": competitor_dict["r2p1cA"], + "loser": None, }, { - 'uuid': matches_uuid[2], - 'round': 2, - 'position': 2, - 'competitorA': competitor_dict['r2p2cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p2cA'], - 'loser': None, + "uuid": matches_uuid[2], + "round": 2, + "position": 2, + "competitorA": competitor_dict["r2p2cA"], + "competitorB": None, + "winner": competitor_dict["r2p2cA"], + "loser": None, }, { - 'uuid': matches_uuid[3], - 'round': 2, - 'position': 3, - 'competitorA': competitor_dict['r2p3cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p3cA'], - 'loser': None, + "uuid": matches_uuid[3], + "round": 2, + "position": 3, + "competitorA": competitor_dict["r2p3cA"], + "competitorB": None, + "winner": competitor_dict["r2p3cA"], + "loser": None, }, { - 'uuid': matches_uuid[4], - 'round': 1, - 'position': 0, - 'competitorA': None, - 'competitorB': competitor_dict['r2p1cA'], - 'winner': None, - 'loser': None, + "uuid": matches_uuid[4], + "round": 1, + "position": 0, + "competitorA": None, + "competitorB": competitor_dict["r2p1cA"], + "winner": None, + "loser": None, }, { - 'uuid': matches_uuid[5], - 'round': 1, - 'position': 1, - 'competitorA': competitor_dict['r2p2cA'], - 'competitorB': competitor_dict['r2p3cA'], - 'winner': None, - 'loser': None, + "uuid": matches_uuid[5], + "round": 1, + "position": 1, + "competitorA": competitor_dict["r2p2cA"], + "competitorB": competitor_dict["r2p3cA"], + "winner": None, + "loser": None, }, { - 'uuid': matches_uuid[6], - 'round': 0, - 'position': 0, - 'competitorA': None, - 'competitorB': None, - 'winner': None, - 'loser': None, + "uuid": matches_uuid[6], + "round": 0, + "position": 0, + "competitorA": None, + "competitorB": None, + "winner": None, + "loser": None, }, { - 'uuid': matches_uuid[7], - 'round': 0, - 'position': 1, - 'competitorA': None, - 'competitorB': None, - 'winner': None, - 'loser': None, + "uuid": matches_uuid[7], + "round": 0, + "position": 1, + "competitorA": None, + "competitorB": None, + "winner": None, + "loser": None, }, ], } @@ -552,17 +603,19 @@ def test_201_for_start_tournament_for_five_competitors( def test_404_for_missing_tournament_during_start_tournament(client): response = client.post( START_TOURNAMENT_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -def test_409_for_started_tournament_during_start_tournament(client, session, tournament, competitor): +def test_409_for_started_tournament_during_start_tournament( + client, session, tournament, competitor +): # Already started tournament tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 1 @@ -577,7 +630,7 @@ def test_409_for_started_tournament_during_start_tournament(client, session, tou assert response.status_code == 409 assert response.json() == { - 'detail': 'Target Tournament has already created its matches', + "detail": "Target Tournament has already created its matches", } @@ -588,14 +641,16 @@ def test_422_for_missing_competitor_during_start_tournament(client, tournament): assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament does not have one Competitor registered yet', + "detail": "Target Tournament does not have one Competitor registered yet", } -LIST_TOURNAMENT_MATCHES_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/match' +LIST_TOURNAMENT_MATCHES_URL_TEMPLATE = BASE_URL + "/{tournament_uuid}/match" -def test_200_for_list_tournament_matches_for_one_competitor(session, client, tournament, competitor): +def test_200_for_list_tournament_matches_for_one_competitor( + session, client, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() @@ -614,46 +669,56 @@ def test_200_for_list_tournament_matches_for_one_competitor(session, client, tou response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - past_matches_uuid = [ - match_data['uuid'] - for match_data in response_json['past'] - ] + past_matches_uuid = [match_data["uuid"] for match_data in response_json["past"]] assert response.status_code == 200 - assert len(response_json['past']) == 1 - assert len(response_json['upcoming']) == 0 + assert len(response_json["past"]) == 1 + assert len(response_json["upcoming"]) == 0 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 0, - 'numberCompetitors': 1, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 0, + "numberCompetitors": 1, }, - 'past': [ + "past": [ { - 'uuid': past_matches_uuid[0], - 'round': 0, - 'position': 0, - 'competitorA': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "uuid": past_matches_uuid[0], + "round": 0, + "position": 0, + "competitorA": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'competitorB': None, - 'winner': { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "competitorB": None, + "winner": { + "uuid": str(competitor.uuid), + "label": competitor.label, }, - 'loser': None, + "loser": None, }, ], - 'upcoming': [], + "upcoming": [], } def test_200_list_tournament_matches_for_five_competitors( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -672,108 +737,104 @@ def test_200_list_tournament_matches_for_five_competitors( response_json = response.json() # as UUID is dynamically generated, we will extract it for the assertion - past_matches_uuid = [ - match_data['uuid'] - for match_data in response_json['past'] - ] + past_matches_uuid = [match_data["uuid"] for match_data in response_json["past"]] upcoming_matches_uuid = [ - match_data['uuid'] - for match_data in response_json['upcoming'] + match_data["uuid"] for match_data in response_json["upcoming"] ] # as the competitors are randomly chosen, we will collect them to do the assertion competitor_dict = { - 'r2p0cA': response_json['upcoming'][0]['competitorA'], - 'r2p0cB': response_json['upcoming'][0]['competitorB'], - 'r2p1cA': response_json['past'][0]['competitorA'], - 'r2p2cA': response_json['past'][1]['competitorA'], - 'r2p3cA': response_json['past'][2]['competitorA'], + "r2p0cA": response_json["upcoming"][0]["competitorA"], + "r2p0cB": response_json["upcoming"][0]["competitorB"], + "r2p1cA": response_json["past"][0]["competitorA"], + "r2p2cA": response_json["past"][1]["competitorA"], + "r2p3cA": response_json["past"][2]["competitorA"], } assert response.status_code == 200 - assert len(response_json['past']) == 3 - assert len(response_json['upcoming']) == 5 + assert len(response_json["past"]) == 3 + assert len(response_json["upcoming"]) == 5 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 2, - 'numberCompetitors': 5, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 2, + "numberCompetitors": 5, }, - 'past': [ + "past": [ { - 'uuid': past_matches_uuid[0], - 'round': 2, - 'position': 1, - 'competitorA': competitor_dict['r2p1cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p1cA'], - 'loser': None, + "uuid": past_matches_uuid[0], + "round": 2, + "position": 1, + "competitorA": competitor_dict["r2p1cA"], + "competitorB": None, + "winner": competitor_dict["r2p1cA"], + "loser": None, }, { - 'uuid': past_matches_uuid[1], - 'round': 2, - 'position': 2, - 'competitorA': competitor_dict['r2p2cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p2cA'], - 'loser': None, + "uuid": past_matches_uuid[1], + "round": 2, + "position": 2, + "competitorA": competitor_dict["r2p2cA"], + "competitorB": None, + "winner": competitor_dict["r2p2cA"], + "loser": None, }, { - 'uuid': past_matches_uuid[2], - 'round': 2, - 'position': 3, - 'competitorA': competitor_dict['r2p3cA'], - 'competitorB': None, - 'winner': competitor_dict['r2p3cA'], - 'loser': None, + "uuid": past_matches_uuid[2], + "round": 2, + "position": 3, + "competitorA": competitor_dict["r2p3cA"], + "competitorB": None, + "winner": competitor_dict["r2p3cA"], + "loser": None, }, ], - 'upcoming': [ + "upcoming": [ { - 'uuid': upcoming_matches_uuid[0], - 'round': 2, - 'position': 0, - 'competitorA': competitor_dict['r2p0cA'], - 'competitorB': competitor_dict['r2p0cB'], - 'winner': None, - 'loser': None, + "uuid": upcoming_matches_uuid[0], + "round": 2, + "position": 0, + "competitorA": competitor_dict["r2p0cA"], + "competitorB": competitor_dict["r2p0cB"], + "winner": None, + "loser": None, }, { - 'uuid': upcoming_matches_uuid[1], - 'round': 1, - 'position': 0, - 'competitorA': None, - 'competitorB': competitor_dict['r2p1cA'], - 'winner': None, - 'loser': None, + "uuid": upcoming_matches_uuid[1], + "round": 1, + "position": 0, + "competitorA": None, + "competitorB": competitor_dict["r2p1cA"], + "winner": None, + "loser": None, }, { - 'uuid': upcoming_matches_uuid[2], - 'round': 1, - 'position': 1, - 'competitorA': competitor_dict['r2p2cA'], - 'competitorB': competitor_dict['r2p3cA'], - 'winner': None, - 'loser': None, + "uuid": upcoming_matches_uuid[2], + "round": 1, + "position": 1, + "competitorA": competitor_dict["r2p2cA"], + "competitorB": competitor_dict["r2p3cA"], + "winner": None, + "loser": None, }, { - 'uuid': upcoming_matches_uuid[3], - 'round': 0, - 'position': 0, - 'competitorA': None, - 'competitorB': None, - 'winner': None, - 'loser': None, + "uuid": upcoming_matches_uuid[3], + "round": 0, + "position": 0, + "competitorA": None, + "competitorB": None, + "winner": None, + "loser": None, }, { - 'uuid': upcoming_matches_uuid[4], - 'round': 0, - 'position': 1, - 'competitorA': None, - 'competitorB': None, - 'winner': None, - 'loser': None, + "uuid": upcoming_matches_uuid[4], + "round": 0, + "position": 1, + "competitorA": None, + "competitorB": None, + "winner": None, + "loser": None, }, ], } @@ -782,17 +843,19 @@ def test_200_list_tournament_matches_for_five_competitors( def test_404_for_missing_tournament_during_list_tournament_matches(client): response = client.get( LIST_TOURNAMENT_MATCHES_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -def test_422_for_missing_competitor_during_list_tournament_matches(session, client, tournament, competitor): +def test_422_for_missing_competitor_during_list_tournament_matches( + session, client, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() @@ -804,14 +867,16 @@ def test_422_for_missing_competitor_during_list_tournament_matches(session, clie assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament has not created its matches yet', + "detail": "Target Tournament has not created its matches yet", } -GET_TOURNAMENT_TOP4_URL_TEMPLATE = BASE_URL + '/{tournament_uuid}/result' +GET_TOURNAMENT_TOP4_URL_TEMPLATE = BASE_URL + "/{tournament_uuid}/result" -def test_200_for_get_tournament_top4_for_one_competitor(session, client, tournament, competitor): +def test_200_for_get_tournament_top4_for_one_competitor( + session, client, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() @@ -830,18 +895,18 @@ def test_200_for_get_tournament_top4_for_one_competitor(session, client, tournam response_json = response.json() assert response.status_code == 200 - assert len(response_json['top4']) == 4 + assert len(response_json["top4"]) == 4 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 0, - 'numberCompetitors': 1, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 0, + "numberCompetitors": 1, }, - 'top4': [ + "top4": [ { - 'uuid': str(competitor.uuid), - 'label': competitor.label, + "uuid": str(competitor.uuid), + "label": competitor.label, }, None, None, @@ -850,11 +915,15 @@ def test_200_for_get_tournament_top4_for_one_competitor(session, client, tournam } -REGISTER_MATCH_RESULT_URL_TEMPLATE = '/match/{match_uuid}' +REGISTER_MATCH_RESULT_URL_TEMPLATE = "/match/{match_uuid}" def test_200_for_get_tournament_top4_for_two_competitors( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): map_uuid_to_competitor = {} for competitor_ in [competitor1, competitor2]: @@ -870,25 +939,25 @@ def test_200_for_get_tournament_top4_for_two_competitors( ) response_start_json = response_start.json() - json_final = response_start_json['matches'][0] + json_final = response_start_json["matches"][0] - assert json_final['round'] == 0 - assert json_final['position'] == 0 - assert json_final['winner'] is None - assert json_final['loser'] is None - assert json_final['competitorA'] is not None - assert json_final['competitorB'] is not None + assert json_final["round"] == 0 + assert json_final["position"] == 0 + assert json_final["winner"] is None + assert json_final["loser"] is None + assert json_final["competitorA"] is not None + assert json_final["competitorB"] is not None - second_place_uuid = json_final['competitorA']['uuid'] + second_place_uuid = json_final["competitorA"]["uuid"] second_place = map_uuid_to_competitor[second_place_uuid] - first_place_uuid = json_final['competitorB']['uuid'] + first_place_uuid = json_final["competitorB"]["uuid"] first_place = map_uuid_to_competitor[first_place_uuid] # Then we register the final match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final["uuid"]), json={ - 'winner_uuid': first_place_uuid, + "winner_uuid": first_place_uuid, }, ) @@ -900,22 +969,22 @@ def test_200_for_get_tournament_top4_for_two_competitors( response_json = response.json() assert response.status_code == 200 - assert len(response_json['top4']) == 4 + assert len(response_json["top4"]) == 4 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 0, - 'numberCompetitors': 2, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 0, + "numberCompetitors": 2, }, - 'top4': [ + "top4": [ { - 'uuid': first_place_uuid, - 'label': first_place.label, + "uuid": first_place_uuid, + "label": first_place.label, }, { - 'uuid': second_place_uuid, - 'label': second_place.label, + "uuid": second_place_uuid, + "label": second_place.label, }, None, None, @@ -924,7 +993,12 @@ def test_200_for_get_tournament_top4_for_two_competitors( def test_200_for_get_tournament_top4_for_three_competitors( - session, client, tournament, competitor1, competitor2, competitor3, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, ): map_uuid_to_competitor = {} for competitor_ in [competitor1, competitor2, competitor3]: @@ -940,44 +1014,44 @@ def test_200_for_get_tournament_top4_for_three_competitors( ) response_start_json = response_start.json() - json_semifinal = response_start_json['matches'][0] - json_final = response_start_json['matches'][2] + json_semifinal = response_start_json["matches"][0] + json_final = response_start_json["matches"][2] - first_place_uuid = response_start_json['matches'][1]['winner']['uuid'] + first_place_uuid = response_start_json["matches"][1]["winner"]["uuid"] first_place = map_uuid_to_competitor[first_place_uuid] - assert json_semifinal['round'] == 1 - assert json_semifinal['position'] == 0 - assert json_semifinal['winner'] is None - assert json_semifinal['loser'] is None - assert json_semifinal['competitorA'] is not None - assert json_semifinal['competitorB'] is not None - - assert json_final['round'] == 0 - assert json_final['position'] == 0 - assert json_final['winner'] is None - assert json_final['loser'] is None - assert json_final['competitorA'] is None - assert json_final['competitorB'] is not None - - third_place_uuid = json_semifinal['competitorA']['uuid'] + assert json_semifinal["round"] == 1 + assert json_semifinal["position"] == 0 + assert json_semifinal["winner"] is None + assert json_semifinal["loser"] is None + assert json_semifinal["competitorA"] is not None + assert json_semifinal["competitorB"] is not None + + assert json_final["round"] == 0 + assert json_final["position"] == 0 + assert json_final["winner"] is None + assert json_final["loser"] is None + assert json_final["competitorA"] is None + assert json_final["competitorB"] is not None + + third_place_uuid = json_semifinal["competitorA"]["uuid"] third_place = map_uuid_to_competitor[third_place_uuid] - second_place_uuid = json_semifinal['competitorB']['uuid'] + second_place_uuid = json_semifinal["competitorB"]["uuid"] second_place = map_uuid_to_competitor[second_place_uuid] # Then we register the semifinal match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal["uuid"]), json={ - 'winner_uuid': second_place_uuid, + "winner_uuid": second_place_uuid, }, ) # Then we register the final match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final["uuid"]), json={ - 'winner_uuid': first_place_uuid, + "winner_uuid": first_place_uuid, }, ) @@ -989,26 +1063,26 @@ def test_200_for_get_tournament_top4_for_three_competitors( response_json = response.json() assert response.status_code == 200 - assert len(response_json['top4']) == 4 + assert len(response_json["top4"]) == 4 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 1, - 'numberCompetitors': 3, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 1, + "numberCompetitors": 3, }, - 'top4': [ + "top4": [ { - 'uuid': first_place_uuid, - 'label': first_place.label, + "uuid": first_place_uuid, + "label": first_place.label, }, { - 'uuid': second_place_uuid, - 'label': second_place.label, + "uuid": second_place_uuid, + "label": second_place.label, }, { - 'uuid': third_place_uuid, - 'label': third_place.label, + "uuid": third_place_uuid, + "label": third_place.label, }, None, ], @@ -1016,7 +1090,13 @@ def test_200_for_get_tournament_top4_for_three_competitors( def test_200_for_get_tournament_top4_for_four_competitors( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, ): map_uuid_to_competitor = {} for competitor_ in [competitor1, competitor2, competitor3, competitor4]: @@ -1032,78 +1112,80 @@ def test_200_for_get_tournament_top4_for_four_competitors( ) response_start_json = response_start.json() - json_semifinal0 = response_start_json['matches'][0] - json_semifinal1 = response_start_json['matches'][1] - json_final = response_start_json['matches'][2] - json_third_place_match = response_start_json['matches'][3] - - assert json_semifinal0['round'] == 1 - assert json_semifinal0['position'] == 0 - assert json_semifinal0['winner'] is None - assert json_semifinal0['loser'] is None - assert json_semifinal0['competitorA'] is not None - assert json_semifinal0['competitorB'] is not None - - assert json_semifinal1['round'] == 1 - assert json_semifinal1['position'] == 1 - assert json_semifinal1['winner'] is None - assert json_semifinal1['loser'] is None - assert json_semifinal1['competitorA'] is not None - assert json_semifinal1['competitorB'] is not None - - assert json_final['round'] == 0 - assert json_final['position'] == 0 - assert json_final['winner'] is None - assert json_final['loser'] is None - assert json_final['competitorA'] is None - assert json_final['competitorB'] is None - - assert json_third_place_match['round'] == 0 - assert json_third_place_match['position'] == 1 - assert json_third_place_match['winner'] is None - assert json_third_place_match['loser'] is None - assert json_third_place_match['competitorA'] is None - assert json_third_place_match['competitorB'] is None - - third_place_uuid = json_semifinal0['competitorA']['uuid'] + json_semifinal0 = response_start_json["matches"][0] + json_semifinal1 = response_start_json["matches"][1] + json_final = response_start_json["matches"][2] + json_third_place_match = response_start_json["matches"][3] + + assert json_semifinal0["round"] == 1 + assert json_semifinal0["position"] == 0 + assert json_semifinal0["winner"] is None + assert json_semifinal0["loser"] is None + assert json_semifinal0["competitorA"] is not None + assert json_semifinal0["competitorB"] is not None + + assert json_semifinal1["round"] == 1 + assert json_semifinal1["position"] == 1 + assert json_semifinal1["winner"] is None + assert json_semifinal1["loser"] is None + assert json_semifinal1["competitorA"] is not None + assert json_semifinal1["competitorB"] is not None + + assert json_final["round"] == 0 + assert json_final["position"] == 0 + assert json_final["winner"] is None + assert json_final["loser"] is None + assert json_final["competitorA"] is None + assert json_final["competitorB"] is None + + assert json_third_place_match["round"] == 0 + assert json_third_place_match["position"] == 1 + assert json_third_place_match["winner"] is None + assert json_third_place_match["loser"] is None + assert json_third_place_match["competitorA"] is None + assert json_third_place_match["competitorB"] is None + + third_place_uuid = json_semifinal0["competitorA"]["uuid"] third_place = map_uuid_to_competitor[third_place_uuid] - second_place_uuid = json_semifinal0['competitorB']['uuid'] + second_place_uuid = json_semifinal0["competitorB"]["uuid"] second_place = map_uuid_to_competitor[second_place_uuid] # Then we register the semifinal0 match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal0['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal0["uuid"]), json={ - 'winner_uuid': second_place_uuid, + "winner_uuid": second_place_uuid, }, ) - fourth_place_uuid = json_semifinal1['competitorA']['uuid'] + fourth_place_uuid = json_semifinal1["competitorA"]["uuid"] fourth_place = map_uuid_to_competitor[fourth_place_uuid] - first_place_uuid = json_semifinal1['competitorB']['uuid'] + first_place_uuid = json_semifinal1["competitorB"]["uuid"] first_place = map_uuid_to_competitor[first_place_uuid] # Then we register the semifinal1 match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal1['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_semifinal1["uuid"]), json={ - 'winner_uuid': first_place_uuid, + "winner_uuid": first_place_uuid, }, ) # Then we register the third place match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_third_place_match['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format( + match_uuid=json_third_place_match["uuid"] + ), json={ - 'winner_uuid': third_place_uuid, + "winner_uuid": third_place_uuid, }, ) # Then we register the final match result client.post( - REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final['uuid']), + REGISTER_MATCH_RESULT_URL_TEMPLATE.format(match_uuid=json_final["uuid"]), json={ - 'winner_uuid': first_place_uuid, + "winner_uuid": first_place_uuid, }, ) @@ -1115,30 +1197,30 @@ def test_200_for_get_tournament_top4_for_four_competitors( response_json = response.json() assert response.status_code == 200 - assert len(response_json['top4']) == 4 + assert len(response_json["top4"]) == 4 assert response.json() == { - 'tournament': { - 'uuid': str(tournament.uuid), - 'label': tournament.label, - 'startingRound': 1, - 'numberCompetitors': 4, + "tournament": { + "uuid": str(tournament.uuid), + "label": tournament.label, + "startingRound": 1, + "numberCompetitors": 4, }, - 'top4': [ + "top4": [ { - 'uuid': first_place_uuid, - 'label': first_place.label, + "uuid": first_place_uuid, + "label": first_place.label, }, { - 'uuid': second_place_uuid, - 'label': second_place.label, + "uuid": second_place_uuid, + "label": second_place.label, }, { - 'uuid': third_place_uuid, - 'label': third_place.label, + "uuid": third_place_uuid, + "label": third_place.label, }, { - 'uuid': fourth_place_uuid, - 'label': fourth_place.label, + "uuid": fourth_place_uuid, + "label": fourth_place.label, }, ], } @@ -1147,17 +1229,19 @@ def test_200_for_get_tournament_top4_for_four_competitors( def test_404_for_missing_tournament_during_get_tournament_top4(client): response = client.get( GET_TOURNAMENT_TOP4_URL_TEMPLATE.format( - tournament_uuid='01234567-89ab-cdef-0123-456789abcdef', + tournament_uuid="01234567-89ab-cdef-0123-456789abcdef", ), ) assert response.status_code == 404 assert response.json() == { - 'detail': 'Target Tournament does not exist', + "detail": "Target Tournament does not exist", } -def test_422_for_missing_competitor_during_get_tournament_top4(session, client, tournament, competitor): +def test_422_for_missing_competitor_during_get_tournament_top4( + session, client, tournament, competitor +): tournament.competitors.append(competitor) session.add(tournament) session.commit() @@ -1169,12 +1253,16 @@ def test_422_for_missing_competitor_during_get_tournament_top4(session, client, assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament has not created its matches yet', + "detail": "Target Tournament has not created its matches yet", } def test_422_for_final_not_played_during_get_tournament_for_two_competitors( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): for competitor_ in [competitor1, competitor2]: tournament.competitors.append(competitor_) @@ -1194,12 +1282,17 @@ def test_422_for_final_not_played_during_get_tournament_for_two_competitors( assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament is not ready to display the top 4 competitors', + "detail": "Target Tournament is not ready to display the top 4 competitors", } def test_422_for_final_not_played_during_get_tournament_for_three_competitors( - session, client, tournament, competitor1, competitor2, competitor3, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, ): for competitor_ in [competitor1, competitor2, competitor3]: tournament.competitors.append(competitor_) @@ -1219,5 +1312,5 @@ def test_422_for_final_not_played_during_get_tournament_for_three_competitors( assert response.status_code == 422 assert response.json() == { - 'detail': 'Target Tournament is not ready to display the top 4 competitors', + "detail": "Target Tournament is not ready to display the top 4 competitors", } diff --git a/tests/services/test_register_match_result.py b/tests/services/test_register_match_result.py index 3f83c07..1312544 100644 --- a/tests/services/test_register_match_result.py +++ b/tests/services/test_register_match_result.py @@ -18,7 +18,11 @@ def test_register_match_result_for_final_match( - session, client, tournament, competitor1, competitor2, + session, + client, + tournament, + competitor1, + competitor2, ): for competitor_ in [competitor1, competitor2]: tournament.competitors.append(competitor_) @@ -79,7 +83,12 @@ def test_register_match_result_for_final_match( def test_200_for_register_match_result_for_semifinal_match_for_three_competitors( - session, client, tournament, competitor1, competitor2, competitor3, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, ): for competitor_ in [competitor1, competitor2, competitor3]: tournament.competitors.append(competitor_) @@ -159,9 +168,22 @@ def test_200_for_register_match_result_for_semifinal_match_for_three_competitors def test_register_match_result_for_round_1_match( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -235,9 +257,22 @@ def test_register_match_result_for_round_1_match( def test_register_match_result_for_round_greater_than_1_entry_match( - session, client, tournament, competitor1, competitor2, competitor3, competitor4, competitor5, + session, + client, + tournament, + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, ): - for competitor_ in [competitor1, competitor2, competitor3, competitor4, competitor5]: + for competitor_ in [ + competitor1, + competitor2, + competitor3, + competitor4, + competitor5, + ]: tournament.competitors.append(competitor_) session.add(tournament) session.commit() @@ -305,7 +340,9 @@ def test_register_match_result_for_round_greater_than_1_entry_match( assert tournament_competitor_competitor_b.next_match_id is None -def test_match_with_registered_result_during_register_match_result(client, session, tournament, competitor): +def test_match_with_registered_result_during_register_match_result( + client, session, tournament, competitor +): tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 1 tournament.starting_round = 0 @@ -336,7 +373,9 @@ def test_match_with_registered_result_during_register_match_result(client, sessi ) -def test_match_that_should_have_automatic_winner_during_register_match_result(client, session, tournament, competitor): +def test_match_that_should_have_automatic_winner_during_register_match_result( + client, session, tournament, competitor +): tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 1 tournament.starting_round = 0 @@ -365,7 +404,9 @@ def test_match_that_should_have_automatic_winner_during_register_match_result(cl ) -def test_missing_competitor_during_register_match_result(client, session, tournament, competitor1, competitor2, competitor3): +def test_missing_competitor_during_register_match_result( + client, session, tournament, competitor1, competitor2, competitor3 +): tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 3 tournament.starting_round = 1 @@ -394,7 +435,9 @@ def test_missing_competitor_during_register_match_result(client, session, tourna ) -def test_competitor_not_match_competitor_during_register_match_result(client, session, tournament, competitor1, competitor2, competitor3): +def test_competitor_not_match_competitor_during_register_match_result( + client, session, tournament, competitor1, competitor2, competitor3 +): tournament.matches_creation = datetime(year=2024, month=1, day=1) tournament.number_competitors = 3 tournament.starting_round = 1 diff --git a/tests/services/test_start_tournament.py b/tests/services/test_start_tournament.py index 26dde46..afba286 100644 --- a/tests/services/test_start_tournament.py +++ b/tests/services/test_start_tournament.py @@ -51,7 +51,9 @@ def test_start_tournament_for_a_single_competitor(session, tournament, competito assert tournament_competior.next_match_id is None -def test_start_tournament_for_two_competitors(session, tournament, competitor1, competitor2): +def test_start_tournament_for_two_competitors( + session, tournament, competitor1, competitor2 +): competitor_set = {competitor1, competitor2} tournament_competitor_dict = {} for competitor_ in competitor_set: @@ -82,15 +84,25 @@ def test_start_tournament_for_two_competitors(session, tournament, competitor1, assert match.round == 0 assert match.position == 0 assert match.competitor_a_id in {competitor1.id, competitor2.id} - assert {match.competitor_b_id} == {competitor1.id, competitor2.id}.difference({match.competitor_a_id}) + assert {match.competitor_b_id} == {competitor1.id, competitor2.id}.difference( + {match.competitor_a_id} + ) assert match.result_registration is None assert match.winner_id is None assert match.loser_id is None - assert tournament_competitor_dict[matches[0].competitor_a_id].next_match_id == matches[0].id - assert tournament_competitor_dict[matches[0].competitor_b_id].next_match_id == matches[0].id + assert ( + tournament_competitor_dict[matches[0].competitor_a_id].next_match_id + == matches[0].id + ) + assert ( + tournament_competitor_dict[matches[0].competitor_b_id].next_match_id + == matches[0].id + ) -def test_start_tournament_for_three_competitors(session, tournament, competitor1, competitor2, competitor3): +def test_start_tournament_for_three_competitors( + session, tournament, competitor1, competitor2, competitor3 +): competitor_set = {competitor1, competitor2, competitor3} tournament_competitor_dict = {} for competitor_ in competitor_set: @@ -129,8 +141,14 @@ def test_start_tournament_for_three_competitors(session, tournament, competitor1 assert matches[0].result_registration is None assert matches[0].winner_id is None assert matches[0].loser_id is None - assert tournament_competitor_dict[matches[0].competitor_a_id].next_match_id == matches[0].id - assert tournament_competitor_dict[matches[0].competitor_b_id].next_match_id == matches[0].id + assert ( + tournament_competitor_dict[matches[0].competitor_a_id].next_match_id + == matches[0].id + ) + assert ( + tournament_competitor_dict[matches[0].competitor_b_id].next_match_id + == matches[0].id + ) # round 1 position 1 has one competitor, who will compete on the final match assert matches[1].round == 1 @@ -141,7 +159,10 @@ def test_start_tournament_for_three_competitors(session, tournament, competitor1 assert matches[1].result_registration > before_start_tournament assert matches[1].winner_id is matches[1].competitor_a_id assert matches[1].loser_id is None - assert tournament_competitor_dict[matches[1].competitor_a_id].next_match_id != matches[1].id + assert ( + tournament_competitor_dict[matches[1].competitor_a_id].next_match_id + != matches[1].id + ) # round 0 position 0 has one competitor assert matches[2].round == 0 @@ -151,7 +172,10 @@ def test_start_tournament_for_three_competitors(session, tournament, competitor1 assert matches[2].result_registration is None assert matches[2].winner_id is None assert matches[2].loser_id is None - assert tournament_competitor_dict[matches[1].competitor_a_id].next_match_id == matches[2].id + assert ( + tournament_competitor_dict[matches[1].competitor_a_id].next_match_id + == matches[2].id + ) # round 0 position 1 has no competitor assert matches[3].round == 0 @@ -163,7 +187,9 @@ def test_start_tournament_for_three_competitors(session, tournament, competitor1 assert matches[3].loser_id is None -def test_start_tournament_for_four_competitors(session, tournament, competitor1, competitor2, competitor3, competitor4): +def test_start_tournament_for_four_competitors( + session, tournament, competitor1, competitor2, competitor3, competitor4 +): competitor_set = {competitor1, competitor2, competitor3, competitor4} tournament_competitor_dict = {} for competitor_ in competitor_set: @@ -194,7 +220,12 @@ def test_start_tournament_for_four_competitors(session, tournament, competitor1, # round 1 position 0 has both competitors assert matches[0].round == 1 assert matches[0].position == 0 - remaining_competitor_id_set = {competitor1.id, competitor2.id, competitor3.id, competitor4.id} + remaining_competitor_id_set = { + competitor1.id, + competitor2.id, + competitor3.id, + competitor4.id, + } assert matches[0].competitor_a_id in remaining_competitor_id_set remaining_competitor_id_set.difference_update({matches[0].competitor_a_id}) assert matches[0].competitor_b_id in remaining_competitor_id_set @@ -202,8 +233,14 @@ def test_start_tournament_for_four_competitors(session, tournament, competitor1, assert matches[0].result_registration is None assert matches[0].winner_id is None assert matches[0].loser_id is None - assert tournament_competitor_dict[matches[0].competitor_a_id].next_match_id == matches[0].id - assert tournament_competitor_dict[matches[0].competitor_b_id].next_match_id == matches[0].id + assert ( + tournament_competitor_dict[matches[0].competitor_a_id].next_match_id + == matches[0].id + ) + assert ( + tournament_competitor_dict[matches[0].competitor_b_id].next_match_id + == matches[0].id + ) # round 1 position 1 has both competitors assert matches[1].round == 1 @@ -214,8 +251,14 @@ def test_start_tournament_for_four_competitors(session, tournament, competitor1, assert matches[1].result_registration is None assert matches[1].winner_id is None assert matches[1].loser_id is None - assert tournament_competitor_dict[matches[1].competitor_a_id].next_match_id == matches[1].id - assert tournament_competitor_dict[matches[1].competitor_b_id].next_match_id == matches[1].id + assert ( + tournament_competitor_dict[matches[1].competitor_a_id].next_match_id + == matches[1].id + ) + assert ( + tournament_competitor_dict[matches[1].competitor_b_id].next_match_id + == matches[1].id + ) # round 0 position 0 has no competitor assert matches[2].round == 0 @@ -236,7 +279,9 @@ def test_start_tournament_for_four_competitors(session, tournament, competitor1, assert matches[3].loser_id is None -def test_start_tournament_for_five_competitors(session, tournament, competitor1, competitor2, competitor3, competitor4, competitor5): +def test_start_tournament_for_five_competitors( + session, tournament, competitor1, competitor2, competitor3, competitor4, competitor5 +): competitor_set = {competitor1, competitor2, competitor3, competitor4, competitor5} tournament_competitor_dict = {} for competitor_ in competitor_set: @@ -267,7 +312,13 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, # round 2 position 0 has both competitors assert matches[0].round == 2 assert matches[0].position == 0 - remaining_competitor_id_set = {competitor1.id, competitor2.id, competitor3.id, competitor4.id, competitor5.id} + remaining_competitor_id_set = { + competitor1.id, + competitor2.id, + competitor3.id, + competitor4.id, + competitor5.id, + } assert matches[0].competitor_a_id in remaining_competitor_id_set remaining_competitor_id_set.difference_update({matches[0].competitor_a_id}) assert matches[0].competitor_b_id in remaining_competitor_id_set @@ -275,8 +326,14 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[0].result_registration is None assert matches[0].winner_id is None assert matches[0].loser_id is None - assert tournament_competitor_dict[matches[0].competitor_a_id].next_match_id == matches[0].id - assert tournament_competitor_dict[matches[0].competitor_b_id].next_match_id == matches[0].id + assert ( + tournament_competitor_dict[matches[0].competitor_a_id].next_match_id + == matches[0].id + ) + assert ( + tournament_competitor_dict[matches[0].competitor_b_id].next_match_id + == matches[0].id + ) # round 2 position 1 has one competitor, who will compete on a semifinal match assert matches[1].round == 2 @@ -288,7 +345,10 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[1].result_registration > before_start_tournament assert matches[1].winner_id == matches[1].competitor_a_id assert matches[1].loser_id is None - assert tournament_competitor_dict[matches[1].competitor_a_id].next_match_id != matches[1].id + assert ( + tournament_competitor_dict[matches[1].competitor_a_id].next_match_id + != matches[1].id + ) # round 2 position 2 has one competitor, who will compete on a semifinal match assert matches[2].round == 2 @@ -300,7 +360,10 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[2].result_registration > before_start_tournament assert matches[2].winner_id == matches[2].competitor_a_id assert matches[2].loser_id is None - assert tournament_competitor_dict[matches[2].competitor_a_id].next_match_id != matches[2].id + assert ( + tournament_competitor_dict[matches[2].competitor_a_id].next_match_id + != matches[2].id + ) # round 2 position 3 has one competitor, who will compete on a semifinal match assert matches[3].round == 2 @@ -311,7 +374,10 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[3].result_registration > before_start_tournament assert matches[3].winner_id == matches[3].competitor_a_id assert matches[3].loser_id is None - assert tournament_competitor_dict[matches[3].competitor_a_id].next_match_id != matches[3].id + assert ( + tournament_competitor_dict[matches[3].competitor_a_id].next_match_id + != matches[3].id + ) # round 1 position 0 has one competitor assert matches[4].round == 1 @@ -321,7 +387,10 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[4].result_registration is None assert matches[4].winner_id is None assert matches[4].loser_id is None - assert tournament_competitor_dict[matches[4].competitor_b_id].next_match_id == matches[4].id + assert ( + tournament_competitor_dict[matches[4].competitor_b_id].next_match_id + == matches[4].id + ) # round 1 position 1 has two competitors assert matches[5].round == 1 @@ -331,8 +400,14 @@ def test_start_tournament_for_five_competitors(session, tournament, competitor1, assert matches[5].result_registration is None assert matches[5].winner_id is None assert matches[5].loser_id is None - assert tournament_competitor_dict[matches[5].competitor_a_id].next_match_id == matches[5].id - assert tournament_competitor_dict[matches[5].competitor_b_id].next_match_id == matches[5].id + assert ( + tournament_competitor_dict[matches[5].competitor_a_id].next_match_id + == matches[5].id + ) + assert ( + tournament_competitor_dict[matches[5].competitor_b_id].next_match_id + == matches[5].id + ) # round 0 position 0 has no competitor assert matches[6].round == 0 diff --git a/tests/test_app.py b/tests/test_app.py index 85eebd4..7c9aae8 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,8 +1,8 @@ def test_api_docs_endpoint_is_accessible(client): - response = client.get('/docs') + response = client.get("/docs") assert response.status_code == 200 def test_api_docs_definition_is_accessible(client): - response = client.get('/openapi.json') + response = client.get("/openapi.json") assert response.status_code == 200 diff --git a/tests/test_schemas.py b/tests/test_schemas.py index d142b60..20417d4 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -12,9 +12,9 @@ TournamentCompetitorPayloadSchema, TournamentCompetitorSchema, TournamentMatchesSchema, + TournamentResultSchema, TournamentSchema, TournamentStartSchema, - TournamentResultSchema, TrimmedString, UuidLabelSchema, WinnerPayloadSchema, @@ -24,170 +24,157 @@ def test_trimmedstring(): class SingleField(BaseModel): field: TrimmedString - instance = SingleField(field='\r\n\t something \t\r\n') - assert instance.field == 'something' + + instance = SingleField(field="\r\n\t something \t\r\n") + assert instance.field == "something" def test_label_schema(): schema = LabelSchema( - label='\t\nSouth Korea\n ', + label="\t\nSouth Korea\n ", ) - assert schema.label == 'South Korea' + assert schema.label == "South Korea" def test_labelschema_does_not_accept_whitespace_only_label_value(): with pytest.raises( - ValidationError, - match='must not be empty or contain only whitespace characters', + ValidationError, + match="must not be empty or contain only whitespace characters", ): LabelSchema( - label='\r\n\f\v \r\n', + label="\r\n\f\v \r\n", ) def test_tournament_competitor_payload_schema(): schema = TournamentCompetitorPayloadSchema( - competitor_uuid='01234567-89ab-cdef-0123-456789abcdef' + competitor_uuid="01234567-89ab-cdef-0123-456789abcdef" ) - assert schema.competitor_uuid == uuid.UUID('01234567-89ab-cdef-0123-456789abcdef') + assert schema.competitor_uuid == uuid.UUID("01234567-89ab-cdef-0123-456789abcdef") def test_winner_payload_schema(): - schema = WinnerPayloadSchema( - winner_uuid='01234567-89ab-cdef-0123-456789abcdef' - ) - assert schema.winner_uuid == uuid.UUID('01234567-89ab-cdef-0123-456789abcdef') + schema = WinnerPayloadSchema(winner_uuid="01234567-89ab-cdef-0123-456789abcdef") + assert schema.winner_uuid == uuid.UUID("01234567-89ab-cdef-0123-456789abcdef") def test_uuid_label_schema(): schema = UuidLabelSchema( - uuid='01234567-89ab-cdef-0123-456789abcdef', - label='\t\nSouth Korea\n ', + uuid="01234567-89ab-cdef-0123-456789abcdef", + label="\t\nSouth Korea\n ", ) - assert schema.uuid == uuid.UUID('01234567-89ab-cdef-0123-456789abcdef') - assert schema.label == 'South Korea' + assert schema.uuid == uuid.UUID("01234567-89ab-cdef-0123-456789abcdef") + assert schema.label == "South Korea" def test_tournament_schema(): schema = TournamentSchema( **{ - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", } ) - assert schema.uuid == uuid.UUID('03c964f8-7f5c-4224-b848-1ab6c1413c7d') - assert schema.label == '2002 FIFA World Cup' + assert schema.uuid == uuid.UUID("03c964f8-7f5c-4224-b848-1ab6c1413c7d") + assert schema.label == "2002 FIFA World Cup" def test_competitor_schema(): schema = CompetitorSchema( - **{ - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' - } + **{"uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", "label": "South Korea"} ) - assert schema.uuid == uuid.UUID('5d1bd1d1-2679-432a-ac11-ebfebfa1bce9') - assert schema.label == 'South Korea' + assert schema.uuid == uuid.UUID("5d1bd1d1-2679-432a-ac11-ebfebfa1bce9") + assert schema.label == "South Korea" def test_tournament_competitor_schema(): schema = TournamentCompetitorSchema( **{ - 'tournament': { - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", }, - 'competitor': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea', + "competitor": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, } ) assert isinstance(schema.tournament, TournamentSchema) assert isinstance(schema.competitor, CompetitorSchema) - assert schema.tournament.uuid == uuid.UUID('03c964f8-7f5c-4224-b848-1ab6c1413c7d') - assert schema.tournament.label == '2002 FIFA World Cup' - assert schema.competitor.uuid == uuid.UUID('5d1bd1d1-2679-432a-ac11-ebfebfa1bce9') - assert schema.competitor.label == 'South Korea' + assert schema.tournament.uuid == uuid.UUID("03c964f8-7f5c-4224-b848-1ab6c1413c7d") + assert schema.tournament.label == "2002 FIFA World Cup" + assert schema.competitor.uuid == uuid.UUID("5d1bd1d1-2679-432a-ac11-ebfebfa1bce9") + assert schema.competitor.label == "South Korea" def test_tournament_start_schema(): schema = TournamentStartSchema( **{ - 'tournament': { - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', - 'starting_round': 1, - 'number_competitors': 4 + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "starting_round": 1, + "number_competitors": 4, }, - 'competitors': [ - { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' - }, + "competitors": [ + {"uuid": "de686e37-804b-4815-a507-d5879a240af6", "label": "Germany"}, { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - { - 'uuid': '7f026276-0904-4a7b-ae14-8c66b95ffc9e', - 'label': 'Brazil' - }, - { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' - } + {"uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", "label": "Brazil"}, + {"uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", "label": "Turkey"}, ], - 'matches': [ + "matches": [ { - 'uuid': '1e172084-ec76-4f56-bd8e-7b3c170e1221', - 'round': 1, - 'position': 0, - 'competitor_a': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' + "uuid": "1e172084-ec76-4f56-bd8e-7b3c170e1221", + "round": 1, + "position": 0, + "competitor_a": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", }, - 'competitor_b': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' + "competitor_b": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - 'winner': None, - 'loser': None + "winner": None, + "loser": None, }, { - 'uuid': '3866cad6-ba40-44fb-96c6-09f1131c5649', - 'round': 1, - 'position': 1, - 'competitor_a': { - 'uuid': '7f026276-0904-4a7b-ae14-8c66b95ffc9e', - 'label': 'Brazil' + "uuid": "3866cad6-ba40-44fb-96c6-09f1131c5649", + "round": 1, + "position": 1, + "competitor_a": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil", }, - 'competitor_b': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' + "competitor_b": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey", }, - 'winner': None, - 'loser': None + "winner": None, + "loser": None, }, { - 'uuid': '1f1fc156-4382-427c-aefb-5ae10009b7ce', - 'round': 0, - 'position': 0, - 'competitor_a': None, - 'competitor_b': None, - 'winner': None, - 'loser': None + "uuid": "1f1fc156-4382-427c-aefb-5ae10009b7ce", + "round": 0, + "position": 0, + "competitor_a": None, + "competitor_b": None, + "winner": None, + "loser": None, }, { - 'uuid': 'a9367a16-3f64-408b-9596-4029f7f60e62', - 'round': 0, - 'position': 1, - 'competitor_a': None, - 'competitor_b': None, - 'winner': None, - 'loser': None - } - ] + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "round": 0, + "position": 1, + "competitor_a": None, + "competitor_b": None, + "winner": None, + "loser": None, + }, + ], } ) assert isinstance(schema.tournament, TournamentAfterStartSchema) @@ -200,94 +187,94 @@ def test_tournament_start_schema(): def test_tournament_matches_schema(): schema = TournamentMatchesSchema( **{ - 'tournament': { - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', - 'starting_round': 1, - 'number_competitors': 4 + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "starting_round": 1, + "number_competitors": 4, }, - 'past': [ + "past": [ { - 'uuid': '1e172084-ec76-4f56-bd8e-7b3c170e1221', - 'round': 1, - 'position': 0, - 'competitor_a': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' + "uuid": "1e172084-ec76-4f56-bd8e-7b3c170e1221", + "round": 1, + "position": 0, + "competitor_a": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", }, - 'competitor_b': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' + "competitor_b": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - 'winner': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' + "winner": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", + }, + "loser": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - 'loser': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' - } }, { - 'uuid': '3866cad6-ba40-44fb-96c6-09f1131c5649', - 'round': 1, - 'position': 1, - 'competitor_a': { - 'uuid': '7f026276-0904-4a7b-ae14-8c66b95ffc9e', - 'label': 'Brazil' + "uuid": "3866cad6-ba40-44fb-96c6-09f1131c5649", + "round": 1, + "position": 1, + "competitor_a": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil", + }, + "competitor_b": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey", }, - 'competitor_b': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' + "winner": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil", }, - 'winner': { - 'uuid': '7f026276-0904-4a7b-ae14-8c66b95ffc9e', - 'label': 'Brazil' + "loser": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey", }, - 'loser': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' - } }, { - 'uuid': 'a9367a16-3f64-408b-9596-4029f7f60e62', - 'round': 0, - 'position': 1, - 'competitor_a': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "round": 0, + "position": 1, + "competitor_a": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - 'competitor_b': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' + "competitor_b": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey", }, - 'winner': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' + "winner": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey", }, - 'loser': { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' - } - } + "loser": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", + }, + }, ], - 'upcoming': [ + "upcoming": [ { - 'uuid': '1f1fc156-4382-427c-aefb-5ae10009b7ce', - 'round': 0, - 'position': 0, - 'competitor_a': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' + "uuid": "1f1fc156-4382-427c-aefb-5ae10009b7ce", + "round": 0, + "position": 0, + "competitor_a": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", }, - 'competitor_b': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Brazil' + "competitor_b": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil", }, - 'winner': None, - 'loser': None + "winner": None, + "loser": None, } - ] + ], } ) assert isinstance(schema.tournament, TournamentAfterStartSchema) @@ -300,31 +287,31 @@ def test_tournament_matches_schema(): def test_match_schema(): schema = MatchSchema( **{ - 'uuid': 'a9367a16-3f64-408b-9596-4029f7f60e62', - 'tournament': { - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', - 'starting_round': 1, - 'number_competitors': 4 + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "starting_round": 1, + "number_competitors": 4, + }, + "round": 0, + "position": 0, + "competitor_a": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", }, - 'round': 0, - 'position': 0, - 'competitor_a': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' + "competitor_b": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil", }, - 'competitor_b': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Brazil' + "winner": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil", }, - 'winner': { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Brazil' + "loser": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany", }, - 'loser': { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' - } } ) assert isinstance(schema.uuid, uuid.UUID) @@ -341,30 +328,21 @@ def test_match_schema(): def test_tournament_result_schema(): schema = TournamentResultSchema( **{ - 'tournament': { - 'uuid': '03c964f8-7f5c-4224-b848-1ab6c1413c7d', - 'label': '2002 FIFA World Cup', - 'starting_round': 1, - 'number_competitors': 4 + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "starting_round": 1, + "number_competitors": 4, }, - 'top4': [ + "top4": [ + {"uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", "label": "Brazil"}, + {"uuid": "de686e37-804b-4815-a507-d5879a240af6", "label": "Germany"}, + {"uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", "label": "Turkey"}, { - 'uuid': '7f026276-0904-4a7b-ae14-8c66b95ffc9e', - 'label': 'Brazil' + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea", }, - { - 'uuid': 'de686e37-804b-4815-a507-d5879a240af6', - 'label': 'Germany' - }, - { - 'uuid': '15f4fe33-f317-4c4a-96e0-3b815dc481c6', - 'label': 'Turkey' - }, - { - 'uuid': '5d1bd1d1-2679-432a-ac11-ebfebfa1bce9', - 'label': 'South Korea' - } - ] + ], }, ) assert isinstance(schema.tournament, TournamentAfterStartSchema) diff --git a/tests/utils.py b/tests/utils.py index b465c86..0a90710 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,10 +4,8 @@ from sqlalchemy.orm import Session, joinedload from matamata.models import Match, Tournament, TournamentCompetitor -from matamata.services import ( - register_match_result as register_match_result_service, - start_tournament as start_tournament_service, -) +from matamata.services import register_match_result as register_match_result_service +from matamata.services import start_tournament as start_tournament_service def retrieve_tournament_competitor( @@ -17,8 +15,7 @@ def retrieve_tournament_competitor( session: Session, ) -> TournamentCompetitor: tournament_competitor = session.scalar( - select(TournamentCompetitor) - .where( + select(TournamentCompetitor).where( TournamentCompetitor.tournament_id == tournament_id, TournamentCompetitor.competitor_id == competitor_id, ) @@ -77,8 +74,9 @@ def retrieve_tournament_with_competitors( select(Tournament) .where(Tournament.uuid == tournament_uuid) .options( - joinedload(Tournament.competitor_associations) - .subqueryload(TournamentCompetitor.competitor) + joinedload(Tournament.competitor_associations).subqueryload( + TournamentCompetitor.competitor + ) ) )