Files
ChatBot/ChatBot.Tests/Telegram/Commands/CommandAttributeTests.cs
Leonid Pershin c9eac74e35
Some checks failed
SonarQube / Build and analyze (push) Failing after 3m2s
Unit Tests / Run Tests (push) Failing after 2m23s
Add more tests
2025-10-20 08:20:55 +03:00

447 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ChatBot.Services.Telegram.Commands;
using FluentAssertions;
using Xunit;
namespace ChatBot.Tests.Telegram.Commands;
public class CommandAttributeTests
{
[Fact]
public void CommandAttribute_ShouldHaveCorrectAttributeUsage()
{
// Arrange
var attributeType = typeof(CommandAttribute);
var attributeUsage = attributeType
.GetCustomAttributes(typeof(AttributeUsageAttribute), false)
.Cast<AttributeUsageAttribute>()
.FirstOrDefault();
// Assert
attributeUsage.Should().NotBeNull();
attributeUsage!.ValidOn.Should().Be(AttributeTargets.Class);
attributeUsage.AllowMultiple.Should().BeFalse();
}
[Fact]
public void CommandAttribute_ShouldSetCommandNameAndDescription()
{
// Arrange
var commandName = "/test";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().Be(description);
attribute.Priority.Should().Be(0); // Default value
}
[Fact]
public void CommandAttribute_ShouldAllowSettingPriority()
{
// Arrange
var commandName = "/test";
var description = "Test command";
var priority = 5;
// Act
var attribute = new CommandAttribute(commandName, description) { Priority = priority };
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().Be(description);
attribute.Priority.Should().Be(priority);
}
[Theory]
[InlineData("/start", "Start the bot")]
[InlineData("/help", "Show help")]
[InlineData("/status", "Show status")]
[InlineData("/clear", "Clear chat history")]
[InlineData("/settings", "Show settings")]
public void CommandAttribute_ShouldAcceptValidCommandNames(
string commandName,
string description
)
{
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().Be(description);
}
[Theory]
[InlineData("")]
[InlineData("start")]
[InlineData("help")]
[InlineData("status")]
[InlineData("clear")]
[InlineData("settings")]
public void CommandAttribute_ShouldAcceptCommandNamesWithoutSlash(string commandName)
{
// Arrange
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().Be(description);
}
[Theory]
[InlineData("")]
[InlineData("A simple description")]
[InlineData(
"A very long description that contains multiple words and explains what the command does in detail"
)]
[InlineData("Описание на русском языке")]
[InlineData("Description with special characters: !@#$%^&*()_+-=[]{}|;':\",./<>?")]
[InlineData("Description with unicode: 用户 ユーザー مستخدم")]
public void CommandAttribute_ShouldAcceptVariousDescriptions(string description)
{
// Arrange
var commandName = "/test";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().Be(description);
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(10)]
[InlineData(100)]
[InlineData(int.MaxValue)]
[InlineData(int.MinValue)]
[InlineData(-1)]
[InlineData(-100)]
public void CommandAttribute_ShouldAcceptVariousPriorities(int priority)
{
// Arrange
var commandName = "/test";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description) { Priority = priority };
// Assert
attribute.Priority.Should().Be(priority);
}
[Fact]
public void CommandAttribute_ShouldAllowNullCommandName()
{
// Arrange
string? commandName = null;
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName!, description);
// Assert
attribute.CommandName.Should().BeNull();
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldAllowNullDescription()
{
// Arrange
var commandName = "/test";
string? description = null;
// Act
var attribute = new CommandAttribute(commandName, description!);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.Description.Should().BeNull();
}
[Fact]
public void CommandAttribute_ShouldAllowBothNullValues()
{
// Arrange
string? commandName = null;
string? description = null;
// Act
var attribute = new CommandAttribute(commandName!, description!);
// Assert
attribute.CommandName.Should().BeNull();
attribute.Description.Should().BeNull();
}
[Fact]
public void CommandAttribute_ShouldBeImmutableAfterConstruction()
{
// Arrange
var commandName = "/test";
var description = "Test command";
var attribute = new CommandAttribute(commandName, description);
// Act & Assert
// CommandName and Description should be read-only
var commandNameProperty = typeof(CommandAttribute).GetProperty(
nameof(CommandAttribute.CommandName)
);
var descriptionProperty = typeof(CommandAttribute).GetProperty(
nameof(CommandAttribute.Description)
);
commandNameProperty!.CanWrite.Should().BeFalse();
descriptionProperty!.CanWrite.Should().BeFalse();
}
[Fact]
public void CommandAttribute_ShouldAllowPriorityModification()
{
// Arrange
var commandName = "/test";
var description = "Test command";
var attribute = new CommandAttribute(commandName, description);
// Act
attribute.Priority = 42;
// Assert
attribute.Priority.Should().Be(42);
}
[Fact]
public void CommandAttribute_ShouldInheritFromAttribute()
{
// Arrange & Act
var attribute = new CommandAttribute("/test", "Test command");
// Assert
attribute.Should().BeAssignableTo<Attribute>();
}
[Fact]
public void CommandAttribute_ShouldBeSerializable()
{
// Arrange
var commandName = "/test";
var description = "Test command";
var priority = 5;
var attribute = new CommandAttribute(commandName, description) { Priority = priority };
// Act & Assert
// Check if the attribute can be serialized (basic check)
attribute.Should().NotBeNull();
// Note: In .NET 5+, IsSerializable is obsolete and returns false for most types
// This test verifies the attribute can be created and used
attribute.GetType().Should().NotBeNull();
}
[Fact]
public void CommandAttribute_ShouldHandleVeryLongCommandName()
{
// Arrange
var commandName = new string('a', 1000); // Very long command name
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
attribute.CommandName.Should().HaveLength(1000);
}
[Fact]
public void CommandAttribute_ShouldHandleVeryLongDescription()
{
// Arrange
var commandName = "/test";
var description = new string('a', 10000); // Very long description
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
attribute.Description.Should().HaveLength(10000);
}
[Fact]
public void CommandAttribute_ShouldHandleCommandNameWithSpecialCharacters()
{
// Arrange
var commandName = "/test-command_with.special@chars#123";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithNewlines()
{
// Arrange
var commandName = "/test";
var description = "Line 1\nLine 2\nLine 3";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithTabs()
{
// Arrange
var commandName = "/test";
var description = "Column1\tColumn2\tColumn3";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithCarriageReturns()
{
// Arrange
var commandName = "/test";
var description = "Line 1\r\nLine 2\r\nLine 3";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleWhitespaceOnlyCommandName()
{
// Arrange
var commandName = " ";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
}
[Fact]
public void CommandAttribute_ShouldHandleWhitespaceOnlyDescription()
{
// Arrange
var commandName = "/test";
var description = " ";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleCommandNameWithUnicode()
{
// Arrange
var commandName = "/команда_命令_コマンド_أمر";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithUnicode()
{
// Arrange
var commandName = "/test";
var description = "Описание команды 命令描述 コマンドの説明 وصف الأمر";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleCommandNameWithSpaces()
{
// Arrange
var commandName = "/test command with spaces";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithSpaces()
{
// Arrange
var commandName = "/test";
var description = "This is a test command with multiple spaces";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
[Fact]
public void CommandAttribute_ShouldHandleCommandNameWithNumbers()
{
// Arrange
var commandName = "/test123";
var description = "Test command";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.CommandName.Should().Be(commandName);
}
[Fact]
public void CommandAttribute_ShouldHandleDescriptionWithNumbers()
{
// Arrange
var commandName = "/test";
var description = "Test command version 1.0.0 build 123";
// Act
var attribute = new CommandAttribute(commandName, description);
// Assert
attribute.Description.Should().Be(description);
}
}