using GmRelay.Bot.Infrastructure.Telegram; namespace GmRelay.Bot.Tests.Infrastructure.Telegram; public sealed class TelegramTopicRoutingTests { [Fact] public void ResolveNewScheduleDestination_UsesIncomingTopic_WhenForumCommandWasSentInsideTopic() { var destination = TelegramTopicRouting.ResolveNewScheduleDestination( chatIsForum: true, incomingMessageThreadId: 42); Assert.Equal(42, destination.MessageThreadId); Assert.False(destination.ShouldCreateForumTopic); Assert.False(destination.TopicCreatedByBot); } [Fact] public void ResolveNewScheduleDestination_CreatesBotOwnedTopic_WhenForumCommandWasSentInRoot() { var destination = TelegramTopicRouting.ResolveNewScheduleDestination( chatIsForum: true, incomingMessageThreadId: null); Assert.Null(destination.MessageThreadId); Assert.True(destination.ShouldCreateForumTopic); Assert.True(destination.TopicCreatedByBot); } [Fact] public void ResolveNewScheduleDestination_UsesPlainChat_WhenChatIsNotForum() { var destination = TelegramTopicRouting.ResolveNewScheduleDestination( chatIsForum: false, incomingMessageThreadId: 42); Assert.Null(destination.MessageThreadId); Assert.False(destination.ShouldCreateForumTopic); Assert.False(destination.TopicCreatedByBot); } [Fact] public void MissingForumTopicRightsMessage_NamesRequiredAdminRight() { Assert.Contains("admin", TelegramTopicRouting.MissingForumTopicRightsMessage, StringComparison.OrdinalIgnoreCase); Assert.Contains("Manage Topics", TelegramTopicRouting.MissingForumTopicRightsMessage, StringComparison.Ordinal); } [Theory] [InlineData("Bad Request: not enough rights to create forum topic")] [InlineData("Bad Request: CHAT_ADMIN_REQUIRED")] [InlineData("Forbidden: bot is not an administrator")] public void IsMissingForumTopicRightsError_MatchesAdminPermissionErrors(string apiError) { Assert.True(TelegramTopicRouting.IsMissingForumTopicRightsError(apiError)); } [Fact] public void IsMissingForumTopicRightsError_IgnoresUnrelatedApiErrors() { Assert.False(TelegramTopicRouting.IsMissingForumTopicRightsError("Bad Request: topic name is invalid")); } [Theory] [InlineData(true, 0, true)] [InlineData(true, 1, false)] [InlineData(false, 0, false)] public void ShouldDeleteForumTopic_DeletesOnlyBotOwnedEmptyTopic( bool topicCreatedByBot, int remainingSessionsInTopic, bool expected) { var shouldDelete = TelegramTopicRouting.ShouldDeleteForumTopic( topicCreatedByBot, remainingSessionsInTopic); Assert.Equal(expected, shouldDelete); } }