mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-30 07:44:43 -05:00
209 lines
7.1 KiB
TypeScript
209 lines
7.1 KiB
TypeScript
import { addHours } from "date-fns";
|
|
import { NZAP_TEST_ID } from "~/db/seed/constants";
|
|
import { ADMIN_ID } from "~/features/admin/admin-constants";
|
|
import { dateToDatabaseTimestamp } from "~/utils/dates";
|
|
import {
|
|
expect,
|
|
impersonate,
|
|
isNotVisible,
|
|
navigate,
|
|
test,
|
|
waitForPOSTResponse,
|
|
} from "./helpers/playwright";
|
|
import { CalendarNewEventPage } from "./pages/calendar/calendar-new-event-page";
|
|
import { AnythingAdder } from "./pages/layout/anything-adder";
|
|
import { NewOrganizationPage } from "./pages/org/new-organization-page";
|
|
import { OrganizationPage } from "./pages/org/organization-page";
|
|
import { TournamentPage } from "./pages/tournament/tournament-page";
|
|
|
|
const ORGANIZATION_NAME = "Sendou.ink";
|
|
const TOURNAMENT_NAME = "PICNIC #2";
|
|
const PLAYER_NAME = "Banned Bob";
|
|
|
|
test.describe("Tournament Organization", () => {
|
|
test("can create a new organization", async ({ page, factories }) => {
|
|
const organizer = await factories.UserFactory.create(null, {
|
|
roles: ["TOURNAMENT_ORGANIZER"],
|
|
});
|
|
|
|
await impersonate(page, organizer.id);
|
|
await navigate({ page, url: "/" });
|
|
|
|
await new AnythingAdder(page).add("organization");
|
|
|
|
const newOrganization = new NewOrganizationPage(page);
|
|
await newOrganization.form.fill("name", "Test Organization");
|
|
await newOrganization.save();
|
|
|
|
const organization = new OrganizationPage(page);
|
|
await expect(organization.locators.editButton).toBeVisible();
|
|
});
|
|
|
|
test("user can be promoted to admin gaining org controls and can edit tournaments", async ({
|
|
page,
|
|
factories,
|
|
}) => {
|
|
const org = await factories.TournamentOrganizationFactory.create(
|
|
{ ownerId: ADMIN_ID, name: ORGANIZATION_NAME },
|
|
{ members: [{ userId: NZAP_TEST_ID, role: "MEMBER" }] },
|
|
);
|
|
const tournament = await factories.TournamentFactory.create({
|
|
authorId: ADMIN_ID,
|
|
name: TOURNAMENT_NAME,
|
|
organizationId: org.id,
|
|
startTimes: [dateToDatabaseTimestamp(addHours(new Date(), 2))],
|
|
});
|
|
|
|
const organization = new OrganizationPage(page);
|
|
|
|
// 1. As a regular user, verify edit controls are not visible
|
|
await impersonate(page, NZAP_TEST_ID);
|
|
await organization.goto(org.slug);
|
|
await isNotVisible(organization.locators.editButton);
|
|
|
|
// 2. As admin, promote user to admin
|
|
await impersonate(page, ADMIN_ID);
|
|
await organization.goto(org.slug);
|
|
const organizationEdit = await organization.openEdit();
|
|
await organizationEdit.setMemberRole("N-ZAP", "ADMIN");
|
|
await organizationEdit.save();
|
|
|
|
// Establish the organization so its admins can edit tournament event info
|
|
await organization.goto(org.slug);
|
|
await organization.establish();
|
|
|
|
// 3. As the promoted user, verify edit controls are visible and page can be accessed
|
|
await impersonate(page, NZAP_TEST_ID);
|
|
await organization.goto(org.slug);
|
|
await organization.openEdit();
|
|
await expect(organizationEdit.locators.title).toBeVisible();
|
|
|
|
// 4. As the promoted user, verify they can edit tournaments
|
|
const tournamentPage = new TournamentPage(page);
|
|
await tournamentPage.goto(tournament.id);
|
|
|
|
const tournamentAdmin = await tournamentPage.nav.openAdmin();
|
|
const calendarEvent = await tournamentAdmin.editEventInfo();
|
|
await expect(calendarEvent.locators.nameInput).toHaveValue(TOURNAMENT_NAME);
|
|
});
|
|
|
|
test("banned player cannot join a tournament of that organization", async ({
|
|
page,
|
|
factories,
|
|
}) => {
|
|
const player = await factories.UserFactory.create({
|
|
discordName: PLAYER_NAME,
|
|
});
|
|
const org = await factories.TournamentOrganizationFactory.create({
|
|
ownerId: ADMIN_ID,
|
|
name: ORGANIZATION_NAME,
|
|
});
|
|
const tournament = await factories.TournamentFactory.create({
|
|
authorId: ADMIN_ID,
|
|
name: TOURNAMENT_NAME,
|
|
organizationId: org.id,
|
|
startTimes: [dateToDatabaseTimestamp(addHours(new Date(), 2))],
|
|
});
|
|
|
|
const organization = new OrganizationPage(page);
|
|
const tournamentPage = new TournamentPage(page);
|
|
|
|
// 1. As admin, ban the player from the organization
|
|
await impersonate(page, ADMIN_ID);
|
|
await organization.goto(org.slug);
|
|
await organization.openBannedUsers();
|
|
|
|
const banModal = await organization.openBanModal();
|
|
await expect(banModal.locators.dialog).toBeVisible();
|
|
await banModal.selectUser(PLAYER_NAME);
|
|
await banModal.form.fill("privateNote", "Test reason");
|
|
// a future expiration date to avoid validation issues
|
|
await banModal.form.setDateTime("expiresAt", addHours(new Date(), 24));
|
|
await banModal.save();
|
|
|
|
await expect(organization.locators.bannedUsersTable).toContainText(
|
|
"Test reason",
|
|
);
|
|
|
|
// 2. As the banned user, try to join a tournament
|
|
await impersonate(page, player.id);
|
|
await tournamentPage.goto(tournament.id);
|
|
|
|
const register = await tournamentPage.register();
|
|
await register.form.fill("pickUpName", "Banned Team");
|
|
await waitForPOSTResponse(page, () => register.form.submit());
|
|
|
|
// "Fill roster" only appears after a successful registration
|
|
await expect(register.locators.fillRosterHeading).not.toBeVisible();
|
|
|
|
// 3. As admin, remove the ban
|
|
await impersonate(page, ADMIN_ID);
|
|
await organization.goto(org.slug);
|
|
await organization.openBannedUsers();
|
|
await organization.unban();
|
|
|
|
// 4. As the unbanned user, verify they can now join a tournament
|
|
await impersonate(page, player.id);
|
|
await tournamentPage.goto(tournament.id);
|
|
const registerAgain = await tournamentPage.register();
|
|
|
|
const teamsTab = tournamentPage.nav.locators.teamsTab;
|
|
await expect(teamsTab).toContainText("Teams (0)");
|
|
|
|
await registerAgain.form.fill("pickUpName", "Unbanned Team");
|
|
await registerAgain.form.submit();
|
|
|
|
await expect(teamsTab).toContainText("Teams (1)");
|
|
|
|
// 5. As admin, ban user again but with permanent ban this time
|
|
await impersonate(page, ADMIN_ID);
|
|
await organization.goto(org.slug);
|
|
await organization.openBannedUsers();
|
|
|
|
const permanentBanModal = await organization.openBanModal();
|
|
await expect(permanentBanModal.locators.dialog).toBeVisible();
|
|
await permanentBanModal.selectUser(PLAYER_NAME);
|
|
await permanentBanModal.form.fill("privateNote", "Does not expire");
|
|
// expiresAt left empty makes the ban permanent
|
|
await permanentBanModal.save();
|
|
|
|
await expect(organization.locators.bannedUsersTable).toContainText(
|
|
"Permanent",
|
|
);
|
|
});
|
|
|
|
test("allows member of established org to create tournament", async ({
|
|
page,
|
|
factories,
|
|
}) => {
|
|
const orgAdmin = await factories.UserFactory.create();
|
|
const org = await factories.TournamentOrganizationFactory.create(
|
|
{ ownerId: ADMIN_ID, name: ORGANIZATION_NAME },
|
|
{ members: [{ userId: orgAdmin.id, role: "ADMIN" }] },
|
|
);
|
|
|
|
const newTournament = new CalendarNewEventPage(page);
|
|
|
|
await impersonate(page, orgAdmin.id);
|
|
await newTournament.gotoNewTournament();
|
|
|
|
await expect(
|
|
newTournament.locators.noTournamentPermissionsAlert,
|
|
).toBeVisible();
|
|
await expect(newTournament.locators.newTournamentHeading).not.toBeVisible();
|
|
|
|
await impersonate(page, ADMIN_ID);
|
|
const organization = new OrganizationPage(page);
|
|
await organization.goto(org.slug);
|
|
await organization.establish();
|
|
|
|
await impersonate(page, orgAdmin.id);
|
|
await newTournament.gotoNewTournament();
|
|
|
|
await expect(
|
|
newTournament.locators.noTournamentPermissionsAlert,
|
|
).not.toBeVisible();
|
|
await expect(newTournament.locators.newTournamentHeading).toBeVisible();
|
|
});
|
|
});
|