From 8fc76fd317ba9c095a7611045603c56f0d78c05e Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Mon, 29 Sep 2025 20:31:03 +0300 Subject: [PATCH] Fix crash when starting second Swiss bracket in the same tournament TournamentStage.number is a running number for Swiss now as well. Before was hardcoded as 1. Running number was already in use in bracket-manager so this was just an oversight. Crash was caused by database unique constaint --- .../createSwissBracketInTransaction.server.ts | 3 +- e2e/tournament-bracket.spec.ts | 58 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/app/features/tournament/queries/createSwissBracketInTransaction.server.ts b/app/features/tournament/queries/createSwissBracketInTransaction.server.ts index 9859b2389..92b46418d 100644 --- a/app/features/tournament/queries/createSwissBracketInTransaction.server.ts +++ b/app/features/tournament/queries/createSwissBracketInTransaction.server.ts @@ -18,7 +18,7 @@ const createTournamentStageStm = sql.prepare(/* sql */ ` @type, @createdAt, @settings, - @number, + (select coalesce(max("number"), 0) + 1 from "TournamentStage" where "tournamentId" = @tournamentId), @name ) returning * `); @@ -81,7 +81,6 @@ export function createSwissBracketInTransaction( type: stageInput.type, createdAt: dateToDatabaseTimestamp(new Date()), settings: JSON.stringify(stageInput.settings), - number: stageInput.number, name: stageInput.name, }) as Tables["TournamentStage"]; diff --git a/e2e/tournament-bracket.spec.ts b/e2e/tournament-bracket.spec.ts index 32a7a3c61..b3d572fb0 100644 --- a/e2e/tournament-bracket.spec.ts +++ b/e2e/tournament-bracket.spec.ts @@ -542,7 +542,7 @@ test.describe("Tournament bracket", () => { }) => { const tournamentId = 4; - await seed(page, "SMALL_SOS"); + await seed(page); await impersonate(page); await navigate({ @@ -552,34 +552,56 @@ test.describe("Tournament bracket", () => { await page.getByTestId("edit-event-info-button").click(); await page.getByTestId("delete-bracket-button").last().click(); - await page.getByTestId("delete-bracket-button").last().click(); - await page.getByTestId("delete-bracket-button").last().click(); - await page.getByTestId("follow-up-bracket-switch").click(); + for (const toggle of await page + .getByTestId("follow-up-bracket-switch") + .all()) { + await toggle.click(); + } + await page.getByLabel("Format").first().selectOption("Single-elimination"); + await page.getByLabel("Format").nth(1).selectOption("Single-elimination"); + await page.getByLabel("Format").nth(2).selectOption("Swiss"); + await page.getByLabel("Format").nth(3).selectOption("Swiss"); await submit(page); await page.getByText("Seeds").click(); await page.getByTestId("set-starting-brackets").click(); - await page - .getByTestId("starting-bracket-select") - .first() - .selectOption("Great White"); - await page - .getByTestId("starting-bracket-select") - .nth(1) - .selectOption("Great White"); + for (let i = 0; i < 16; i++) { + let bracketName: string; + if (i < 4) { + bracketName = "Groups stage"; + } else if (i < 8) { + bracketName = "Great White"; + } else if (i < 12) { + bracketName = "Hammerhead"; + } else { + bracketName = "Mako"; + } + + await page + .getByTestId("starting-bracket-select") + .nth(i) + .selectOption(bracketName); + } await submit(page, "set-starting-brackets-submit-button"); - await page.getByTestId("brackets-tab").click(); - await page.getByText("Great White").click(); - await page.getByTestId("finalize-bracket-button").click(); - await page.getByTestId("confirm-finalize-bracket-button").click(); - await expect(page.locator('[data-match-id="1"]')).toBeVisible(); - await isNotVisible(page.locator('[data-match-id="2"]')); + await page.getByTestId("brackets-tab").click(); + for (const bracketName of [ + "Groups stage", + "Great White", + "Hammerhead", + "Mako", + ]) { + await page.getByRole("button", { name: bracketName }).click(); + await page.getByTestId("finalize-bracket-button").click(); + await page.getByTestId("confirm-finalize-bracket-button").click(); + } + + await expect(page.locator('[data-match-id="11"]')).toBeVisible(); }); test("organizer edits a match after it is done", async ({ page }) => {