using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; 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 { 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 { 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"); } }