Files
ChatBot/ChatBot.Tests/Models/ChatSessionEntityTests.cs
Leonid Pershin 1c910d7b7f
All checks were successful
SonarQube / Build and analyze (push) Successful in 3m54s
Unit Tests / Run Tests (push) Successful in 2m23s
add tests
2025-10-20 15:11:42 +03:00

690 lines
20 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using ChatBot.Models.Entities;
using FluentAssertions;
namespace ChatBot.Tests.Models;
public class ChatSessionEntityTests
{
[Fact]
public void Constructor_ShouldInitializePropertiesWithDefaultValues()
{
// Arrange & Act
var entity = new ChatSessionEntity();
// Assert
entity.Id.Should().Be(0);
entity.SessionId.Should().Be(string.Empty);
entity.ChatId.Should().Be(0);
entity.ChatType.Should().Be("private");
entity.ChatTitle.Should().Be(string.Empty);
entity.Model.Should().Be(string.Empty);
entity.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
entity.LastUpdatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
entity.MaxHistoryLength.Should().Be(30);
entity.Messages.Should().NotBeNull();
entity.Messages.Should().BeEmpty();
}
[Fact]
public void Id_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedId = 123;
// Act
entity.Id = expectedId;
// Assert
entity.Id.Should().Be(expectedId);
}
[Fact]
public void SessionId_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedSessionId = "session-123";
// Act
entity.SessionId = expectedSessionId;
// Assert
entity.SessionId.Should().Be(expectedSessionId);
}
[Fact]
public void ChatId_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedChatId = 987654321L;
// Act
entity.ChatId = expectedChatId;
// Assert
entity.ChatId.Should().Be(expectedChatId);
}
[Fact]
public void ChatType_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedChatType = "group";
// Act
entity.ChatType = expectedChatType;
// Assert
entity.ChatType.Should().Be(expectedChatType);
}
[Fact]
public void ChatTitle_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedChatTitle = "My Test Group";
// Act
entity.ChatTitle = expectedChatTitle;
// Assert
entity.ChatTitle.Should().Be(expectedChatTitle);
}
[Fact]
public void Model_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedModel = "llama3.1:8b";
// Act
entity.Model = expectedModel;
// Assert
entity.Model.Should().Be(expectedModel);
}
[Fact]
public void CreatedAt_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedDate = DateTime.UtcNow.AddDays(-1);
// Act
entity.CreatedAt = expectedDate;
// Assert
entity.CreatedAt.Should().Be(expectedDate);
}
[Fact]
public void LastUpdatedAt_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedDate = DateTime.UtcNow.AddHours(-2);
// Act
entity.LastUpdatedAt = expectedDate;
// Assert
entity.LastUpdatedAt.Should().Be(expectedDate);
}
[Fact]
public void MaxHistoryLength_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedLength = 50;
// Act
entity.MaxHistoryLength = expectedLength;
// Assert
entity.MaxHistoryLength.Should().Be(expectedLength);
}
[Fact]
public void Messages_ShouldBeSettable()
{
// Arrange
var entity = new ChatSessionEntity();
var expectedMessages = new List<ChatMessageEntity>
{
new() { Content = "Test message 1", Role = "user" },
new() { Content = "Test message 2", Role = "assistant" },
};
// Act
entity.Messages = expectedMessages;
// Assert
entity.Messages.Should().BeSameAs(expectedMessages);
entity.Messages.Should().HaveCount(2);
}
[Theory]
[InlineData("private")]
[InlineData("group")]
[InlineData("supergroup")]
[InlineData("channel")]
public void ChatType_ShouldAcceptValidTypes(string chatType)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.ChatType = chatType;
// Assert
entity.ChatType.Should().Be(chatType);
}
[Theory]
[InlineData("")]
[InlineData("a")]
[InlineData("very long chat type name")]
public void ChatType_ShouldAcceptVariousLengths(string chatType)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.ChatType = chatType;
// Assert
entity.ChatType.Should().Be(chatType);
}
[Theory]
[InlineData("")]
[InlineData("Short title")]
[InlineData("A very long chat title that contains a lot of text and should still be valid")]
public void ChatTitle_ShouldAcceptVariousLengths(string chatTitle)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.ChatTitle = chatTitle;
// Assert
entity.ChatTitle.Should().Be(chatTitle);
}
[Theory]
[InlineData("")]
[InlineData("llama3.1:8b")]
[InlineData("gpt-4")]
[InlineData("claude-3-sonnet")]
public void Model_ShouldAcceptVariousModels(string model)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.Model = model;
// Assert
entity.Model.Should().Be(model);
}
[Theory]
[InlineData("")]
[InlineData("session-123")]
[InlineData("very-long-session-id-that-exceeds-normal-length")]
public void SessionId_ShouldAcceptVariousLengths(string sessionId)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.SessionId = sessionId;
// Assert
entity.SessionId.Should().Be(sessionId);
}
[Theory]
[InlineData(0L)]
[InlineData(123456789L)]
[InlineData(-987654321L)]
[InlineData(long.MaxValue)]
[InlineData(long.MinValue)]
public void ChatId_ShouldAcceptVariousValues(long chatId)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.ChatId = chatId;
// Assert
entity.ChatId.Should().Be(chatId);
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(30)]
[InlineData(100)]
[InlineData(int.MaxValue)]
public void MaxHistoryLength_ShouldAcceptVariousValues(int maxHistoryLength)
{
// Arrange
var entity = new ChatSessionEntity();
// Act
entity.MaxHistoryLength = maxHistoryLength;
// Assert
entity.MaxHistoryLength.Should().Be(maxHistoryLength);
}
[Fact]
public void CreatedAt_ShouldDefaultToCurrentUtcTime()
{
// Arrange
var beforeCreation = DateTime.UtcNow;
// Act
var entity = new ChatSessionEntity();
// Assert
entity.CreatedAt.Should().BeOnOrAfter(beforeCreation);
entity.CreatedAt.Should().BeOnOrBefore(DateTime.UtcNow);
}
[Fact]
public void LastUpdatedAt_ShouldDefaultToCurrentUtcTime()
{
// Arrange
var beforeCreation = DateTime.UtcNow;
// Act
var entity = new ChatSessionEntity();
// Assert
entity.LastUpdatedAt.Should().BeOnOrAfter(beforeCreation);
entity.LastUpdatedAt.Should().BeOnOrBefore(DateTime.UtcNow);
}
[Fact]
public void AllProperties_ShouldBeMutable()
{
// Arrange
var entity = new ChatSessionEntity();
var messages = new List<ChatMessageEntity>
{
new() { Content = "Test", Role = "user" },
};
// Act
entity.Id = 1;
entity.SessionId = "test-session";
entity.ChatId = 123456789L;
entity.ChatType = "group";
entity.ChatTitle = "Test Group";
entity.Model = "llama3.1:8b";
entity.CreatedAt = DateTime.UtcNow.AddDays(-1);
entity.LastUpdatedAt = DateTime.UtcNow.AddHours(-1);
entity.MaxHistoryLength = 50;
entity.Messages = messages;
// Assert
entity.Id.Should().Be(1);
entity.SessionId.Should().Be("test-session");
entity.ChatId.Should().Be(123456789L);
entity.ChatType.Should().Be("group");
entity.ChatTitle.Should().Be("Test Group");
entity.Model.Should().Be("llama3.1:8b");
entity.CreatedAt.Should().BeCloseTo(DateTime.UtcNow.AddDays(-1), TimeSpan.FromSeconds(1));
entity
.LastUpdatedAt.Should()
.BeCloseTo(DateTime.UtcNow.AddHours(-1), TimeSpan.FromSeconds(1));
entity.MaxHistoryLength.Should().Be(50);
entity.Messages.Should().BeSameAs(messages);
}
[Fact]
public void Entity_ShouldHaveCorrectTableAttribute()
{
// Arrange
var entityType = typeof(ChatSessionEntity);
var tableAttribute =
entityType.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault()
as TableAttribute;
// Assert
tableAttribute.Should().NotBeNull();
tableAttribute!.Name.Should().Be("chat_sessions");
}
[Fact]
public void Id_ShouldHaveKeyAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.Id));
var keyAttribute =
property?.GetCustomAttributes(typeof(KeyAttribute), false).FirstOrDefault()
as KeyAttribute;
// Assert
keyAttribute.Should().NotBeNull();
}
[Fact]
public void Id_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.Id));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("id");
}
[Fact]
public void SessionId_ShouldHaveRequiredAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.SessionId));
var requiredAttribute =
property?.GetCustomAttributes(typeof(RequiredAttribute), false).FirstOrDefault()
as RequiredAttribute;
// Assert
requiredAttribute.Should().NotBeNull();
}
[Fact]
public void SessionId_ShouldHaveStringLengthAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.SessionId));
var stringLengthAttribute =
property?.GetCustomAttributes(typeof(StringLengthAttribute), false).FirstOrDefault()
as StringLengthAttribute;
// Assert
stringLengthAttribute.Should().NotBeNull();
stringLengthAttribute!.MaximumLength.Should().Be(50);
}
[Fact]
public void SessionId_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.SessionId));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("session_id");
}
[Fact]
public void ChatId_ShouldHaveRequiredAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatId));
var requiredAttribute =
property?.GetCustomAttributes(typeof(RequiredAttribute), false).FirstOrDefault()
as RequiredAttribute;
// Assert
requiredAttribute.Should().NotBeNull();
}
[Fact]
public void ChatId_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatId));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("chat_id");
}
[Fact]
public void ChatType_ShouldHaveRequiredAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatType));
var requiredAttribute =
property?.GetCustomAttributes(typeof(RequiredAttribute), false).FirstOrDefault()
as RequiredAttribute;
// Assert
requiredAttribute.Should().NotBeNull();
}
[Fact]
public void ChatType_ShouldHaveStringLengthAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatType));
var stringLengthAttribute =
property?.GetCustomAttributes(typeof(StringLengthAttribute), false).FirstOrDefault()
as StringLengthAttribute;
// Assert
stringLengthAttribute.Should().NotBeNull();
stringLengthAttribute!.MaximumLength.Should().Be(20);
}
[Fact]
public void ChatType_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatType));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("chat_type");
}
[Fact]
public void ChatTitle_ShouldHaveStringLengthAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatTitle));
var stringLengthAttribute =
property?.GetCustomAttributes(typeof(StringLengthAttribute), false).FirstOrDefault()
as StringLengthAttribute;
// Assert
stringLengthAttribute.Should().NotBeNull();
stringLengthAttribute!.MaximumLength.Should().Be(200);
}
[Fact]
public void ChatTitle_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.ChatTitle));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("chat_title");
}
[Fact]
public void Model_ShouldHaveStringLengthAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.Model));
var stringLengthAttribute =
property?.GetCustomAttributes(typeof(StringLengthAttribute), false).FirstOrDefault()
as StringLengthAttribute;
// Assert
stringLengthAttribute.Should().NotBeNull();
stringLengthAttribute!.MaximumLength.Should().Be(100);
}
[Fact]
public void Model_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.Model));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("model");
}
[Fact]
public void CreatedAt_ShouldHaveRequiredAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.CreatedAt));
var requiredAttribute =
property?.GetCustomAttributes(typeof(RequiredAttribute), false).FirstOrDefault()
as RequiredAttribute;
// Assert
requiredAttribute.Should().NotBeNull();
}
[Fact]
public void CreatedAt_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(nameof(ChatSessionEntity.CreatedAt));
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("created_at");
}
[Fact]
public void LastUpdatedAt_ShouldHaveRequiredAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(
nameof(ChatSessionEntity.LastUpdatedAt)
);
var requiredAttribute =
property?.GetCustomAttributes(typeof(RequiredAttribute), false).FirstOrDefault()
as RequiredAttribute;
// Assert
requiredAttribute.Should().NotBeNull();
}
[Fact]
public void LastUpdatedAt_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(
nameof(ChatSessionEntity.LastUpdatedAt)
);
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("last_updated_at");
}
[Fact]
public void MaxHistoryLength_ShouldHaveColumnAttribute()
{
// Arrange
var property = typeof(ChatSessionEntity).GetProperty(
nameof(ChatSessionEntity.MaxHistoryLength)
);
var columnAttribute =
property?.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault()
as ColumnAttribute;
// Assert
columnAttribute.Should().NotBeNull();
columnAttribute!.Name.Should().Be("max_history_length");
}
[Fact]
public void JsonSerialization_RoundTrip_ShouldPreserveScalarProperties()
{
// Arrange
var original = new ChatSessionEntity
{
Id = 101,
SessionId = "session-json-1",
ChatId = 123456789L,
ChatType = "group",
ChatTitle = "Test Group",
Model = "llama3.1:8b",
CreatedAt = DateTime.UtcNow.AddMinutes(-10),
LastUpdatedAt = DateTime.UtcNow.AddMinutes(-5),
MaxHistoryLength = 77,
Messages = new List<ChatMessageEntity>(),
};
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false,
DefaultIgnoreCondition = System
.Text
.Json
.Serialization
.JsonIgnoreCondition
.WhenWritingNull,
};
// Act
var json = JsonSerializer.Serialize(original, options);
var deserialized = JsonSerializer.Deserialize<ChatSessionEntity>(json, options)!;
// Assert
deserialized.Id.Should().Be(original.Id);
deserialized.SessionId.Should().Be(original.SessionId);
deserialized.ChatId.Should().Be(original.ChatId);
deserialized.ChatType.Should().Be(original.ChatType);
deserialized.ChatTitle.Should().Be(original.ChatTitle);
deserialized.Model.Should().Be(original.Model);
deserialized.MaxHistoryLength.Should().Be(original.MaxHistoryLength);
// Allow small delta for DateTime serialization
deserialized.CreatedAt.Should().BeCloseTo(original.CreatedAt, TimeSpan.FromSeconds(1));
deserialized
.LastUpdatedAt.Should()
.BeCloseTo(original.LastUpdatedAt, TimeSpan.FromSeconds(1));
deserialized.Messages.Should().NotBeNull();
deserialized.Messages.Should().BeEmpty();
}
}