// using Luna.Channels.Abstractions; // using Luna.Channels.Telegram; // using Luna.Configuration; // using Luna.Shared; // using Microsoft.Extensions.Logging; // using Moq; // using Telegram.Bot; // using Telegram.Bot.Requests; // using Telegram.Bot.Types; // // namespace Luna.Channels.Tests; // // [TestFixture] // [Category("Unit")] // public class TelegramChannelTests // { // private Mock mockBotClient = null!; // private Mock> mockLogger = null!; // private TelegramOptions options = null!; // private TelegramChannel channel = null!; // // [SetUp] // public void SetUp() // { // mockBotClient = new Mock(); // mockLogger = new Mock>(); // options = new TelegramOptions { BotToken = "test-bot-token:ABCDEF" }; // channel = new TelegramChannel("100", mockBotClient.Object, mockLogger.Object, options); // } // // [TearDown] // public void TearDown() // { // channel.Dispose(); // } // // [Test] // public void ChannelType_Returns_Telegram() // { // Assert.That(channel.ChannelType, Is.EqualTo("telegram")); // } // // [Test] // public void ChannelId_IsSet_From_Constructor() // { // Assert.That(channel.ChannelId, Is.EqualTo("100")); // } // // [Test] // public void ChannelId_IsUnique_Per_Instance() // { // var channel1 = new TelegramChannel("111", mockBotClient.Object, mockLogger.Object, options); // var channel2 = new TelegramChannel("222", mockBotClient.Object, mockLogger.Object, options); // // Assert.That(channel1.ChannelId, Is.Not.EqualTo(channel2.ChannelId)); // // channel1.Dispose(); // channel2.Dispose(); // } // // [Test] // public void DisplayName_Contains_Telegram() // { // Assert.That(channel.DisplayName, Does.Contain("Telegram")); // } // // [Test] // public void IsConnected_Is_True_Initially() // { // Assert.That(channel.IsConnected, Is.True); // } // // [Test] // public void IsConnected_Is_False_After_Dispose() // { // channel.Dispose(); // // Assert.That(channel.IsConnected, Is.False); // } // // [Test] // public async Task SendMessageAsync_Calls_BotClient_SendMessage() // { // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 1, Chat = new Chat { Id = 100 } }); // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "100", "42", "Alice", "Hello!", DateTimeOffset.UtcNow); // // await channel.SendMessageAsync(message); // // mockBotClient.Verify( // c => c.SendRequest(It.IsAny(), It.IsAny()), // Times.Once); // } // // [Test] // public async Task SendMessageAsync_Handles_Network_Error_Without_Crash() // { // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ThrowsAsync(new HttpRequestException("Network error")); // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "100", "42", "Alice", "Hello!", DateTimeOffset.UtcNow); // // Assert.DoesNotThrowAsync(async () => await channel.SendMessageAsync(message)); // } // // [Test] // public void RaiseMessageReceived_Fires_Event_With_Correct_Mapping() // { // ChannelMessageReceivedEventArgs? captured = null; // channel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "999", "77", "Bob", "Hello Luna", DateTimeOffset.UtcNow); // // channel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Not.Null); // Assert.That(captured!.Message.ConversationId, Is.EqualTo("999")); // Assert.That(captured.Message.SenderId, Is.EqualTo("77")); // Assert.That(captured.Message.SenderName, Is.EqualTo("Bob")); // Assert.That(captured.Message.Content, Is.EqualTo("Hello Luna")); // Assert.That(captured.Channel, Is.SameAs(channel)); // } // // [Test] // public void RaiseMessageReceived_Maps_SenderName_And_Timestamp() // { // var sentAt = new DateTimeOffset(2025, 6, 1, 12, 0, 0, TimeSpan.Zero); // // ChannelMessageReceivedEventArgs? captured = null; // channel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "123", "55", "Carol", "Hi", sentAt); // // channel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Not.Null); // Assert.That(captured!.Message.SenderName, Is.EqualTo("Carol")); // Assert.That(captured.Message.Timestamp, Is.EqualTo(sentAt)); // } // // [Test] // public async Task SendStreamingMessageAsync_Sends_Initial_Then_Edits_In_Place() // { // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 10, Chat = new Chat { Id = 100 } }); // // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 10, Chat = new Chat { Id = 100 } }); // // var updates = new List // { // new(ChatStreamUpdateType.Text, "Hello ", null, false), // new(ChatStreamUpdateType.Text, "World", null, false), // new(ChatStreamUpdateType.Complete, null, null, true), // }; // // await channel.SendStreamingMessageAsync(updates.ToAsyncEnumerable()); // // // First chunk sends a message, second chunk edits it // mockBotClient.Verify( // c => c.SendRequest(It.IsAny(), It.IsAny()), // Times.Once); // // mockBotClient.Verify( // c => c.SendRequest(It.IsAny(), It.IsAny()), // Times.AtLeastOnce); // } // // [Test] // public async Task SendStreamingMessageAsync_Handles_4096_Char_Limit_By_Chunking() // { // var longContent = new string('A', 4097); // var updates = new List // { // new(ChatStreamUpdateType.Text, longContent, null, false), // new(ChatStreamUpdateType.Complete, null, null, true), // }; // // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 20, Chat = new Chat { Id = 100 } }); // // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 20, Chat = new Chat { Id = 100 } }); // // await channel.SendStreamingMessageAsync(updates.ToAsyncEnumerable()); // // // Content exceeds 4096 — needs at least 2 SendMessage calls (initial + overflow) // mockBotClient.Verify( // c => c.SendRequest(It.IsAny(), It.IsAny()), // Times.AtLeast(2)); // } // // [Test] // public async Task SendStreamingMessageAsync_Handles_IsComplete_True_With_Final_Edit() // { // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 30, Chat = new Chat { Id = 100 } }); // // mockBotClient // .Setup(c => c.SendRequest(It.IsAny(), It.IsAny())) // .ReturnsAsync(new Message { Id = 30, Chat = new Chat { Id = 100 } }); // // var updates = new List // { // new(ChatStreamUpdateType.Text, "Final answer", null, false), // new(ChatStreamUpdateType.Complete, null, null, true), // }; // // await channel.SendStreamingMessageAsync(updates.ToAsyncEnumerable()); // // // Initial message sent // mockBotClient.Verify( // c => c.SendRequest(It.IsAny(), It.IsAny()), // Times.Once); // } // // [Test] // public void AllowedUserIds_Non_Empty_Blocks_Unauthorized_User() // { // var restrictedOptions = new TelegramOptions // { // BotToken = "test-token", // AllowedUserIds = ["111", "222"] // }; // var restrictedChannel = new TelegramChannel( // "500", mockBotClient.Object, mockLogger.Object, restrictedOptions); // // ChannelMessageReceivedEventArgs? captured = null; // restrictedChannel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "500", "999", "Hacker", "attack", DateTimeOffset.UtcNow); // // restrictedChannel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Null, "Message from unauthorized user should be silently ignored"); // // restrictedChannel.Dispose(); // } // // [Test] // public void AllowedUserIds_Non_Empty_Allows_Authorized_User() // { // var restrictedOptions = new TelegramOptions // { // BotToken = "test-token", // AllowedUserIds = ["111", "222"] // }; // var restrictedChannel = new TelegramChannel( // "500", mockBotClient.Object, mockLogger.Object, restrictedOptions); // // ChannelMessageReceivedEventArgs? captured = null; // restrictedChannel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "500", "111", "TrustedUser", "hello", DateTimeOffset.UtcNow); // // restrictedChannel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Not.Null, "Message from authorized user should be accepted"); // // restrictedChannel.Dispose(); // } // // [Test] // public void AllowedUserIds_Empty_Accepts_All_Users() // { // var openOptions = new TelegramOptions // { // BotToken = "test-token", // AllowedUserIds = [] // }; // var openChannel = new TelegramChannel( // "600", mockBotClient.Object, mockLogger.Object, openOptions); // // ChannelMessageReceivedEventArgs? captured = null; // openChannel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "600", "12345", "Anyone", "hello", DateTimeOffset.UtcNow); // // openChannel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Not.Null, "Message should be accepted when AllowedUserIds is empty"); // // openChannel.Dispose(); // } // // [Test] // public void Malformed_Message_With_Null_Text_Is_Skipped() // { // ChannelMessageReceivedEventArgs? captured = null; // channel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "700", "88", "Ghost", null!, DateTimeOffset.UtcNow); // // channel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Null, "Message with null text should be silently skipped"); // } // // [Test] // public void Malformed_Message_With_Empty_Text_Is_Skipped() // { // ChannelMessageReceivedEventArgs? captured = null; // channel.MessageReceived += (_, args) => { captured = args; return Task.CompletedTask; }; // // var message = new ChannelMessage( // Guid.NewGuid().ToString(), "700", "88", "Ghost", "", DateTimeOffset.UtcNow); // // channel.RaiseMessageReceived(message); // // Assert.That(captured, Is.Null, "Message with empty text should be silently skipped"); // } // // [Test] // public void Dispose_Fires_ConnectionStateChanged() // { // ChannelConnectionEventArgs? captured = null; // channel.ConnectionStateChanged += (_, args) => // { // captured = args; // return Task.CompletedTask; // }; // // channel.Dispose(); // // Assert.That(captured, Is.Not.Null); // Assert.That(captured!.IsConnected, Is.False); // Assert.That(captured.Channel, Is.SameAs(channel)); // } // }