using System; using System.Threading; using System.Threading.Tasks; using GmRelay.Bot.Features.Sessions.CreateSession; using GmRelay.Bot.Features.Sessions.CreateSession.Wizard; using GmRelay.Shared.Features.Sessions.CreateSession.Wizard; using Microsoft.Extensions.Logging.Abstractions; using static GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard.WizardTestFakes; namespace GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard; /// /// Verifies that bails /// out gracefully when the wizard payload is missing required fields. The /// missing-fields path returns before the shared handler is ever called, /// so we pass null! for the shared dependency — a NRE on that /// branch would itself prove the validation did not fire. /// public sealed class CreateSessionHandlerSubmitMissingFieldsTests { [Fact] public async Task SubmitDraftAsync_EmptyPayload_EditsMessageWithMissingFields() { var drafts = new FakeWizardDraftRepository(); var messenger = new FakeWizardMessenger(); var sut = new CreateSessionHandler( drafts, shared: null!, // missing-fields path returns before touching the shared handler messenger, NullLogger.Instance); // Empty payload → every required field is missing. var draft = NewDraft(WizardStepNames.Confirm, new WizardPayload()); drafts.Seed(draft); await sut.SubmitDraftAsync(draft, CancellationToken.None); // The wizard message is edited to surface the missing-field error. Assert.Single(messenger.Edits); var edit = messenger.Edits[0]; Assert.Equal(draft.ChatId, edit.ChatId); Assert.Contains("Не заполнены", edit.Text, StringComparison.OrdinalIgnoreCase); } [Fact] public async Task SubmitDraftAsync_MissingTitleOnly_EditsMessageNamingTitle() { var drafts = new FakeWizardDraftRepository(); var messenger = new FakeWizardMessenger(); var sut = new CreateSessionHandler( drafts, shared: null!, messenger, NullLogger.Instance); // All required fields set except Title. var payload = new WizardPayload { Type = WizardCreationType.Single, System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Single = new WizardSingleInput { ScheduledAt = DateTimeOffset.UtcNow.AddDays(7), MaxPlayers = 4, }, }; var draft = NewDraft(WizardStepNames.Confirm, payload); drafts.Seed(draft); await sut.SubmitDraftAsync(draft, CancellationToken.None); Assert.Single(messenger.Edits); Assert.Contains("название", messenger.Edits[0].Text, StringComparison.OrdinalIgnoreCase); } }