From b496a401fcd0b59c62f93ebd4cab7fb7b39f43bd Mon Sep 17 00:00:00 2001 From: Toutsu Date: Thu, 28 May 2026 16:33:29 +0300 Subject: [PATCH] test: add GameSystem fuzzy matching and showcase query tests Co-Authored-By: Claude Opus 4.7 --- .../Domain/GameSystemTests.cs | 61 +++++++++++++++++++ .../Web/AuthorizedSessionServiceTests.cs | 10 +++ .../Web/ShowcaseQueryTests.cs | 55 +++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 tests/GmRelay.Bot.Tests/Domain/GameSystemTests.cs create mode 100644 tests/GmRelay.Bot.Tests/Web/ShowcaseQueryTests.cs diff --git a/tests/GmRelay.Bot.Tests/Domain/GameSystemTests.cs b/tests/GmRelay.Bot.Tests/Domain/GameSystemTests.cs new file mode 100644 index 0000000..3834ec0 --- /dev/null +++ b/tests/GmRelay.Bot.Tests/Domain/GameSystemTests.cs @@ -0,0 +1,61 @@ +using GmRelay.Shared.Domain; + +namespace GmRelay.Bot.Tests.Domain; + +public sealed class GameSystemTests +{ + [Theory] + [InlineData("Dnd5e", GameSystem.Dnd5e)] + [InlineData("D&D", GameSystem.Dnd5e)] + [InlineData("dnd5e", GameSystem.Dnd5e)] + [InlineData("pathfinder", GameSystem.Pathfinder2e)] + [InlineData("call of cthulhu", GameSystem.CallOfCthulhu7e)] + [InlineData("shadow", GameSystem.Shadowdark)] + [InlineData("unknown xyz", GameSystem.Other)] + public void TryParseFuzzy_ShouldMapInputToExpectedSystem(string input, GameSystem expected) + { + var result = GameSystemExtensions.TryParseFuzzy(input); + + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("днд")] + [InlineData("колова")] + public void TryParseFuzzy_ShouldReturnOtherForUnmatchedCyrillicInput(string input) + { + var result = GameSystemExtensions.TryParseFuzzy(input); + + Assert.Equal(GameSystem.Other, result); + } + + [Fact] + public void TryParseFuzzy_ShouldReturnNullForNullInput() + { + var result = GameSystemExtensions.TryParseFuzzy(null!); + + Assert.Null(result); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + public void TryParseFuzzy_ShouldReturnNullForEmptyOrWhitespaceInput(string input) + { + var result = GameSystemExtensions.TryParseFuzzy(input); + + Assert.Null(result); + } + + [Theory] + [InlineData(GameSystem.Dnd5e, "D&D 5e")] + [InlineData(GameSystem.Other, "Другое")] + [InlineData(GameSystem.Pathfinder2e, "Pathfinder 2e")] + [InlineData(GameSystem.Shadowdark, "Shadowdark")] + public void ToDisplayName_ShouldReturnExpectedName(GameSystem system, string expected) + { + var result = system.ToDisplayName(); + + Assert.Equal(expected, result); + } +} diff --git a/tests/GmRelay.Bot.Tests/Web/AuthorizedSessionServiceTests.cs b/tests/GmRelay.Bot.Tests/Web/AuthorizedSessionServiceTests.cs index b54dbb5..3675b8c 100644 --- a/tests/GmRelay.Bot.Tests/Web/AuthorizedSessionServiceTests.cs +++ b/tests/GmRelay.Bot.Tests/Web/AuthorizedSessionServiceTests.cs @@ -2,6 +2,7 @@ using GmRelay.Web.Services; using System.Security.Claims; using Microsoft.AspNetCore.Http; using GmRelay.Shared.Domain; +using GmRelay.Shared.Features.Showcase; namespace GmRelay.Bot.Tests.Web; @@ -1209,6 +1210,15 @@ public sealed class AuthorizedSessionServiceTests public Task UpsertPlayerAsync(string platform, string externalUserId, string displayName, string? avatarUrl) => Task.CompletedTask; + public Task> GetShowcaseSessionsAsync(ShowcaseFilter filter, int page, int pageSize) => + Task.FromResult>([]); + + public Task GetShowcaseSessionAsync(Guid sessionId) => + Task.FromResult(null); + + public Task RegisterFromShowcaseAsync(Guid sessionId, string platform, string externalUserId, string displayName) => + Task.FromResult(false); + private bool IsManager(Guid groupId, long telegramId) => IsOwner(groupId, telegramId) || managers.Any(manager => manager.GroupId == groupId && manager.TelegramId == telegramId); diff --git a/tests/GmRelay.Bot.Tests/Web/ShowcaseQueryTests.cs b/tests/GmRelay.Bot.Tests/Web/ShowcaseQueryTests.cs new file mode 100644 index 0000000..5914bb7 --- /dev/null +++ b/tests/GmRelay.Bot.Tests/Web/ShowcaseQueryTests.cs @@ -0,0 +1,55 @@ +using GmRelay.Bot.Features.Sessions.CreateSession; +using GmRelay.Shared.Domain; + +namespace GmRelay.Bot.Tests.Web; + +public sealed class ShowcaseQueryTests +{ + [Fact] + public void RegisterFromShowcase_WhenUnlimitedSeats_ShouldReturnActive() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: null, activeParticipants: 5); + + Assert.Equal(ParticipantRegistrationStatus.Active, status); + } + + [Fact] + public void RegisterFromShowcase_WhenOneFreeSeat_ShouldReturnActive() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: 4, activeParticipants: 3); + + Assert.Equal(ParticipantRegistrationStatus.Active, status); + } + + [Fact] + public void RegisterFromShowcase_WhenExactlyAtCapacity_ShouldReturnWaitlisted() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: 4, activeParticipants: 4); + + Assert.Equal(ParticipantRegistrationStatus.Waitlisted, status); + } + + [Fact] + public void RegisterFromShowcase_WhenOverCapacity_ShouldReturnWaitlisted() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: 3, activeParticipants: 5); + + Assert.Equal(ParticipantRegistrationStatus.Waitlisted, status); + } + + [Fact] + public void RegisterFromShowcase_WhenZeroActiveAndZeroMax_ShouldReturnWaitlisted() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: 0, activeParticipants: 0); + + Assert.Equal(ParticipantRegistrationStatus.Waitlisted, status); + } + + [Fact] + public void RegisterFromShowcase_WhenZeroActiveAndPositiveMax_ShouldReturnActive() + { + var status = SessionCapacityRules.DecideJoinStatus(maxPlayers: 1, activeParticipants: 0); + + Assert.Equal(ParticipantRegistrationStatus.Active, status); + } +}