Skip to content

SCRUM-27 - implement tournament planning and ladder tests#15

Open
Peres270 wants to merge 5 commits intomasterfrom
SCRUM-27-tournament-planning-implementation
Open

SCRUM-27 - implement tournament planning and ladder tests#15
Peres270 wants to merge 5 commits intomasterfrom
SCRUM-27-tournament-planning-implementation

Conversation

@Peres270
Copy link
Copy Markdown
Contributor

Description
This pull request implements the tournament ladder planning feature on the frontend.

Main changes

  • Added ladder page (/t/[id]/ladder)
  • Implemented tournament planning form with validation
  • Integrated server action (planTournament)
  • Added placeholder for ladder visualization
  • Created Phase type
  • Connected UI with backend via fetchServerside

Validation logic

  • All inputs must be positive integers
  • advancing_teams must be a power of two
  • Proper error handling for failed requests

Backend note

The /tournament/{id}/plan endpoint is not yet implemented.
As specified in the task, the success state is mocked in unit tests.

Testing

  • I have run all tests and ensured that they pass consistently.
  • Added unit tests for planTournament using Jest
  • Mocked fetchServerside to simulate backend responses (200 / error)
  • Covered validation logic and request handling

Copy link
Copy Markdown
Member

@Mateusz-Dobrzynski Mateusz-Dobrzynski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review and tested; all good. I managed to figure out issues I had with testing previously. My setup was faulty; gotta make sure to document what I've learned along the way.

image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear: you do not have to include Polish translations. They will have to be revised by Polish native speakers either way. Updating en.json alone would have been enough.

@Akirus12
Copy link
Copy Markdown

Akirus12 commented Apr 7, 2026

I'm getting errors from the playwright part- since I pulled this from GitHub I, once again, had to change the address in fetchServerSide, utils.ts from http://localhost:2023 to http://127.0.0.1:2023. So, the errors might come from that change.

Test info

  • Name: tournament creation >> creates tournament successfully
  • Location: tournament.test.ts:33:7

Error details

Error: expect(locator).toBeVisible() failed

Locator:  getByText('Tournament 1775554526246')
Expected: visible
Received: <element(s) not found>
Timeout:  5000ms

Call log:
  - Expect "toBeVisible" with timeout 5000ms
  - waiting for getByText('Tournament 1775554526246')


  46 |     await page.getByRole("button", { name: "Create", exact: true }).click();
  47 |
