diff --git a/components/tournament/TournamentJoinForm.vue b/components/tournament/TournamentJoinForm.vue index 57b7793c..924c20b0 100644 --- a/components/tournament/TournamentJoinForm.vue +++ b/components/tournament/TournamentJoinForm.vue @@ -44,7 +44,11 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue"; }} - + 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"; }, @@ -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 { diff --git a/i18n/locales/ar_SA.json b/i18n/locales/ar_SA.json index f9a29e9f..d8bc4c3d 100644 --- a/i18n/locales/ar_SA.json +++ b/i18n/locales/ar_SA.json @@ -6530,6 +6530,7 @@ "loading_more": "جارٍ تحميل المزيد…", "ineligible": { "in_tournament": "مشارك بالفعل في هذه البطولة.", + "owner_in_tournament": "مالكه لديه فريق بالفعل في هذه البطولة.", "in_season": "مسجَّل بالفعل في هذا الموسم.", "tournament_organizer": "منظِّم بالفعل لهذه البطولة.", "in_event": "مرتبط بالفعل بهذه الفعالية.", diff --git a/i18n/locales/da_DK.json b/i18n/locales/da_DK.json index de3055bc..9dfea3cb 100644 --- a/i18n/locales/da_DK.json +++ b/i18n/locales/da_DK.json @@ -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.", diff --git a/i18n/locales/de_DE.json b/i18n/locales/de_DE.json index 968e7492..769cbd04 100644 --- a/i18n/locales/de_DE.json +++ b/i18n/locales/de_DE.json @@ -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.", diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 2f577a46..f1b79b05 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -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.", diff --git a/i18n/locales/es_ES.json b/i18n/locales/es_ES.json index 24677dee..1b23c1d9 100644 --- a/i18n/locales/es_ES.json +++ b/i18n/locales/es_ES.json @@ -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.", diff --git a/i18n/locales/fr_FR.json b/i18n/locales/fr_FR.json index eff1654c..96cca4a3 100644 --- a/i18n/locales/fr_FR.json +++ b/i18n/locales/fr_FR.json @@ -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.", diff --git a/i18n/locales/it_IT.json b/i18n/locales/it_IT.json index 2e32cf14..aa988ca9 100644 --- a/i18n/locales/it_IT.json +++ b/i18n/locales/it_IT.json @@ -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.", diff --git a/i18n/locales/ja_JP.json b/i18n/locales/ja_JP.json index 355c1523..fea244c9 100644 --- a/i18n/locales/ja_JP.json +++ b/i18n/locales/ja_JP.json @@ -6530,6 +6530,7 @@ "loading_more": "さらに読み込み中…", "ineligible": { "in_tournament": "すでにこのトーナメントに参加登録済みです。", + "owner_in_tournament": "オーナーはすでにこのトーナメントにチームを登録しています。", "in_season": "すでにこのシーズンに登録済みです。", "tournament_organizer": "すでにこのトーナメントの主催者です。", "in_event": "すでにこのイベントに紐づいています。", diff --git a/i18n/locales/ko_KR.json b/i18n/locales/ko_KR.json index 8a8cb205..ca92dafe 100644 --- a/i18n/locales/ko_KR.json +++ b/i18n/locales/ko_KR.json @@ -6530,6 +6530,7 @@ "loading_more": "더 불러오는 중…", "ineligible": { "in_tournament": "이미 이 토너먼트에 등록되어 있습니다.", + "owner_in_tournament": "소유자가 이미 이 토너먼트에 팀을 등록했습니다.", "in_season": "이미 이 시즌에 등록되어 있습니다.", "tournament_organizer": "이미 이 토너먼트의 주최자입니다.", "in_event": "이미 이 이벤트에 연결되어 있습니다.", diff --git a/i18n/locales/pl_PL.json b/i18n/locales/pl_PL.json index 3c848c00..7129ce9e 100644 --- a/i18n/locales/pl_PL.json +++ b/i18n/locales/pl_PL.json @@ -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.", diff --git a/i18n/locales/pt_BR.json b/i18n/locales/pt_BR.json index 9641e4c1..79a30abf 100644 --- a/i18n/locales/pt_BR.json +++ b/i18n/locales/pt_BR.json @@ -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.", diff --git a/i18n/locales/ru_RU.json b/i18n/locales/ru_RU.json index dbf8b7b9..57c6e037 100644 --- a/i18n/locales/ru_RU.json +++ b/i18n/locales/ru_RU.json @@ -6530,6 +6530,7 @@ "loading_more": "Загрузка…", "ineligible": { "in_tournament": "Уже заявлена на этот турнир.", + "owner_in_tournament": "У её владельца уже есть команда в этом турнире.", "in_season": "Уже зарегистрирована на этот сезон.", "tournament_organizer": "Уже организатор этого турнира.", "in_event": "Уже привязана к этому событию.", diff --git a/i18n/locales/sv_SE.json b/i18n/locales/sv_SE.json index f4e0064c..ea539661 100644 --- a/i18n/locales/sv_SE.json +++ b/i18n/locales/sv_SE.json @@ -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.", diff --git a/i18n/locales/tr_TR.json b/i18n/locales/tr_TR.json index 348d4dcd..8250b7f8 100644 --- a/i18n/locales/tr_TR.json +++ b/i18n/locales/tr_TR.json @@ -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ı.", diff --git a/i18n/locales/uk_UA.json b/i18n/locales/uk_UA.json index 9b630bbd..cc58d436 100644 --- a/i18n/locales/uk_UA.json +++ b/i18n/locales/uk_UA.json @@ -6530,6 +6530,7 @@ "loading_more": "Завантаження…", "ineligible": { "in_tournament": "Уже заявлена на цей турнір.", + "owner_in_tournament": "Її власник уже має команду в цьому турнірі.", "in_season": "Уже зареєстрована на цей сезон.", "tournament_organizer": "Уже організатор цього турніру.", "in_event": "Уже прив'язана до цієї події.", diff --git a/i18n/locales/zh_Hans.json b/i18n/locales/zh_Hans.json index d1694393..cdd6f587 100644 --- a/i18n/locales/zh_Hans.json +++ b/i18n/locales/zh_Hans.json @@ -6530,6 +6530,7 @@ "loading_more": "加载更多…", "ineligible": { "in_tournament": "已报名这场锦标赛。", + "owner_in_tournament": "其所有者已在这场锦标赛中拥有战队。", "in_season": "已注册这个赛季。", "tournament_organizer": "已是这场锦标赛的主办方。", "in_event": "已与这个活动关联。", diff --git a/i18n/locales/zh_Hant.json b/i18n/locales/zh_Hant.json index 5031b9ab..fd698085 100644 --- a/i18n/locales/zh_Hant.json +++ b/i18n/locales/zh_Hant.json @@ -6530,6 +6530,7 @@ "loading_more": "載入更多…", "ineligible": { "in_tournament": "已報名這場錦標賽。", + "owner_in_tournament": "其擁有者已在這場錦標賽中擁有隊伍。", "in_season": "已註冊這個賽季。", "tournament_organizer": "已是這場錦標賽的主辦方。", "in_event": "已與這個活動連結。", diff --git a/tests/components/tournament/TournamentJoinForm.spec.ts b/tests/components/tournament/TournamentJoinForm.spec.ts new file mode 100644 index 00000000..3ad0cf28 --- /dev/null +++ b/tests/components/tournament/TournamentJoinForm.spec.ts @@ -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["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>) { + 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.", + }); + }); +});