mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-25 20:50:14 -05:00
Fix tournament delete permission check
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
import type { ActionFunction } from "react-router";
|
||||
import { redirect } from "react-router";
|
||||
import * as v from "valibot";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server";
|
||||
import * as BracketRepository from "~/features/tournament-bracket/BracketRepository.server";
|
||||
import { clearTournamentDataCache } from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import {
|
||||
clearTournamentDataCache,
|
||||
tournamentFromDB,
|
||||
} from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import { requirePermission } from "~/modules/permissions/guards.server";
|
||||
import { errorToastIfFalsy, notFoundIfNullish } from "~/utils/remix.server";
|
||||
import {
|
||||
errorToastIfFalsy,
|
||||
forbidden,
|
||||
notFoundIfNullish,
|
||||
} from "~/utils/remix.server";
|
||||
import { actualNumber, id, preprocess } from "~/utils/schema";
|
||||
import { CALENDAR_PAGE } from "~/utils/urls";
|
||||
|
||||
@@ -19,14 +26,17 @@ export const action: ActionFunction = async ({ params }) => {
|
||||
await CalendarRepository.findById(parsedParams.id),
|
||||
);
|
||||
|
||||
requirePermission(event, "DELETE");
|
||||
|
||||
if (event.tournamentId) {
|
||||
errorToastIfFalsy(
|
||||
(await BracketRepository.findByTournamentId(event.tournamentId)).stage
|
||||
.length === 0,
|
||||
"Tournament has already started",
|
||||
);
|
||||
const user = requireUser();
|
||||
const tournament = await tournamentFromDB(event.tournamentId);
|
||||
|
||||
if (!tournament.canEditEventInfo(user)) {
|
||||
throw forbidden();
|
||||
}
|
||||
|
||||
errorToastIfFalsy(!tournament.hasStarted, "Tournament has already started");
|
||||
} else {
|
||||
requirePermission(event, "DELETE");
|
||||
}
|
||||
|
||||
await CalendarRepository.deleteById({
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { addDays } from "date-fns";
|
||||
import { addDays, subDays } from "date-fns";
|
||||
import type * as v from "valibot";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import * as TournamentFactory from "~/db/seed/factories/TournamentFactory";
|
||||
import * as TournamentOrganizationFactory from "~/db/seed/factories/TournamentOrganizationFactory";
|
||||
import * as UserFactory from "~/db/seed/factories/UserFactory";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import { dateToDatabaseTimestamp } from "~/utils/dates";
|
||||
@@ -47,4 +48,43 @@ describe("calendar event deletion", () => {
|
||||
const eventAfter = await CalendarRepository.findById(tournament.eventId);
|
||||
expect(eventAfter).toBeNull();
|
||||
});
|
||||
|
||||
test("lets the author delete a tournament whose start time passed without it ever starting", async () => {
|
||||
await UserFactory.createAdmin();
|
||||
const regular = await UserFactory.createRegular();
|
||||
const tournament = await TournamentFactory.create({
|
||||
authorId: regular.id,
|
||||
startTimes: [dateToDatabaseTimestamp(subDays(new Date(), 2))],
|
||||
});
|
||||
|
||||
await deleteAction(
|
||||
{},
|
||||
{ user: "regular", params: { id: String(tournament.eventId) } },
|
||||
);
|
||||
|
||||
const eventAfter = await CalendarRepository.findById(tournament.eventId);
|
||||
expect(eventAfter).toBeNull();
|
||||
});
|
||||
|
||||
test("lets an admin of an established organization delete its tournament", async () => {
|
||||
const admin = await UserFactory.createAdmin();
|
||||
await UserFactory.createRegular();
|
||||
const orgAdmin = await UserFactory.create();
|
||||
const organization = await TournamentOrganizationFactory.create(
|
||||
{ ownerId: orgAdmin.id },
|
||||
{ isEstablished: true },
|
||||
);
|
||||
const tournament = await TournamentFactory.create({
|
||||
authorId: admin.id,
|
||||
organizationId: organization.id,
|
||||
});
|
||||
|
||||
await deleteAction(
|
||||
{},
|
||||
{ user: orgAdmin.id, params: { id: String(tournament.eventId) } },
|
||||
);
|
||||
|
||||
const eventAfter = await CalendarRepository.findById(tournament.eventId);
|
||||
expect(eventAfter).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user