> 48 |     await expect(page.getByText(fullName)).toBeVisible();
     |                                            ^
  49 |   });
  50 |
  51 |   test("shows error when creating duplicate tournament", async ({ page }) => {
    at /home/akirus/Documents/UNI/Semester Project/granda-front/test/e2e/tournament.test.ts:48:44

Page snapshot

- generic [active] [ref=e1]:
  - button "Open Next.js Dev Tools" [ref=e7] [cursor=pointer]:
    - img [ref=e8] [cursor=pointer]
  - alert [ref=e11]
  - generic [ref=e12]:
    - heading "Welcome, admin!" [level=1] [ref=e13]
    - paragraph [ref=e14]: Here's a selection of tournaments you can access.
    - button "Create tournament" [ref=e15]
    - generic [ref=e17]:
      - generic [ref=e18]:
        - heading "Create tournament" [level=2] [ref=e19]
        - button "Close" [ref=e20]
      - generic [ref=e21]:
        - generic [ref=e22]:
          - generic [ref=e23]: Full name
          - textbox "Full name" [ref=e24]
        - generic [ref=e25]:
          - generic [ref=e26]: Short name
          - textbox "Short name" [ref=e27]
        - paragraph [ref=e28]: Failed to create tournament.
        - button "Create" [ref=e29]
    - paragraph [ref=e31]: There aren't any tournaments you're a part of yet.
    - paragraph [ref=e32]:
      - text: Alternatively, back to the
      - link "login page" [ref=e33] [cursor=pointer]:
        - /url: /en/login
      - text: .

Test source

   1 | import { test, expect } from "@playwright/test";
   2 |
   3 | test.describe("tournament creation", () => {
   4 |   test.beforeEach(async ({ page }) => {
   5 |     await page.goto("/en/login");
   6 |
   7 |     await page
   8 |       .getByRole("textbox", { name: "Your handle (username)" })
   9 |       .fill("admin");
  10 |
  11 |     await page.getByRole("textbox", { name: "Your password" }).fill("admin");
  12 |
  13 |     await page.getByRole("button", { name: "Log in" }).click();
  14 |
  15 |     await page.waitForURL("/en/tournaments");
  16 |   });
  17 |
  18 |   test("admin sees create tournament button", async ({ page }) => {
  19 |     const button = page.getByRole("button", { name: "Create tournament" });
  20 |     await expect(button).toBeVisible();
  21 |   });
  22 |
  23 |   test("opens create tournament modal", async ({ page }) => {
  24 |     await page.getByRole("button", { name: "Create tournament" }).click();
  25 |
  26 |     await expect(
  27 |       page.getByRole("heading", { name: "Create tournament" }),
  28 |     ).toBeVisible();
  29 |     await expect(page.getByLabel("Full name")).toBeVisible();
  30 |     await expect(page.getByLabel("Short name")).toBeVisible();
  31 |   });
  32 |
  33 |   test("creates tournament successfully", async ({ page }) => {
  34 |     await page.getByRole("button", { name: "Create tournament" }).click();
  35 |
  36 |     await expect(
  37 |       page.getByRole("heading", { name: "Create tournament" }),
  38 |     ).toBeVisible();
  39 |
  40 |     const unique = Date.now();
  41 |     const fullName = `Tournament ${unique}`;
  42 |     const shortName = `T${unique}`;
  43 |
  44 |     await page.getByLabel("Full name").fill(fullName);
  45 |     await page.getByLabel("Short name").fill(shortName);
  46 |     await page.getByRole("button", { name: "Create", exact: true }).click();
  47 |
> 48 |     await expect(page.getByText(fullName)).toBeVisible();
     |                                            ^ Error: expect(locator).toBeVisible() failed
  49 |   });
  50 |
  51 |   test("shows error when creating duplicate tournament", async ({ page }) => {
  52 |     const unique = Date.now();
  53 |     const fullName = `Tournament ${unique}`;
  54 |     const shortName = `T${unique}`;
  55 |
  56 |     await page.getByRole("button", { name: "Create tournament" }).click();
  57 |
  58 |     await expect(
  59 |       page.getByRole("heading", { name: "Create tournament" }),
  60 |     ).toBeVisible();
  61 |
  62 |     await page.getByLabel("Full name").fill(fullName);
  63 |     await page.getByLabel("Short name").fill(shortName);
  64 |     await page.getByRole("button", { name: "Create", exact: true }).click();
  65 |
  66 |     await expect(
  67 |       page.getByRole("heading", { name: "Create tournament" }),
  68 |     ).not.toBeVisible();
  69 |
  70 |     await expect(page.getByText(fullName)).toBeVisible();
  71 |
  72 |     await page.getByRole("button", { name: "Create tournament" }).click();
  73 |
  74 |     await expect(
  75 |       page.getByRole("heading", { name: "Create tournament" }),
  76 |     ).toBeVisible();
  77 |
  78 |     await page.getByLabel("Full name").fill(fullName);
  79 |     await page.getByLabel("Short name").fill(shortName);
  80 |     await page.getByRole("button", { name: "Create", exact: true }).click();
  81 |
  82 |     await expect(page.locator("form")).toContainText(
  83 |       /failed to create tournament/i,
  84 |     );
  85 |   });
  86 | });
  87 |
  88 | //

Copy link
Copy Markdown
Member

@Mateusz-Dobrzynski Mateusz-Dobrzynski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a path mismatch. Please update it (in the marked line and any other, if applicable) and make sure it works.

};
}

const res = await fetchServerside(`/tournament/${tournamentId}/plan`, {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpoint path has changed and therefore the tournament creation tests fail. @Peres270, please update this and see if the tests pass.

Suggested change
const res = await fetchServerside(`/tournament/${tournamentId}/plan`, {
const res = await fetchServerside(`/tournaments/${tournamentId}/plan`, {

@Peres270
Copy link
Copy Markdown
Contributor Author

I fixed the endpoint path in ladder-actions.ts (/tournaments/${tournamentId}/plan) and pushed the changes in commit ea13e94. The branch is up to date. Could you please re-review?
I am not sure but i see the changes in the code , but it is telling that the tests are failing i don´t know why, if we could see that tomorrow i appreciate it, sorry for the hours

Copy link
Copy Markdown
Member

@Mateusz-Dobrzynski Mateusz-Dobrzynski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix a failing unit test.

// THEN
expect(mockedFetchServerside).toHaveBeenCalledTimes(1);
expect(mockedFetchServerside).toHaveBeenCalledWith(
"/tournament/test-tournament-id/plan",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"/tournament/test-tournament-id/plan",
"/tournaments/test-tournament-id/plan",

Tests fail; this is probably the reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants