diff --git a/backend/bracket/routes/stages.py b/backend/bracket/routes/stages.py index ea70974d..6ab47e16 100644 --- a/backend/bracket/routes/stages.py +++ b/backend/bracket/routes/stages.py @@ -61,7 +61,7 @@ async def delete_stage( detail="Stage contains stage items, please delete those first", ) - if stage.is_active: + if stage.is_active and len(stage.stage_items) > 0: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Stage is active, please activate another stage first", diff --git a/backend/bracket/routes/tournaments.py b/backend/bracket/routes/tournaments.py index 0214867f..0a3547ba 100644 --- a/backend/bracket/routes/tournaments.py +++ b/backend/bracket/routes/tournaments.py @@ -109,7 +109,14 @@ async def update_tournament_by_id( async def delete_tournament( tournament_id: TournamentId, _: UserPublic = Depends(user_authenticated_for_tournament) ) -> SuccessResponse: - with check_foreign_key_violation({ForeignKey.stages_tournament_id_fkey}): + with check_foreign_key_violation( + { + ForeignKey.stages_tournament_id_fkey, + ForeignKey.teams_tournament_id_fkey, + ForeignKey.players_tournament_id_fkey, + ForeignKey.courts_tournament_id_fkey, + } + ): await sql_delete_tournament(tournament_id) return SuccessResponse() diff --git a/backend/bracket/utils/errors.py b/backend/bracket/utils/errors.py index 3174bcac..f4cdc0b6 100644 --- a/backend/bracket/utils/errors.py +++ b/backend/bracket/utils/errors.py @@ -16,12 +16,16 @@ class UniqueIndex(EnumAutoStr): class ForeignKey(EnumAutoStr): - stages_tournament_id_fkey = auto() - tournaments_club_id_fkey = auto() - stage_item_inputs_team_id_fkey = auto() + courts_tournament_id_fkey = auto() matches_team1_id_fkey = auto() - matches_team2_id_fkey = auto() matches_team1_winner_from_stage_item_id_fkey = auto() + matches_team2_id_fkey = auto() + matches_team2_winner_from_stage_item_id_fkey = auto() + players_tournament_id_fkey = auto() + stage_item_inputs_team_id_fkey = auto() + stages_tournament_id_fkey = auto() + teams_tournament_id_fkey = auto() + tournaments_club_id_fkey = auto() unique_index_violation_error_lookup = { @@ -31,13 +35,18 @@ unique_index_violation_error_lookup = { foreign_key_violation_error_lookup = { - ForeignKey.stages_tournament_id_fkey: "This tournament still has stages, delete those first", - ForeignKey.tournaments_club_id_fkey: "This club still has tournaments, delete those first", - ForeignKey.stage_item_inputs_team_id_fkey: "This team is still used in stage items", + ForeignKey.courts_tournament_id_fkey: "This tournament still has courts, delete those first", ForeignKey.matches_team1_id_fkey: "This team is still part of matches", - ForeignKey.matches_team2_id_fkey: "This team is still part of matches", ForeignKey.matches_team1_winner_from_stage_item_id_fkey: "This stage item is referenced by " "other stage items", + ForeignKey.matches_team2_id_fkey: "This team is still part of matches", + ForeignKey.matches_team2_winner_from_stage_item_id_fkey: "This stage item is referenced by " + "other stage items", + ForeignKey.players_tournament_id_fkey: "This tournament still has players, delete those first", + ForeignKey.stage_item_inputs_team_id_fkey: "This team is still used in stage items", + ForeignKey.stages_tournament_id_fkey: "This tournament still has stages, delete those first", + ForeignKey.teams_tournament_id_fkey: "This tournament still has teams, delete those first", + ForeignKey.tournaments_club_id_fkey: "This club still has tournaments, delete those first", } diff --git a/backend/pyproject.toml b/backend/pyproject.toml index cc2bbdc7..0f888842 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -70,6 +70,7 @@ disable = [ 'unspecified-encoding', 'unused-argument', # Gives false positives. 'wrong-import-position', + 'contextmanager-generator-missing-cleanup', # Gives false positives. ] [tool.bandit] diff --git a/backend/tests/integration_tests/conftest.py b/backend/tests/integration_tests/conftest.py index e930814b..0b8871d3 100644 --- a/backend/tests/integration_tests/conftest.py +++ b/backend/tests/integration_tests/conftest.py @@ -72,6 +72,5 @@ async def reinit_database(event_loop: AbstractEventLoop, worker_id: str) -> Asyn @pytest.fixture(scope="session") async def auth_context(reinit_database: Database) -> AsyncIterator[AuthContext]: - async with reinit_database: - async with inserted_auth_context() as auth_context: - yield auth_context + async with reinit_database, inserted_auth_context() as auth_context: + yield auth_context diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index b3e7a13e..6172466a 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -140,9 +140,11 @@ "negative_match_margin_validation": "Match margin cannot be negative", "negative_score_validation": "Score cannot be negative", "next_matches_badge": "Next matches", - "next_stage_button": "Go to Next Stage", + "next_stage_button": "Next Stage", "no_matches_description": "First, add matches by creating stages and stage items. Then, schedule them using the button in the topright corner.", "no_matches_title": "No matches scheduled yet", + "no_players_title": "No players yet", + "no_teams_title": "No teams yet", "no_round_description": "There are no rounds in this stage item yet", "no_round_found_description": "Please wait for the organiser to add them.", "no_round_found_in_stage_description": "There are no rounds in this stage yet", @@ -168,7 +170,7 @@ "players_spotlight_description": "View, add or delete players", "players_title": "players", "policy_not_accepted": "Please indicate that you have read the policy", - "previous_stage_button": "Go to Previous Stage", + "previous_stage_button": "Previous Stage", "recommended_badge_title": "Recommended", "remove_logo": "Remove logo", "remove_match_button": "Remove Match", diff --git a/frontend/src/components/buttons/create_stage.tsx b/frontend/src/components/buttons/create_stage.tsx index be143f7c..1bcf4dab 100644 --- a/frontend/src/components/buttons/create_stage.tsx +++ b/frontend/src/components/buttons/create_stage.tsx @@ -47,7 +47,7 @@ export function CreateStageButtonLarge({ variant="outline" color="green" size="lg" - style={{ marginRight: 10, width: '25%' }} + style={{ marginRight: 10 }} onClick={async () => { await createStage(tournament.id); await swrStagesResponse.mutate(); diff --git a/frontend/src/components/modals/club_modal.tsx b/frontend/src/components/modals/club_modal.tsx index a4d48cf5..8060afec 100644 --- a/frontend/src/components/modals/club_modal.tsx +++ b/frontend/src/components/modals/club_modal.tsx @@ -1,4 +1,4 @@ -import { Button, Group, Modal, TextInput } from '@mantine/core'; +import { Button, Modal, TextInput } from '@mantine/core'; import { useForm } from '@mantine/form'; import { BiEditAlt } from '@react-icons/all-files/bi/BiEditAlt'; import { GoPlus } from '@react-icons/all-files/go/GoPlus'; @@ -23,13 +23,13 @@ export default function ClubModal({ const icon = is_create_form ? : ; const [opened, setOpened] = useState(false); const modalOpenButton = is_create_form ? ( - - setOpened(true)} - leftSection={} - title={operation_text} - /> - + setOpened(true)} + leftSection={} + title={operation_text} + /> ) : (