267 lines
7.7 KiB
C#
267 lines
7.7 KiB
C#
using ChatBot.Data;
|
|
using ChatBot.Data.Interfaces;
|
|
using ChatBot.Data.Repositories;
|
|
using ChatBot.Models.Entities;
|
|
using ChatBot.Tests.TestUtilities;
|
|
using FluentAssertions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
|
|
namespace ChatBot.Tests.Data.Repositories;
|
|
|
|
public class ChatSessionRepositoryTests : TestBase
|
|
{
|
|
private ChatBotDbContext _dbContext = null!;
|
|
private ChatSessionRepository _repository = null!;
|
|
|
|
public ChatSessionRepositoryTests()
|
|
{
|
|
SetupServices();
|
|
}
|
|
|
|
protected override void ConfigureServices(IServiceCollection services)
|
|
{
|
|
// Add in-memory database with unique name per test
|
|
services.AddDbContext<ChatBotDbContext>(options =>
|
|
options.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
|
);
|
|
|
|
// Add logger
|
|
services.AddSingleton(Mock.Of<ILogger<ChatSessionRepository>>());
|
|
|
|
// Add repository
|
|
services.AddScoped<IChatSessionRepository, ChatSessionRepository>();
|
|
}
|
|
|
|
protected override void SetupServices()
|
|
{
|
|
base.SetupServices();
|
|
|
|
_dbContext = ServiceProvider.GetRequiredService<ChatBotDbContext>();
|
|
_repository = (ChatSessionRepository)
|
|
ServiceProvider.GetRequiredService<IChatSessionRepository>();
|
|
|
|
// Ensure database is created
|
|
_dbContext.Database.EnsureCreated();
|
|
}
|
|
|
|
private void CleanupDatabase()
|
|
{
|
|
_dbContext.ChatSessions.RemoveRange(_dbContext.ChatSessions);
|
|
_dbContext.ChatMessages.RemoveRange(_dbContext.ChatMessages);
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOrCreateAsync_ShouldReturnExistingSession_WhenSessionExists()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
var chatType = "private";
|
|
var chatTitle = "Test Chat";
|
|
|
|
var existingSession = TestDataBuilder.Mocks.CreateChatSessionEntity(
|
|
1,
|
|
chatId,
|
|
"existing-session",
|
|
chatType,
|
|
chatTitle
|
|
);
|
|
_dbContext.ChatSessions.Add(existingSession);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _repository.GetOrCreateAsync(chatId, chatType, chatTitle);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.ChatId.Should().Be(chatId);
|
|
result.SessionId.Should().Be("existing-session");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetOrCreateAsync_ShouldCreateNewSession_WhenSessionDoesNotExist()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
var chatType = "private";
|
|
var chatTitle = "Test Chat";
|
|
|
|
// Act
|
|
var result = await _repository.GetOrCreateAsync(chatId, chatType, chatTitle);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.ChatId.Should().Be(chatId);
|
|
result.ChatType.Should().Be(chatType);
|
|
result.ChatTitle.Should().Be(chatTitle);
|
|
result.SessionId.Should().NotBeNullOrEmpty();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetByChatIdAsync_ShouldReturnSession_WhenSessionExists()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
var session = TestDataBuilder.Mocks.CreateChatSessionEntity(1, chatId);
|
|
_dbContext.ChatSessions.Add(session);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _repository.GetByChatIdAsync(chatId);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.ChatId.Should().Be(chatId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetByChatIdAsync_ShouldReturnNull_WhenSessionDoesNotExist()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
|
|
// Act
|
|
var result = await _repository.GetByChatIdAsync(chatId);
|
|
|
|
// Assert
|
|
result.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetBySessionIdAsync_ShouldReturnSession_WhenSessionExists()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var sessionId = "test-session";
|
|
var session = TestDataBuilder.Mocks.CreateChatSessionEntity(1, 12345, sessionId);
|
|
_dbContext.ChatSessions.Add(session);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _repository.GetBySessionIdAsync(sessionId);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.SessionId.Should().Be(sessionId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetBySessionIdAsync_ShouldReturnNull_WhenSessionDoesNotExist()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var sessionId = "nonexistent-session";
|
|
|
|
// Act
|
|
var result = await _repository.GetBySessionIdAsync(sessionId);
|
|
|
|
// Assert
|
|
result.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateAsync_ShouldUpdateSession()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var session = TestDataBuilder.Mocks.CreateChatSessionEntity(1, 12345);
|
|
_dbContext.ChatSessions.Add(session);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
session.ChatTitle = "Updated Title";
|
|
|
|
// Act
|
|
var result = await _repository.UpdateAsync(session);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.ChatTitle.Should().Be("Updated Title");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteAsync_ShouldReturnTrue_WhenSessionExists()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
var session = TestDataBuilder.Mocks.CreateChatSessionEntity(1, chatId);
|
|
_dbContext.ChatSessions.Add(session);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var result = await _repository.DeleteAsync(chatId);
|
|
|
|
// Assert
|
|
result.Should().BeTrue();
|
|
var deletedSession = await _repository.GetByChatIdAsync(chatId);
|
|
deletedSession.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteAsync_ShouldReturnFalse_WhenSessionDoesNotExist()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var chatId = 12345L;
|
|
|
|
// Act
|
|
var result = await _repository.DeleteAsync(chatId);
|
|
|
|
// Assert
|
|
result.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetActiveSessionsCountAsync_ShouldReturnCorrectCount()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
var session1 = TestDataBuilder.Mocks.CreateChatSessionEntity(1, 12345);
|
|
var session2 = TestDataBuilder.Mocks.CreateChatSessionEntity(2, 12346);
|
|
_dbContext.ChatSessions.AddRange(session1, session2);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var count = await _repository.GetActiveSessionsCountAsync();
|
|
|
|
// Assert
|
|
count.Should().Be(2);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CleanupOldSessionsAsync_ShouldRemoveOldSessions()
|
|
{
|
|
// Arrange
|
|
CleanupDatabase();
|
|
|
|
// Verify database is empty
|
|
var initialCount = await _repository.GetActiveSessionsCountAsync();
|
|
initialCount.Should().Be(0);
|
|
|
|
var oldSession = TestDataBuilder.Mocks.CreateChatSessionEntity(1, 12345);
|
|
oldSession.LastUpdatedAt = DateTime.UtcNow.AddDays(-2); // 2 days old
|
|
|
|
var recentSession = TestDataBuilder.Mocks.CreateChatSessionEntity(2, 12346);
|
|
recentSession.LastUpdatedAt = DateTime.UtcNow.AddMinutes(-30); // 30 minutes old
|
|
|
|
_dbContext.ChatSessions.AddRange(oldSession, recentSession);
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// Act
|
|
var removedCount = await _repository.CleanupOldSessionsAsync(1); // Remove sessions older than 1 hour
|
|
|
|
// Assert
|
|
removedCount.Should().Be(1);
|
|
var remainingSessions = await _repository.GetActiveSessionsCountAsync();
|
|
remainingSessions.Should().Be(1);
|
|
}
|
|
}
|