Files
GmRelayBot/tests/GmRelay.Bot.Tests/Discord/Wizard/DiscordWizardStepCapacityRenderTests.cs
T
Toutsu 9709d09b15
PR Checks / test-and-build (pull_request) Successful in 30m45s
feat(discord): make /newsession identical to Telegram wizard
- Remove legacy DiscordNewSessionCommand/Handler and their tests.
- Rename /newsession-wizard to /newsession.
- Add shared pool capacity step before Format/Location.
- Render Format and Location in Discord wizard; Location uses a modal.
- Propagate Format, JoinLink and LocationAddress in BuildCommand.
- Publish created sessions through existing IPlatformMessenger pipeline.
- Update README, version bump to 3.11.1, sync compose/deploy/NavMenu.
2026-06-15 17:49:53 +03:00

90 lines
3.7 KiB
C#

using GmRelay.DiscordBot.Features.Sessions.Wizard;
using GmRelay.Shared.Features.Sessions.CreateSession.Wizard;
using NetCord.Rest;
using Xunit;
namespace GmRelay.Bot.Tests.Discord.Wizard;
/// <summary>
/// Renderer tests for the Discord wizard's Capacity / PoolSlotCapacity steps.
/// Locks in the presence of the "♾ Без лимита" button so the user can pick
/// a session with no player cap (null in <c>sessions.max_players</c>), the
/// same affordance the Telegram wizard provides.
/// </summary>
public sealed class DiscordWizardStepCapacityRenderTests
{
[Fact]
public void RenderCapacity_ContainsNoLimitButton()
{
var draft = new WizardDraft { Step = WizardStepNames.Capacity };
var render = DiscordWizardStep.Render(draft, new WizardPayload());
var labels = ExtractButtonLabels(render);
Assert.Contains(labels, l => l.Contains("Без лимита", System.StringComparison.Ordinal));
}
[Fact]
public void RenderPoolSlotCapacity_ContainsNoLimitButton()
{
var draft = new WizardDraft { Step = WizardStepNames.PoolSlotCapacity };
var render = DiscordWizardStep.Render(draft, new WizardPayload());
var labels = ExtractButtonLabels(render);
Assert.Contains(labels, l => l.Contains("Без лимита", System.StringComparison.Ordinal));
}
[Theory]
[InlineData(WizardStepNames.Capacity, "wizard:btn:choice:Capacity:no_limit")]
[InlineData(WizardStepNames.PoolSlotCapacity, "wizard:btn:choice:PoolSlotCapacity:no_limit")]
public void Render_NoLimitButton_HasChoiceCustomIdForNoLimit(string step, string expectedCustomIdPrefix)
{
var draft = new WizardDraft { Step = step };
var render = DiscordWizardStep.Render(draft, new WizardPayload());
var buttons = ExtractButtons(render);
var noLimit = buttons.SingleOrDefault(b => b.Label?.Contains("Без лимита", System.StringComparison.Ordinal) == true);
Assert.NotNull(noLimit);
Assert.StartsWith(expectedCustomIdPrefix, noLimit!.CustomId);
}
private static System.Collections.Generic.List<string> ExtractButtonLabels(
DiscordWizardStep.DiscordWizardRender render) =>
render.Components
.OfType<ActionRowProperties>()
.SelectMany(r => r.Components)
.OfType<ButtonProperties>()
.Select(b => b.Label ?? string.Empty)
.ToList();
[Fact]
public void RenderFormat_ContainsOnlineAndOfflineButtons()
{
var draft = new WizardDraft { Step = WizardStepNames.Format };
var render = DiscordWizardStep.Render(draft, new WizardPayload());
var labels = ExtractButtonLabels(render);
Assert.Contains(labels, l => l.Contains("Online", System.StringComparison.Ordinal));
Assert.Contains(labels, l => l.Contains("Offline", System.StringComparison.Ordinal));
}
[Theory]
[InlineData(WizardSessionFormat.Online, "🔗 Ссылка")]
[InlineData(WizardSessionFormat.Offline, "📍 Адрес")]
public void RenderLocation_ForFormat_OpensModalAndShowsPrompt(WizardSessionFormat format, string expectedTitle)
{
var draft = new WizardDraft { Step = WizardStepNames.Location };
var render = DiscordWizardStep.Render(draft, new WizardPayload { Format = format });
Assert.Equal(expectedTitle, render.EmbedTitle);
Assert.Equal(WizardStepNames.Location, render.OpenModalStep);
}
private static System.Collections.Generic.List<ButtonProperties> ExtractButtons(
DiscordWizardStep.DiscordWizardRender render) =>
render.Components
.OfType<ActionRowProperties>()
.SelectMany(r => r.Components)
.OfType<ButtonProperties>()
.ToList();
}