fix(bot,discord): allow 'no player limit' option in /newsession wizard (v3.9.3) #124

Closed
Toutsu wants to merge 0 commits from fix/issue-123-no-limit-wizard into main
Owner

Summary

Fix #123 — в /newsession нельзя было задать сессию без лимита мест. В визарде (Telegram + Discord) на шаге «Лимит мест» не было кнопки «Без лимита» — кнопка waitlist:off молча перепрыгивала на следующий шаг, оставляя MaxPlayers = null. Валидация ловила null и ругалась «Не заполнены поля: лимит мест».

DB и контракт CreateSessionCommand.MaxPlayers: int? уже корректно поддерживали NULL (тест CreateSessionCommandContractTests.cs:16, web-форма EditSession.razor:56). Сломан был только wizard-флоу.

Changes

  • src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/WizardStepViewBuilder.cs: добавлена кнопка ♾ Без лимита в BuildCapacity (Telegram).
  • src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs: ветка "no_limit" => (Visibility, SetMaxPlayers(p, null)) в ApplyCapacityChoice. SetMaxPlayers принимает int?.
  • src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs: BuildCommand принимает int?, ?? 0 убран. Сигнатура изменена с private на internal для тестов.
  • src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardStep.cs: кнопка ♾ Без лимита в RenderCapacity и RenderPoolSlotCapacity (Discord). В BuildConfirmDescription при MaxPlayers = null теперь явно пишется 👥 Без лимита, waitlist вкл/выкл.
  • src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardSubmitter.cs: BuildCommand принимает int?, ?? 0 убран. Сигнатура internal.
  • src/GmRelay.DiscordBot/Properties/AssemblyInfo.cs (new): InternalsVisibleTo("GmRelay.Bot.Tests").
  • 9 новых регрессионных тестов (Telegram + Discord, см. issue #123).

Test plan

  • dotnet test — 601 passed, 2 skipped (Testcontainers, как до фикса)
  • dotnet format --verify-no-changes — clean
  • dotnet build — 0 warnings (TreatWarningsAsErrors=true)
  • dotnet list package --vulnerable — clean
  • packages.lock.json не изменились (новых пакетов нет)

Audit

Web-форма (EditSession.razor) уже поддерживает MaxPlayers: int? и placeholder="Без лимита" — там бага нет. Пул-флоу (WizardSlotInput.MaxPlayers: int) by design требует лимит 1..50 для каждого слота, MaxPlayersForPool корректен — там тоже нечего чинить.

Workflow

  • CI passes (pr-checks)
  • Code review approved
  • Deployed to main
  • Release v3.9.3 published
## Summary Fix #123 — в /newsession нельзя было задать сессию без лимита мест. В визарде (Telegram + Discord) на шаге «Лимит мест» не было кнопки «Без лимита» — кнопка `waitlist:off` молча перепрыгивала на следующий шаг, оставляя `MaxPlayers = null`. Валидация ловила null и ругалась «Не заполнены поля: лимит мест». DB и контракт `CreateSessionCommand.MaxPlayers: int?` уже корректно поддерживали `NULL` (тест `CreateSessionCommandContractTests.cs:16`, web-форма `EditSession.razor:56`). Сломан был только wizard-флоу. ## Changes - **`src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/WizardStepViewBuilder.cs`**: добавлена кнопка `♾ Без лимита` в `BuildCapacity` (Telegram). - **`src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs`**: ветка `"no_limit" => (Visibility, SetMaxPlayers(p, null))` в `ApplyCapacityChoice`. `SetMaxPlayers` принимает `int?`. - **`src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs`**: `BuildCommand` принимает `int?`, `?? 0` убран. Сигнатура изменена с `private` на `internal` для тестов. - **`src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardStep.cs`**: кнопка `♾ Без лимита` в `RenderCapacity` и `RenderPoolSlotCapacity` (Discord). В `BuildConfirmDescription` при `MaxPlayers = null` теперь явно пишется `👥 Без лимита, waitlist вкл/выкл`. - **`src/GmRelay.DiscordBot/Features/Sessions/Wizard/DiscordWizardSubmitter.cs`**: `BuildCommand` принимает `int?`, `?? 0` убран. Сигнатура `internal`. - **`src/GmRelay.DiscordBot/Properties/AssemblyInfo.cs`** (new): `InternalsVisibleTo("GmRelay.Bot.Tests")`. - **9 новых регрессионных тестов** (Telegram + Discord, см. issue #123). ## Test plan - [x] `dotnet test` — 601 passed, 2 skipped (Testcontainers, как до фикса) - [x] `dotnet format --verify-no-changes` — clean - [x] `dotnet build` — 0 warnings (TreatWarningsAsErrors=true) - [x] `dotnet list package --vulnerable` — clean - [x] `packages.lock.json` не изменились (новых пакетов нет) ## Audit Web-форма (`EditSession.razor`) уже поддерживает `MaxPlayers: int?` и `placeholder="Без лимита"` — там бага нет. Пул-флоу (`WizardSlotInput.MaxPlayers: int`) by design требует лимит 1..50 для каждого слота, `MaxPlayersForPool` корректен — там тоже нечего чинить. ## Workflow - [ ] CI passes (`pr-checks`) - [ ] Code review approved - [ ] Deployed to main - [ ] Release `v3.9.3` published
Toutsu added 2 commits 2026-06-08 18:20:10 +03:00
In the session creation wizard (Telegram + Discord), the Capacity step
only exposed waitlist on/off buttons. The 'no waitlist' button silently
advanced to the next step without setting MaxPlayers, so users who tried
to create a session with no player cap were blocked with
'Не заполнены поля: лимит мест'.

The DB contract and CreateSessionCommand already supported null
MaxPlayers (int?, ck_sessions_max_players check in V006), and the web
form already exposes 'Без лимита' as an empty InputNumber — only the
wizard flow was broken.

Changes:
- Add '♾ Без лимита' choice button to Capacity in shared
  WizardStepViewBuilder.BuildCapacity (Telegram) and to
  RenderCapacity / RenderPoolSlotCapacity in DiscordWizardStep (Discord).
- Add 'no_limit' branch to GameCreationWizard.ApplyCapacityChoice that
  sets MaxPlayers to null and advances to Visibility.
- Change GameCreationWizard.SetMaxPlayers signature from int to int? so
  the 'no limit' branch compiles.
- Change CreateSessionCommand builder in both Telegram and Discord
  submitters to take int? maxPlayers and drop the '?? 0' that would
  have turned null into 0 (violating the DB CHECK and the 'no limit'
  contract).
- In Discord BuildConfirmDescription, render '👥 Без лимита, waitlist
  вкл/выкл' when MaxPlayers is null (the previous code silently
  omitted the line).
