Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion components/tournament/TournamentJoinForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue";
}}
</h1>

<FormField v-slot="{ value, handleChange }" name="new_team">
<FormField
v-if="!ownsTeamHere"
v-slot="{ value, handleChange }"
name="new_team"
>
<FormItem>
<Card
class="h-9 rounded-md bg-gradient-to-br from-muted/50 to-muted/30 border-border/50 cursor-pointer"
Expand Down Expand Up @@ -361,6 +365,20 @@ export default {
canSelectAnyTeam() {
return this.tournament.is_organizer || useAuthStore().isAdmin;
},
// Only organizers may own more than one team in a tournament.
ownersInTournament() {
return new Set(
(this.tournament.teams || [])
.filter((team) => team.owner_steam_id)
.map((team) => String(team.owner_steam_id)),
);
},
ownsTeamHere() {
return (
!this.canSelectAnyTeam &&
this.ownersInTournament.has(String(this.me.steam_id))
);
},
registrationType() {
return this.registration?.registration_type ?? "teams";
},
Expand Down Expand Up @@ -421,6 +439,18 @@ export default {
);
}
}
if (!this.canSelectAnyTeam) {
for (const team of this.teams || []) {
if (
!map[String(team.id)] &&
this.ownersInTournament.has(String(team.owner_steam_id))
) {
map[String(team.id)] = this.$t(
"team.search.ineligible.owner_in_tournament",
);
}
}
}
return map;
},
ineligibleTournamentPlayers(): Record<string, string> {
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/ar_SA.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "جارٍ تحميل المزيد…",
"ineligible": {
"in_tournament": "مشارك بالفعل في هذه البطولة.",
"owner_in_tournament": "مالكه لديه فريق بالفعل في هذه البطولة.",
"in_season": "مسجَّل بالفعل في هذا الموسم.",
"tournament_organizer": "منظِّم بالفعل لهذه البطولة.",
"in_event": "مرتبط بالفعل بهذه الفعالية.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/da_DK.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Indlæser flere…",
"ineligible": {
"in_tournament": "Allerede tilmeldt denne turnering.",
"owner_in_tournament": "Ejeren har allerede et hold i denne turnering.",
"in_season": "Allerede tilmeldt denne sæson.",
"tournament_organizer": "Allerede arrangør af denne turnering.",
"in_event": "Allerede knyttet til denne begivenhed.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Weitere werden geladen …",
"ineligible": {
"in_tournament": "Bereits in diesem Turnier gemeldet.",
"owner_in_tournament": "Der Besitzer hat bereits ein Team in diesem Turnier.",
"in_season": "Bereits für diese Saison registriert.",
"tournament_organizer": "Bereits Organisator dieses Turniers.",
"in_event": "Bereits diesem Event zugeordnet.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Loading more...",
"ineligible": {
"in_tournament": "Already entered in this tournament.",
"owner_in_tournament": "Its owner already has a team in this tournament.",
"in_season": "Already registered for this season.",
"tournament_organizer": "Already an organizer for this tournament.",
"in_event": "Already attached to this event.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/es_ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Cargando más…",
"ineligible": {
"in_tournament": "Ya está inscrito en este torneo.",
"owner_in_tournament": "Su propietario ya tiene un equipo en este torneo.",
"in_season": "Ya está registrado para esta temporada.",
"tournament_organizer": "Ya es organizador de este torneo.",
"in_event": "Ya está asociado a este evento.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Chargement…",
"ineligible": {
"in_tournament": "Déjà inscrite à ce tournoi.",
"owner_in_tournament": "Son propriétaire a déjà une équipe dans ce tournoi.",
"in_season": "Déjà inscrite pour cette saison.",
"tournament_organizer": "Déjà organisatrice de ce tournoi.",
"in_event": "Déjà rattachée à cet événement.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/it_IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Caricamento…",
"ineligible": {
"in_tournament": "Già iscritta a questo torneo.",
"owner_in_tournament": "Il proprietario ha già una squadra in questo torneo.",
"in_season": "Già registrata per questa stagione.",
"tournament_organizer": "Già organizzatrice di questo torneo.",
"in_event": "Già collegata a questo evento.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/ja_JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "さらに読み込み中…",
"ineligible": {
"in_tournament": "すでにこのトーナメントに参加登録済みです。",
"owner_in_tournament": "オーナーはすでにこのトーナメントにチームを登録しています。",
"in_season": "すでにこのシーズンに登録済みです。",
"tournament_organizer": "すでにこのトーナメントの主催者です。",
"in_event": "すでにこのイベントに紐づいています。",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/ko_KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "더 불러오는 중…",
"ineligible": {
"in_tournament": "이미 이 토너먼트에 등록되어 있습니다.",
"owner_in_tournament": "소유자가 이미 이 토너먼트에 팀을 등록했습니다.",
"in_season": "이미 이 시즌에 등록되어 있습니다.",
"tournament_organizer": "이미 이 토너먼트의 주최자입니다.",
"in_event": "이미 이 이벤트에 연결되어 있습니다.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/pl_PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Wczytywanie…",
"ineligible": {
"in_tournament": "Już zgłoszona do tego turnieju.",
"owner_in_tournament": "Jej właściciel ma już drużynę w tym turnieju.",
"in_season": "Już zarejestrowana na ten sezon.",
"tournament_organizer": "Już jest organizatorem tego turnieju.",
"in_event": "Już przypisana do tego wydarzenia.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/pt_BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Carregando mais...",
"ineligible": {
"in_tournament": "Já inscrito neste torneio.",
"owner_in_tournament": "O dono já tem um time neste torneio.",
"in_season": "Já registrado nesta temporada.",
"tournament_organizer": "Já é organizador deste torneio.",
"in_event": "Já vinculado a este evento.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/ru_RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Загрузка…",
"ineligible": {
"in_tournament": "Уже заявлена на этот турнир.",
"owner_in_tournament": "У её владельца уже есть команда в этом турнире.",
"in_season": "Уже зарегистрирована на этот сезон.",
"tournament_organizer": "Уже организатор этого турнира.",
"in_event": "Уже привязана к этому событию.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/sv_SE.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Läser in fler…",
"ineligible": {
"in_tournament": "Redan anmält till den här turneringen.",
"owner_in_tournament": "Ägaren har redan ett lag i den här turneringen.",
"in_season": "Redan registrerat för den här säsongen.",
"tournament_organizer": "Redan arrangör för den här turneringen.",
"in_event": "Redan kopplat till det här evenemanget.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/tr_TR.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Daha fazlası yükleniyor…",
"ineligible": {
"in_tournament": "Bu turnuvaya zaten kayıtlı.",
"owner_in_tournament": "Sahibinin bu turnuvada zaten bir takımı var.",
"in_season": "Bu sezona zaten kayıtlı.",
"tournament_organizer": "Zaten bu turnuvanın organizatörü.",
"in_event": "Zaten bu etkinliğe bağlı.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/uk_UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "Завантаження…",
"ineligible": {
"in_tournament": "Уже заявлена на цей турнір.",
"owner_in_tournament": "Її власник уже має команду в цьому турнірі.",
"in_season": "Уже зареєстрована на цей сезон.",
"tournament_organizer": "Уже організатор цього турніру.",
"in_event": "Уже прив'язана до цієї події.",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/zh_Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "加载更多…",
"ineligible": {
"in_tournament": "已报名这场锦标赛。",
"owner_in_tournament": "其所有者已在这场锦标赛中拥有战队。",
"in_season": "已注册这个赛季。",
"tournament_organizer": "已是这场锦标赛的主办方。",
"in_event": "已与这个活动关联。",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/zh_Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -6530,6 +6530,7 @@
"loading_more": "載入更多…",
"ineligible": {
"in_tournament": "已報名這場錦標賽。",
"owner_in_tournament": "其擁有者已在這場錦標賽中擁有隊伍。",
"in_season": "已註冊這個賽季。",
"tournament_organizer": "已是這場錦標賽的主辦方。",
"in_event": "已與這個活動連結。",
Expand Down
101 changes: 101 additions & 0 deletions tests/components/tournament/TournamentJoinForm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { afterEach, describe, expect, it } from "vitest";
import { flushPromises } from "@vue/test-utils";
import { mountSuspended } from "@nuxt/test-utils/runtime";
import TournamentJoinForm from "~/components/tournament/TournamentJoinForm.vue";
import TeamSearch from "~/components/teams/TeamSearch.vue";
import { e_player_roles_enum } from "~/generated/zeus";

const ME = "76561198000000001";
const SOMEONE_ELSE = "76561198000000002";

let unmount: (() => void) | null = null;

afterEach(() => {
unmount?.();
unmount = null;
useAuthStore().me = undefined;
});

async function mountJoinForm(options: {
isOrganizer?: boolean;
tournamentOwners: string[];
}) {
useAuthStore().me = {
steam_id: ME,
name: "Player",
role: e_player_roles_enum.user,
teams: [
{ id: "mine", name: "Mine", owner_steam_id: ME },
{ id: "theirs", name: "Theirs", owner_steam_id: SOMEONE_ELSE },
],
} as unknown as ReturnType<typeof useAuthStore>["me"];

const wrapper = await mountSuspended(TournamentJoinForm, {
props: {
tournament: {
id: "tournament-1",
status: "RegistrationOpen",
can_join: true,
is_organizer: options.isOrganizer ?? false,
min_players_per_lineup: 5,
teams: options.tournamentOwners.map((owner, index) => ({
id: `entry-${index}`,
team_id: `registered-${index}`,
owner_steam_id: owner,
roster: [],
})),
},
},
global: { stubs: { TeamSearch: true } },
});
unmount = () => wrapper.unmount();
await flushPromises();
return wrapper;
}

function ineligible(wrapper: Awaited<ReturnType<typeof mountJoinForm>>) {
return wrapper.findComponent(TeamSearch).props("ineligible") as Record<
string,
string
>;
}

describe("TournamentJoinForm", () => {
it("offers a new team to a player who has no team in the tournament", async () => {
const wrapper = await mountJoinForm({ tournamentOwners: [SOMEONE_ELSE] });

expect(wrapper.text()).toContain("Create New Team");
expect(ineligible(wrapper).mine).toBeUndefined();
});

it("stops a player who owns a team here from entering another they own", async () => {
const wrapper = await mountJoinForm({ tournamentOwners: [ME] });

expect(wrapper.text()).not.toContain("Create New Team");
expect(ineligible(wrapper).mine).toBe(
"Its owner already has a team in this tournament.",
);
expect(ineligible(wrapper).theirs).toBeUndefined();
});

it("blocks a managed team whose owner already has a team here", async () => {
const wrapper = await mountJoinForm({ tournamentOwners: [SOMEONE_ELSE] });

expect(ineligible(wrapper).theirs).toBe(
"Its owner already has a team in this tournament.",
);
});

it("lets an organizer add as many teams as they need", async () => {
const wrapper = await mountJoinForm({
isOrganizer: true,
tournamentOwners: [ME, SOMEONE_ELSE],
});

expect(wrapper.text()).toContain("Create New Team");
expect(ineligible(wrapper)).toEqual({
"registered-0": "Already entered in this tournament.",
"registered-1": "Already entered in this tournament.",
});
});
});
Loading