using ChatBot.Data; using ChatBot.Data.Interfaces; using ChatBot.Data.Repositories; using ChatBot.Models; using ChatBot.Models.Entities; using ChatBot.Services; 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.Services; public class DatabaseSessionStorageTests : TestBase { private ChatBotDbContext _dbContext = null!; private DatabaseSessionStorage _sessionStorage = null!; private Mock _repositoryMock = null!; public DatabaseSessionStorageTests() { SetupServices(); } protected override void ConfigureServices(IServiceCollection services) { // Add in-memory database services.AddDbContext(options => options.UseInMemoryDatabase("TestDatabase") ); // Add mocked repository _repositoryMock = new Mock(); services.AddSingleton(_repositoryMock.Object); // Add logger services.AddSingleton(Mock.Of>()); // Add session storage services.AddScoped(); } protected override void SetupServices() { base.SetupServices(); _dbContext = ServiceProvider.GetRequiredService(); _sessionStorage = ServiceProvider.GetRequiredService(); // Ensure database is created _dbContext.Database.EnsureCreated(); } [Fact] public void GetOrCreate_ShouldReturnExistingSession_WhenSessionExists() { // Arrange var existingSession = TestDataBuilder.Mocks.CreateChatSessionEntity(); _repositoryMock .Setup(x => x.GetOrCreateAsync(12345, "private", "Test Chat")) .ReturnsAsync(existingSession); // Act var result = _sessionStorage.GetOrCreate(12345, "private", "Test Chat"); // Assert result.Should().NotBeNull(); result.ChatId.Should().Be(12345); _repositoryMock.Verify(x => x.GetOrCreateAsync(12345, "private", "Test Chat"), Times.Once); } [Fact] public void Get_ShouldReturnSession_WhenSessionExists() { // Arrange var sessionEntity = TestDataBuilder.Mocks.CreateChatSessionEntity(); _repositoryMock.Setup(x => x.GetByChatIdAsync(12345)).ReturnsAsync(sessionEntity); // Act var result = _sessionStorage.Get(12345); // Assert result.Should().NotBeNull(); result.ChatId.Should().Be(12345); _repositoryMock.Verify(x => x.GetByChatIdAsync(12345), Times.Once); } [Fact] public void Get_ShouldReturnNull_WhenSessionDoesNotExist() { // Arrange _repositoryMock .Setup(x => x.GetByChatIdAsync(12345)) .ReturnsAsync((ChatSessionEntity?)null); // Act var result = _sessionStorage.Get(12345); // Assert result.Should().BeNull(); _repositoryMock.Verify(x => x.GetByChatIdAsync(12345), Times.Once); } [Fact] public async Task SaveSessionAsync_ShouldUpdateSession_WhenSessionExists() { // Arrange var session = TestDataBuilder.ChatSessions.CreateBasicSession(12345, "private"); var sessionEntity = TestDataBuilder.Mocks.CreateChatSessionEntity(); _repositoryMock.Setup(x => x.GetByChatIdAsync(12345)).ReturnsAsync(sessionEntity); _repositoryMock .Setup(x => x.UpdateAsync(It.IsAny())) .ReturnsAsync(sessionEntity); // Act await _sessionStorage.SaveSessionAsync(session); // Assert _repositoryMock.Verify(x => x.UpdateAsync(It.IsAny()), Times.Once); } [Fact] public void Remove_ShouldReturnTrue_WhenSessionExists() { // Arrange _repositoryMock.Setup(x => x.DeleteAsync(12345)).ReturnsAsync(true); // Act var result = _sessionStorage.Remove(12345); // Assert result.Should().BeTrue(); _repositoryMock.Verify(x => x.DeleteAsync(12345), Times.Once); } [Fact] public void Remove_ShouldReturnFalse_WhenSessionDoesNotExist() { // Arrange _repositoryMock.Setup(x => x.DeleteAsync(12345)).ReturnsAsync(false); // Act var result = _sessionStorage.Remove(12345); // Assert result.Should().BeFalse(); _repositoryMock.Verify(x => x.DeleteAsync(12345), Times.Once); } [Fact] public void GetActiveSessionsCount_ShouldReturnCorrectCount() { // Arrange var expectedCount = 5; _repositoryMock.Setup(x => x.GetActiveSessionsCountAsync()).ReturnsAsync(expectedCount); // Act var result = _sessionStorage.GetActiveSessionsCount(); // Assert result.Should().Be(expectedCount); _repositoryMock.Verify(x => x.GetActiveSessionsCountAsync(), Times.Once); } [Fact] public void CleanupOldSessions_ShouldReturnCorrectCount() { // Arrange var expectedCount = 3; _repositoryMock.Setup(x => x.CleanupOldSessionsAsync(24)).ReturnsAsync(expectedCount); // Act var result = _sessionStorage.CleanupOldSessions(24); // Assert result.Should().Be(expectedCount); _repositoryMock.Verify(x => x.CleanupOldSessionsAsync(24), Times.Once); } }