diff --git a/app/features/admin/routes/admin.test.ts b/app/features/admin/routes/admin.test.ts index 528430062..2d23a27b8 100644 --- a/app/features/admin/routes/admin.test.ts +++ b/app/features/admin/routes/admin.test.ts @@ -124,7 +124,7 @@ describe("Plus voting", () => { test("combines leaderboard and voting results (after season over)", async () => { vi.setSystemTime(new Date("2023-11-29T00:00:00.000Z")); - await dbInsertUsers(2); + await dbInsertUsers(); await PlusVotingRepository.upsertMany([ voteArgs({ score: 1, @@ -177,7 +177,7 @@ describe("Plus voting", () => { test("ignores leaderboard while season is ongoing", async () => { vi.setSystemTime(new Date("2024-02-15T00:00:00.000Z")); - await dbInsertUsers(2); + await dbInsertUsers(); await PlusVotingRepository.upsertMany([ voteArgs({ score: 1, diff --git a/app/features/team/actions/t.server.test.ts b/app/features/team/actions/t.server.test.ts new file mode 100644 index 000000000..f548fcef8 --- /dev/null +++ b/app/features/team/actions/t.server.test.ts @@ -0,0 +1,30 @@ +import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { dbInsertUsers, dbReset, wrappedAction } from "~/utils/Test"; +import { action as teamIndexPageAction } from "../actions/t.server"; +import type { createTeamSchema } from "../team-schemas.server"; + +const action = wrappedAction({ + action: teamIndexPageAction, +}); + +describe("team creation", () => { + beforeEach(async () => { + await dbInsertUsers(); + }); + afterEach(() => { + dbReset(); + }); + + it("prevents creating a team with a duplicate name", async () => { + await action({ name: "Team 1" }, { user: "regular" }); + const res = await action({ name: "Team 1" }, { user: "regular" }); + + expect(res.errors[0]).toBe("forms.errors.duplicateName"); + }); + + it("prevents creating a team whose name is only special characters", async () => { + expect(action({ name: "𝓢𝓲𝓵" }, { user: "regular" })).rejects.toThrow( + "status code: 400", + ); + }); +}); diff --git a/app/features/team/routes/t.$customUrl.edit.test.ts b/app/features/team/routes/t.$customUrl.edit.test.ts new file mode 100644 index 000000000..cd4f4c8a3 --- /dev/null +++ b/app/features/team/routes/t.$customUrl.edit.test.ts @@ -0,0 +1,59 @@ +import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { dbInsertUsers, dbReset, wrappedAction } from "~/utils/Test"; +import { action as teamIndexPageAction } from "../actions/t.server"; +import { action as _editTeamAction } from "../routes/t.$customUrl.edit"; +import type { createTeamSchema, editTeamSchema } from "../team-schemas.server"; + +const createTeamAction = wrappedAction({ + action: teamIndexPageAction, +}); + +const editTeamAction = wrappedAction({ + action: _editTeamAction, +}); + +describe("team creation", () => { + beforeEach(async () => { + await dbInsertUsers(); + }); + afterEach(() => { + dbReset(); + }); + + it("can't take another team's name via editing", async () => { + await createTeamAction({ name: "Team 1" }, { user: "regular" }); + await createTeamAction({ name: "Team 2" }, { user: "regular" }); + + const res = await editTeamAction( + { + _action: "EDIT", + name: "Team 2", + bio: null, + bsky: null, + css: null, + twitter: null, + }, + { user: "regular", params: { customUrl: "team-1" } }, + ); + + expect(res.errors[0]).toBe("forms.errors.duplicateName"); + }); + + it("prevents editing team name to only special characters", async () => { + await createTeamAction({ name: "Team 1" }, { user: "regular" }); + + expect( + editTeamAction( + { + _action: "EDIT", + name: "𝓢𝓲𝓵", + bio: null, + bsky: null, + css: null, + twitter: null, + }, + { user: "regular", params: { customUrl: "team-1" } }, + ), + ).rejects.toThrow("status code: 400"); + }); +}); diff --git a/app/features/team/routes/t.$customUrl.edit.tsx b/app/features/team/routes/t.$customUrl.edit.tsx index a1d719593..f8645376e 100644 --- a/app/features/team/routes/t.$customUrl.edit.tsx +++ b/app/features/team/routes/t.$customUrl.edit.tsx @@ -95,6 +95,11 @@ export const action: ActionFunction = async ({ request, params }) => { const newCustomUrl = mySlugify(data.name); const existingTeam = await TeamRepository.findByCustomUrl(newCustomUrl); + validate( + newCustomUrl.length > 0, + "Team name can't be only special characters", + ); + // can't take someone else's custom url if (existingTeam && existingTeam.id !== team.id) { return { diff --git a/app/features/team/routes/t.$customUrl.test.ts b/app/features/team/routes/t.$customUrl.test.ts index 8c74958b8..f69b1b7f6 100644 --- a/app/features/team/routes/t.$customUrl.test.ts +++ b/app/features/team/routes/t.$customUrl.test.ts @@ -48,7 +48,7 @@ async function loadTeams() { describe("Secondary teams", () => { beforeEach(async () => { - await dbInsertUsers(2); + await dbInsertUsers(); }); afterEach(() => { dbReset();