using System; using GmRelay.Shared.Features.Sessions.CreateSession.Wizard; using static GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard.WizardTestFakes; namespace GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard; /// /// Verifies the wizard's Cancel and Back transitions: /// - Cancel deletes the draft and posts a "cancelled" message. /// - Back rewinds the draft to the previous step in the flow. /// public sealed class GameCreationWizardCancelBackTests { [Fact] public async Task Cancel_DeletesDraftAndPostsCancelledMessage() { var wizard = BuildWizard(out var drafts, out var messenger); var draft = NewDraft(WizardStepNames.Title); drafts.Seed(draft); var data = WizardCallbackData.Cancel(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Contains(draft.Id, drafts.DeletedIds); Assert.Single(messenger.Edits); Assert.Contains("отменён", messenger.Edits[0].Text, StringComparison.OrdinalIgnoreCase); Assert.Contains("cb-1", messenger.AnsweredCallbacks); } [Fact] public async Task Back_FromTitle_StaysOnTitle_AsItIsFirstStep() { var wizard = BuildWizard(out var drafts, out _); var draft = NewDraft(WizardStepNames.Title); drafts.Seed(draft); var data = WizardCallbackData.Back(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); // Title is the first step, so Back is a no-op. Assert.Equal(WizardStepNames.Title, draft.Step); } [Fact] public async Task Back_FromDescription_GoesToTitle() { var wizard = BuildWizard(out var drafts, out _); var draft = NewDraft(WizardStepNames.Description, new WizardPayload { Type = WizardCreationType.Single, Title = "T" }); drafts.Seed(draft); var data = WizardCallbackData.Back(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Equal(WizardStepNames.Title, draft.Step); } [Fact] public async Task Back_FromCover_GoesToDescription() { var wizard = BuildWizard(out var drafts, out _); var draft = NewDraft(WizardStepNames.Cover, new WizardPayload { Type = WizardCreationType.Single, Title = "T", Description = "D" }); drafts.Seed(draft); var data = WizardCallbackData.Back(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Equal(WizardStepNames.Description, draft.Step); } [Fact] public async Task Back_FromSystem_GoesToCover() { var wizard = BuildWizard(out var drafts, out _); var draft = NewDraft(WizardStepNames.System, new WizardPayload { Type = WizardCreationType.Single, Title = "T", Description = "D" }); drafts.Seed(draft); var data = WizardCallbackData.Back(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Equal(WizardStepNames.Cover, draft.Step); } [Fact] public async Task Back_FromPoolAddSlots_GoesToVisibility() { var wizard = BuildWizard(out var drafts, out _); var draft = NewDraft(WizardStepNames.PoolAddSlots, new WizardPayload { Type = WizardCreationType.Pool, Title = "Pool", Format = WizardSessionFormat.Online, JoinLink = "https://vtt.example/game", Visibility = WizardVisibility.Public, }); drafts.Seed(draft); var data = WizardCallbackData.Back(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Equal(WizardStepNames.Visibility, draft.Step); } [Fact] public async Task Create_IsAcknowledgedButNotPersistedAsStepChange() { // The "create" callback is acknowledged but the wizard does not advance // the step. Submission happens in CreateSessionHandler, not the wizard. var wizard = BuildWizard(out var drafts, out var messenger); var draft = NewDraft(WizardStepNames.Confirm); drafts.Seed(draft); var data = WizardCallbackData.Create(); await wizard.HandleInteractionAsync(CallbackInteraction(data, ownerId: draft.OwnerId), draft, CancellationToken.None); Assert.Equal(WizardStepNames.Confirm, draft.Step); Assert.Contains("cb-1", messenger.AnsweredCallbacks); } }