Public API for changing IGN in tournaments (#2860)
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled

This commit is contained in:
Kalle 2026-03-03 18:46:52 +02:00 committed by GitHub
parent c1cc82c807
commit b61ae6c055
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,49 @@
import type { ActionFunctionArgs } from "react-router";
import { z } from "zod";
import { action as adminAction } from "~/features/tournament/actions/to.$id.admin.server";
import { IN_GAME_NAME_REGEXP } from "~/features/user-page/user-page-constants";
import { parseBody, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import { wrapActionForApi } from "../api-action-wrapper.server";
const paramsSchema = z.object({
id,
teamId: id,
});
const bodySchema = z.object({
userId: id,
inGameName: z.string().regex(IN_GAME_NAME_REGEXP),
});
export const action = async (args: ActionFunctionArgs) => {
const { id: tournamentId } = parseParams({
params: args.params,
schema: paramsSchema,
});
const { userId, inGameName } = await parseBody({
request: args.request,
schema: bodySchema,
});
const hashIndex = inGameName.lastIndexOf("#");
const inGameNameText = inGameName.slice(0, hashIndex);
const inGameNameDiscriminator = inGameName.slice(hashIndex + 1);
const internalRequest = new Request(args.request.url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
_action: "UPDATE_IN_GAME_NAME",
memberId: userId,
inGameNameText,
inGameNameDiscriminator,
}),
});
return wrapActionForApi(adminAction, {
...args,
params: { id: String(tournamentId) },
request: internalRequest,
});
};

View File

@ -526,3 +526,11 @@ export interface TournamentStartingBracketsBody {
export interface TournamentTeamMemberBody {
userId: number;
}
/** POST /api/tournament/{id}/teams/{tournamentTeamId}/update-member-ign */
/** @lintignore */
export interface TournamentUpdateMemberIgnBody {
userId: number;
inGameName: string;
}

View File

@ -323,6 +323,10 @@ export default [
"/tournament/:id/teams/:teamId/remove-member",
"features/api-public/routes/tournament.$id.teams.$teamId.remove-member.ts",
),
route(
"/tournament/:id/teams/:teamId/update-member-ign",
"features/api-public/routes/tournament.$id.teams.$teamId.update-member-ign.ts",
),
]),
]),

View File

@ -317,6 +317,27 @@ test.describe("Public API - Write endpoints", () => {
expect(response.status()).toBe(200);
});
test("updates member IGN via API", async ({ page }) => {
await seed(page);
await impersonate(page, ADMIN_ID);
const token = await generateWriteToken(page);
const response = await page.request.fetch(
`/api/tournament/${ITZ_TOURNAMENT_ID}/teams/${ITZ_TEAM_ID}/update-member-ign`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
data: { userId: ADMIN_ID, inGameName: "NewName#9999" },
},
);
expect(response.status()).toBe(200);
});
test("returns 400 when user is not the organizer of this tournament", async ({
page,
}) => {