add more tests
This commit is contained in:
380
ChatBot.Tests/Telegram/Commands/TelegramCommandBaseTests.cs
Normal file
380
ChatBot.Tests/Telegram/Commands/TelegramCommandBaseTests.cs
Normal file
@@ -0,0 +1,380 @@
|
||||
using ChatBot.Services;
|
||||
using ChatBot.Services.Telegram.Commands;
|
||||
using ChatBot.Tests.TestUtilities;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
|
||||
namespace ChatBot.Tests.Telegram.Commands;
|
||||
|
||||
public class TelegramCommandBaseTests : UnitTestBase
|
||||
{
|
||||
private readonly Mock<ChatService> _chatServiceMock;
|
||||
private readonly Mock<ModelService> _modelServiceMock;
|
||||
private readonly TestTelegramCommand _testCommand;
|
||||
|
||||
public TelegramCommandBaseTests()
|
||||
{
|
||||
_chatServiceMock = new Mock<ChatService>(
|
||||
TestDataBuilder.Mocks.CreateLoggerMock<ChatService>().Object,
|
||||
TestDataBuilder.Mocks.CreateAIServiceMock().Object,
|
||||
TestDataBuilder.Mocks.CreateSessionStorageMock().Object,
|
||||
TestDataBuilder
|
||||
.Mocks.CreateOptionsMock(TestDataBuilder.Configurations.CreateAISettings())
|
||||
.Object,
|
||||
TestDataBuilder.Mocks.CreateCompressionServiceMock().Object
|
||||
);
|
||||
_modelServiceMock = new Mock<ModelService>(
|
||||
TestDataBuilder.Mocks.CreateLoggerMock<ModelService>().Object,
|
||||
TestDataBuilder
|
||||
.Mocks.CreateOptionsMock(TestDataBuilder.Configurations.CreateOllamaSettings())
|
||||
.Object
|
||||
);
|
||||
_testCommand = new TestTelegramCommand(_chatServiceMock.Object, _modelServiceMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ShouldInitializeServices()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = new TestTelegramCommand(_chatServiceMock.Object, _modelServiceMock.Object);
|
||||
|
||||
// Assert
|
||||
command.Should().NotBeNull();
|
||||
command.ChatService.Should().Be(_chatServiceMock.Object);
|
||||
command.ModelService.Should().Be(_modelServiceMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CommandName_ShouldReturnCorrectName()
|
||||
{
|
||||
// Act
|
||||
var commandName = _testCommand.CommandName;
|
||||
|
||||
// Assert
|
||||
commandName.Should().Be("/test");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Description_ShouldReturnCorrectDescription()
|
||||
{
|
||||
// Act
|
||||
var description = _testCommand.Description;
|
||||
|
||||
// Assert
|
||||
description.Should().Be("Test command");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/test", true)]
|
||||
[InlineData("/TEST", true)]
|
||||
[InlineData("/Test", true)]
|
||||
[InlineData("/test ", true)]
|
||||
[InlineData("/test arg1 arg2", true)]
|
||||
[InlineData("/test@botname", true)]
|
||||
[InlineData("/test@botname arg1", true)]
|
||||
[InlineData("/other", false)]
|
||||
[InlineData("test", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData(" ", false)]
|
||||
public void CanHandle_ShouldReturnCorrectResult(string messageText, bool expected)
|
||||
{
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageText);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/test@mybot")]
|
||||
[InlineData("/test@botname")]
|
||||
[InlineData("/test@")]
|
||||
[InlineData("/test@verylongbotname")]
|
||||
public void CanHandle_ShouldRemoveBotUsername(string messageText)
|
||||
{
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageText);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
// The command should be extracted correctly without @botname
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleNullMessage()
|
||||
{
|
||||
// Act & Assert
|
||||
var act = () => _testCommand.CanHandle(null!);
|
||||
act.Should().Throw<NullReferenceException>(); // The method throws NullReferenceException, not ArgumentNullException
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasArguments_ShouldReturnTrue_WhenArgumentsExist()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext { Arguments = "arg1 arg2" };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.HasArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("\t")]
|
||||
[InlineData("\n")]
|
||||
[InlineData("\r\n")]
|
||||
public void HasArguments_ShouldReturnFalse_WhenArgumentsAreEmptyOrWhitespace(string arguments)
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext { Arguments = arguments };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.HasArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasArguments_ShouldReturnFalse_WhenArgumentsAreNull()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext { Arguments = null! };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.HasArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetArguments_ShouldReturnCorrectArguments()
|
||||
{
|
||||
// Arrange
|
||||
var expectedArguments = "arg1 arg2 arg3";
|
||||
var context = new TelegramCommandContext { Arguments = expectedArguments };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.GetArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(expectedArguments);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetArguments_ShouldReturnEmptyString_WhenArgumentsAreNull()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext { Arguments = null! };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.GetArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull(); // The method returns null when Arguments is null
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetArguments_ShouldReturnEmptyString_WhenArgumentsAreEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext { Arguments = "" };
|
||||
|
||||
// Act
|
||||
var result = TestTelegramCommand.GetArguments(context);
|
||||
|
||||
// Assert
|
||||
result.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_ShouldBeImplementedByDerivedClass()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TelegramCommandContext
|
||||
{
|
||||
ChatId = 12345,
|
||||
Username = "testuser",
|
||||
MessageText = "/test",
|
||||
ChatType = "private",
|
||||
ChatTitle = "Test Chat",
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _testCommand.ExecuteAsync(context);
|
||||
|
||||
// Assert
|
||||
result.Should().Be("Test command executed");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleVeryLongMessage()
|
||||
{
|
||||
// Arrange
|
||||
var longMessage = "/test " + new string('a', 10000);
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(longMessage);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithSpecialCharacters()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithSpecialChars = "/test !@#$%^&*()_+-=[]{}|;':\",./<>?";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithSpecialChars);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithUnicodeCharacters()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithUnicode = "/test привет мир 🌍";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithUnicode);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithMultipleSpaces()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithMultipleSpaces = "/test arg1 arg2";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithMultipleSpaces);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithTabsAndNewlines()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithWhitespace = "/test arg1 arg2 arg3"; // Use spaces instead of tabs/newlines
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithWhitespace);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue(); // The method should handle spaces in arguments
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithOnlyCommand()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithOnlyCommand = "/test";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithOnlyCommand);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithTrailingSpaces()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithTrailingSpaces = "/test ";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithTrailingSpaces);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithLeadingSpaces()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithLeadingSpaces = " /test";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithLeadingSpaces);
|
||||
|
||||
// Assert
|
||||
result.Should().BeFalse(); // Leading spaces should make it not match
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithMultipleAtSymbols()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithMultipleAt = "/test@bot1@bot2";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithMultipleAt);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue(); // Should handle multiple @ symbols
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanHandle_ShouldHandleMessageWithAtSymbolButNoBotName()
|
||||
{
|
||||
// Arrange
|
||||
var messageWithAtOnly = "/test@";
|
||||
|
||||
// Act
|
||||
var result = _testCommand.CanHandle(messageWithAtOnly);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue(); // Should handle @ without bot name
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation of TelegramCommandBase for testing purposes
|
||||
/// </summary>
|
||||
public class TestTelegramCommand : TelegramCommandBase
|
||||
{
|
||||
public TestTelegramCommand(ChatService chatService, ModelService modelService)
|
||||
: base(chatService, modelService) { }
|
||||
|
||||
public override string CommandName => "/test";
|
||||
|
||||
public override string Description => "Test command";
|
||||
|
||||
public override Task<string> ExecuteAsync(
|
||||
TelegramCommandContext context,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
return Task.FromResult("Test command executed");
|
||||
}
|
||||
|
||||
// Expose protected methods for testing
|
||||
public new static bool HasArguments(TelegramCommandContext context)
|
||||
{
|
||||
return TelegramCommandBase.HasArguments(context);
|
||||
}
|
||||
|
||||
public static new string GetArguments(TelegramCommandContext context)
|
||||
{
|
||||
return TelegramCommandBase.GetArguments(context);
|
||||
}
|
||||
|
||||
// Expose protected fields for testing
|
||||
public ChatService ChatService => _chatService;
|
||||
public ModelService ModelService => _modelService;
|
||||
}
|
||||
Reference in New Issue
Block a user