- Expose BuildCommand as internal in both submitters and add
  InternalsVisibleTo('GmRelay.Bot.Tests') to the DiscordBot assembly
  for unit-test access.

Tests (9 new):
- WizardStepRenderTests.CapacityStep_HasWaitlistButtons — asserts the
  'Без лимита' button is present.
- GameCreationWizardStepTransitionsTests.NoLimitCapacityButton_… —
  asserts the choice advances to Visibility and leaves MaxPlayers null
  in the JSON draft.
- GameCreationWizardStepTransitionsTests.ChoiceCallback_AdvancesToExpectedStep —
  new Theory row for Capacity/no_limit.
- CreateSessionHandlerBuildCommandTests (new) — null/value propagation
  through the Telegram submitter's BuildCommand.
- DiscordWizardStepCapacityRenderTests (new) — 'Без лимита' button is
  rendered for both Capacity and PoolSlotCapacity, with the expected
  custom-id shape.
- DiscordWizardSubmitterBuildCommandTests (new) — null/value
  propagation through the Discord submitter's BuildCommand.

Closes #123
chore: bump version 3.9.2 -> 3.9.3
PR Checks / test-and-build (pull_request) Failing after 10m16s
5c0397a5e6
Sync the four canonical version sources for the patch release:
- Directory.Build.props
- compose.yaml (bot, discord, web image tags)
- .gitea/workflows/deploy.yml (VERSION env)
- src/GmRelay.Web/Components/Layout/NavMenu.razor (visible nav-version)
Toutsu added 1 commit 2026-06-08 18:32:48 +03:00
test(web): update NavMenu_ShouldExposeCurrentProjectVersion to 3.9.3
PR Checks / test-and-build (pull_request) Successful in 9m57s
3c3ef8db5a
The version-bump commit changed the visible version in NavMenu.razor
from 3.9.2 to 3.9.3 but this test hard-coded the old literal. Update
the assertion to match the new release tag.
Toutsu closed this pull request 2026-06-08 18:49:25 +03:00
Some checks are pending
PR Checks / test-and-build (pull_request) Successful in 9m57s

Pull request closed

Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Toutsu/GmRelayBot#124