using GmRelay.DiscordBot.Features.Sessions.Wizard; using GmRelay.Shared.Features.Sessions.CreateSession.Wizard; using Xunit; namespace GmRelay.Bot.Tests.Discord.Wizard; /// /// Regression coverage for 's /// BuildCommand: when the wizard payload carries no player limit /// (user picked «♾ Без лимита» on the Capacity step), the resulting /// CreateSessionCommand.MaxPlayers must be null — never /// 0. 0 would violate the DB CHECK /// ck_sessions_max_players in V006 and the contract that /// null means "no limit". /// public sealed class DiscordWizardSubmitterBuildCommandTests { [Fact] public void BuildCommand_WhenSingleMaxPlayersIsNull_PropagatesNull() { var draft = new WizardDraft { Id = Guid.NewGuid(), ChatId = "42", OwnerId = "100", Step = "confirm", }; var payload = new WizardPayload { Type = WizardCreationType.Single, Title = "T", System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Single = new WizardSingleInput { ScheduledAt = DateTimeOffset.UtcNow.AddDays(1), MaxPlayers = null, }, }; var cmd = DiscordWizardSubmitter.BuildCommand( draft, payload, new[] { payload.Single!.ScheduledAt!.Value }, payload.Single.MaxPlayers, isOneShot: true); Assert.Null(cmd.MaxPlayers); } [Fact] public void BuildCommand_WhenSingleMaxPlayersIsSet_PropagatesValue() { var draft = new WizardDraft { Id = Guid.NewGuid(), ChatId = "42", OwnerId = "100", Step = "confirm", }; var payload = new WizardPayload { Type = WizardCreationType.Single, Title = "T", System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Single = new WizardSingleInput { ScheduledAt = DateTimeOffset.UtcNow.AddDays(1), MaxPlayers = 5, }, }; var cmd = DiscordWizardSubmitter.BuildCommand( draft, payload, new[] { payload.Single!.ScheduledAt!.Value }, payload.Single.MaxPlayers, isOneShot: true); Assert.Equal(5, cmd.MaxPlayers); } [Fact] public void BuildCommand_WhenFormatIsOnline_PropagatesFormatAndJoinLink() { var draft = new WizardDraft { Id = Guid.NewGuid(), ChatId = "42", OwnerId = "100", Step = "confirm", }; var payload = new WizardPayload { Type = WizardCreationType.Single, Title = "T", System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Format = WizardSessionFormat.Online, JoinLink = "https://vtt.example/game", Single = new WizardSingleInput { ScheduledAt = DateTimeOffset.UtcNow.AddDays(1), MaxPlayers = 5, }, }; var cmd = DiscordWizardSubmitter.BuildCommand( draft, payload, new[] { payload.Single!.ScheduledAt!.Value }, payload.Single.MaxPlayers, isOneShot: true); Assert.Equal("Online", cmd.Format); Assert.Equal("https://vtt.example/game", cmd.Link); Assert.Null(cmd.LocationAddress); } [Fact] public void BuildCommand_WhenFormatIsOffline_PropagatesFormatAndAddress() { var draft = new WizardDraft { Id = Guid.NewGuid(), ChatId = "42", OwnerId = "100", Step = "confirm", }; var payload = new WizardPayload { Type = WizardCreationType.Single, Title = "T", System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Format = WizardSessionFormat.Offline, LocationAddress = "Москва, ул. Кубиков, 12", Single = new WizardSingleInput { ScheduledAt = DateTimeOffset.UtcNow.AddDays(1), MaxPlayers = 5, }, }; var cmd = DiscordWizardSubmitter.BuildCommand( draft, payload, new[] { payload.Single!.ScheduledAt!.Value }, payload.Single.MaxPlayers, isOneShot: true); Assert.Equal("Offline", cmd.Format); Assert.Equal("Москва, ул. Кубиков, 12", cmd.LocationAddress); Assert.Equal(string.Empty, cmd.Link); } [Fact] public void BuildCommand_WhenPoolMaxPlayersIsSet_PropagatesValueToMaxPlayers() { var draft = new WizardDraft { Id = Guid.NewGuid(), ChatId = "42", OwnerId = "100", Step = "confirm", }; var slotTime = DateTimeOffset.UtcNow.AddDays(1); var payload = new WizardPayload { Type = WizardCreationType.Pool, Title = "Pool", System = "Dnd5e", DurationMinutes = 240, Visibility = WizardVisibility.Public, Format = WizardSessionFormat.Online, JoinLink = "https://vtt.example/game", Pool = new WizardPoolInput { MaxPlayers = 12, Slots = { new WizardSlotInput { ScheduledAt = slotTime, MaxPlayers = 8 } }, }, }; var cmd = DiscordWizardSubmitter.BuildCommand( draft, payload, new[] { slotTime }, payload.Pool.MaxPlayers, isOneShot: false); Assert.Equal(12, cmd.MaxPlayers); } }