39132be4e8
PR Checks / test-and-build (pull_request) Successful in 6m6s
Move neutral join/leave handlers into GmRelay.Shared so Telegram and Discord share capacity, waitlist, duplicate-click, and schedule-update behavior. Add Discord component routing for join_session and leave_session buttons with deferred ephemeral replies and serialized schedule message updates. Bump version to 2.5.0 and update Discord docs. Refs #29
97 lines
3.5 KiB
C#
97 lines
3.5 KiB
C#
using GmRelay.DiscordBot.Features.Sessions;
|
|
using GmRelay.Shared.Features.Sessions.CreateSession;
|
|
using GmRelay.Shared.Platform;
|
|
|
|
namespace GmRelay.Bot.Tests.Discord;
|
|
|
|
public sealed class DiscordSessionInteractionMapperTests
|
|
{
|
|
[Fact]
|
|
public void TryParseCustomId_WhenActionAndSessionIdMatch_ReturnsSessionId()
|
|
{
|
|
var sessionId = Guid.NewGuid();
|
|
|
|
var result = DiscordSessionInteractionMapper.TryParseCustomId(
|
|
$"join_session:{sessionId}",
|
|
"join_session",
|
|
out var parsedSessionId);
|
|
|
|
Assert.True(result);
|
|
Assert.Equal(sessionId, parsedSessionId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryParseCustomId_WhenActionDoesNotMatch_ReturnsFalse()
|
|
{
|
|
var result = DiscordSessionInteractionMapper.TryParseCustomId(
|
|
$"leave_session:{Guid.NewGuid()}",
|
|
"join_session",
|
|
out _);
|
|
|
|
Assert.False(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryParseCustomId_WhenSessionIdIsInvalid_ReturnsFalse()
|
|
{
|
|
var result = DiscordSessionInteractionMapper.TryParseCustomId(
|
|
"join_session:not-a-guid",
|
|
"join_session",
|
|
out _);
|
|
|
|
Assert.False(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateJoinCommand_ShouldBuildPlatformNeutralDiscordCommand()
|
|
{
|
|
var sessionId = Guid.NewGuid();
|
|
var input = CreateInput(sessionId, displayName: "Alice GM");
|
|
|
|
JoinSessionCommand command = DiscordSessionInteractionMapper.CreateJoinCommand(input);
|
|
|
|
Assert.Equal(sessionId, command.SessionId);
|
|
Assert.Equal("interaction-1", command.InteractionId);
|
|
Assert.Equal(PlatformKind.Discord, command.User.Platform);
|
|
Assert.Equal("42", command.User.ExternalUserId);
|
|
Assert.Equal("Alice GM", command.User.DisplayName);
|
|
Assert.Equal("alice", command.User.ExternalUsername);
|
|
Assert.Equal(PlatformKind.Discord, command.Group.Platform);
|
|
Assert.Equal("guild-1", command.Group.ExternalGroupId);
|
|
Assert.Equal("channel-1", command.Group.ExternalChannelId);
|
|
Assert.Equal(PlatformKind.Discord, command.ScheduleMessage.Platform);
|
|
Assert.Equal("guild-1", command.ScheduleMessage.ExternalGroupId);
|
|
Assert.Equal("message-1", command.ScheduleMessage.ExternalMessageId);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateLeaveCommand_ShouldBuildPlatformNeutralDiscordCommand()
|
|
{
|
|
var sessionId = Guid.NewGuid();
|
|
var input = CreateInput(sessionId, displayName: null);
|
|
|
|
LeaveSessionCommand command = DiscordSessionInteractionMapper.CreateLeaveCommand(input);
|
|
|
|
Assert.Equal(sessionId, command.SessionId);
|
|
Assert.Equal("interaction-1", command.InteractionId);
|
|
Assert.Equal(PlatformKind.Discord, command.User.Platform);
|
|
Assert.Equal("42", command.User.ExternalUserId);
|
|
Assert.Equal("alice", command.User.DisplayName);
|
|
Assert.Equal("alice", command.User.ExternalUsername);
|
|
Assert.Equal("guild-1", command.Group.ExternalGroupId);
|
|
Assert.Equal("channel-1", command.Group.ExternalChannelId);
|
|
Assert.Equal("message-1", command.ScheduleMessage.ExternalMessageId);
|
|
}
|
|
|
|
private static DiscordSessionInteractionInput CreateInput(Guid sessionId, string? displayName)
|
|
=> new(
|
|
SessionId: sessionId,
|
|
InteractionId: "interaction-1",
|
|
GuildId: "guild-1",
|
|
ChannelId: "channel-1",
|
|
MessageId: "message-1",
|
|
UserId: 42,
|
|
Username: "alice",
|
|
DisplayName: displayName);
|
|
}
|