fix(bot): keep capacity and club wizard steps consistent
Fix two wizard FSM bugs reported after v3.9.4: 1. Capacity waitlist buttons could still advance the draft without a numeric MaxPlayers value. The final submit validation then rejected the draft with 'Не заполнены поля: лимит мест'. Now waitlist:on/off stay on Capacity until MaxPlayers is set; users must either enter a numeric limit or explicitly choose '♾ Без лимита'. 2. PickClub computed NextAfterVisibility before SetClubId, so the first club click left the wizard on PickClub and the second click advanced. Now ClubId is saved first and NextAfterVisibility is evaluated after that mutation, so a valid club click advances on the first try. TDD: - WaitlistChoiceWithoutCapacity_StaysOnCapacityStep covers waitlist:on/off. - PickClub_ValidGuid_AdvancesToPublishOnFirstClick covers the single-click club path. - Stale Capacity waitlist callback test updated to the safer no-advance contract. Closes #127
This commit is contained in:
@@ -298,13 +298,25 @@ public sealed class GameCreationWizard
|
||||
: (null, "Неверная длительность"),
|
||||
};
|
||||
|
||||
private static (string?, string?) ApplyCapacityChoice(WizardPayload p, string choice) => choice switch
|
||||
private static (string?, string?) ApplyCapacityChoice(WizardPayload p, string choice)
|
||||
{
|
||||
"waitlist:on" => (WizardStepNames.Visibility, SetWaitlist(p, true)),
|
||||
"waitlist:off" => (WizardStepNames.Visibility, SetWaitlist(p, false)),
|
||||
"no_limit" => (WizardStepNames.Visibility, SetMaxPlayers(p, null)),
|
||||
_ => (null, "Неизвестный выбор"),
|
||||
};
|
||||
if (choice is "no_limit")
|
||||
{
|
||||
return (WizardStepNames.Visibility, SetMaxPlayers(p, null));
|
||||
}
|
||||
|
||||
if (choice is "waitlist:on" or "waitlist:off" && p.Single?.MaxPlayers is null)
|
||||
{
|
||||
return (null, "Сначала введите лимит мест или нажмите «♾ Без лимита»");
|
||||
}
|
||||
|
||||
return choice switch
|
||||
{
|
||||
"waitlist:on" => (WizardStepNames.Visibility, SetWaitlist(p, true)),
|
||||
"waitlist:off" => (WizardStepNames.Visibility, SetWaitlist(p, false)),
|
||||
_ => (null, "Неизвестный выбор"),
|
||||
};
|
||||
}
|
||||
|
||||
private static (string?, string?) ApplyVisibilityChoice(WizardPayload p, string choice) => choice switch
|
||||
{
|
||||
@@ -316,9 +328,15 @@ public sealed class GameCreationWizard
|
||||
};
|
||||
|
||||
private static (string?, string?) ApplyPickClubChoice(WizardPayload p, string choice)
|
||||
=> Guid.TryParse(choice, out var id)
|
||||
? (NextAfterVisibility(p), SetClubId(p, id))
|
||||
: (null, "Неверный идентификатор клуба");
|
||||
{
|
||||
if (!Guid.TryParse(choice, out var id))
|
||||
{
|
||||
return (null, "Неверный идентификатор клуба");
|
||||
}
|
||||
|
||||
var error = SetClubId(p, id);
|
||||
return (NextAfterVisibility(p), error);
|
||||
}
|
||||
|
||||
private static (string?, string?) ApplyPublishChoice(WizardPayload p, string choice) => choice switch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user