Files
ChatBot/ChatBot.Tests/Services/ChatServiceTests.cs
Leonid Pershin b816eb5aaf clear deps
2025-10-17 06:29:23 +03:00

319 lines
9.6 KiB
C#

using ChatBot.Models.Configuration;
using ChatBot.Services;
using ChatBot.Services.Interfaces;
using ChatBot.Tests.TestUtilities;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
namespace ChatBot.Tests.Services;
public class ChatServiceTests : UnitTestBase
{
private readonly Mock<ILogger<ChatService>> _loggerMock;
private readonly Mock<IAIService> _aiServiceMock;
private readonly Mock<ISessionStorage> _sessionStorageMock;
private readonly Mock<IHistoryCompressionService> _compressionServiceMock;
private readonly AISettings _aiSettings;
private readonly ChatService _chatService;
public ChatServiceTests()
{
_loggerMock = TestDataBuilder.Mocks.CreateLoggerMock<ChatService>();
_aiServiceMock = TestDataBuilder.Mocks.CreateAIServiceMock();
_sessionStorageMock = TestDataBuilder.Mocks.CreateSessionStorageMock();
_compressionServiceMock = TestDataBuilder.Mocks.CreateCompressionServiceMock();
_aiSettings = TestDataBuilder.Configurations.CreateAISettings();
var optionsMock = TestDataBuilder.Mocks.CreateOptionsMock(_aiSettings);
_chatService = new ChatService(
_loggerMock.Object,
_aiServiceMock.Object,
_sessionStorageMock.Object,
optionsMock.Object,
_compressionServiceMock.Object
);
}
[Fact]
public void GetOrCreateSession_ShouldCreateNewSession_WhenSessionDoesNotExist()
{
// Arrange
var chatId = 12345L;
var chatType = "private";
var chatTitle = "Test Chat";
// Act
var session = _chatService.GetOrCreateSession(chatId, chatType, chatTitle);
// Assert
session.Should().NotBeNull();
session.ChatId.Should().Be(chatId);
session.ChatType.Should().Be(chatType);
session.ChatTitle.Should().Be(chatTitle);
_sessionStorageMock.Verify(x => x.GetOrCreate(chatId, chatType, chatTitle), Times.Once);
}
[Fact]
public void GetOrCreateSession_ShouldSetCompressionService_WhenCompressionIsEnabled()
{
// Arrange
var chatId = 12345L;
_aiSettings.EnableHistoryCompression = true;
// Act
var session = _chatService.GetOrCreateSession(chatId);
// Assert
session.Should().NotBeNull();
_sessionStorageMock.Verify(x => x.GetOrCreate(chatId, "private", ""), Times.Once);
}
[Fact]
public async Task ProcessMessageAsync_ShouldProcessMessageSuccessfully_WhenValidInput()
{
// Arrange
var chatId = 12345L;
var username = "testuser";
var message = "Hello, bot!";
var expectedResponse = "Hello! How can I help you?";
_aiServiceMock
.Setup(x =>
x.GenerateChatCompletionWithCompressionAsync(
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
It.IsAny<CancellationToken>()
)
)
.ReturnsAsync(expectedResponse);
// Act
var result = await _chatService.ProcessMessageAsync(chatId, username, message);
// Assert
result.Should().Be(expectedResponse);
_sessionStorageMock.Verify(
x => x.SaveSessionAsync(It.IsAny<ChatBot.Models.ChatSession>()),
Times.AtLeastOnce
);
_aiServiceMock.Verify(
x =>
x.GenerateChatCompletionWithCompressionAsync(
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
It.IsAny<CancellationToken>()
),
Times.Once
);
}
[Fact]
public async Task ProcessMessageAsync_ShouldReturnEmptyString_WhenAIResponseIsEmptyMarker()
{
// Arrange
var chatId = 12345L;
var username = "testuser";
var message = "Hello, bot!";
var emptyResponse = "{empty}";
_aiServiceMock
.Setup(x =>
x.GenerateChatCompletionWithCompressionAsync(
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
It.IsAny<CancellationToken>()
)
)
.ReturnsAsync(emptyResponse);
// Act
var result = await _chatService.ProcessMessageAsync(chatId, username, message);
// Assert
result.Should().BeEmpty();
}
[Fact]
public async Task ProcessMessageAsync_ShouldReturnErrorMessage_WhenAIResponseIsNull()
{
// Arrange
var chatId = 12345L;
var username = "testuser";
var message = "Hello, bot!";
_aiServiceMock
.Setup(x =>
x.GenerateChatCompletionWithCompressionAsync(
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
It.IsAny<CancellationToken>()
)
)
.ReturnsAsync((string)null!);
// Act
var result = await _chatService.ProcessMessageAsync(chatId, username, message);
// Assert
result.Should().Be("Извините, произошла ошибка при генерации ответа.");
}
[Fact]
public async Task ProcessMessageAsync_ShouldHandleException_WhenErrorOccurs()
{
// Arrange
var chatId = 12345L;
var username = "testuser";
var message = "Hello, bot!";
_aiServiceMock
.Setup(x =>
x.GenerateChatCompletionWithCompressionAsync(
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
It.IsAny<CancellationToken>()
)
)
.ThrowsAsync(new Exception("Test exception"));
// Act
var result = await _chatService.ProcessMessageAsync(chatId, username, message);
// Assert
result.Should().Be("Извините, произошла ошибка при обработке вашего сообщения.");
// Verify that error was logged
// In a real test, we would verify the logger calls
}
[Fact]
public async Task UpdateSessionParametersAsync_ShouldUpdateSession_WhenSessionExists()
{
// Arrange
var chatId = 12345L;
var newModel = "llama3.2";
var session = TestDataBuilder.ChatSessions.CreateBasicSession(chatId);
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns(session);
// Act
await _chatService.UpdateSessionParametersAsync(chatId, newModel);
// Assert
session.Model.Should().Be(newModel);
_sessionStorageMock.Verify(x => x.SaveSessionAsync(session), Times.Once);
}
[Fact]
public async Task UpdateSessionParametersAsync_ShouldNotUpdate_WhenSessionDoesNotExist()
{
// Arrange
var chatId = 12345L;
var newModel = "llama3.2";
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns((ChatBot.Models.ChatSession?)null);
// Act
await _chatService.UpdateSessionParametersAsync(chatId, newModel);
// Assert
_sessionStorageMock.Verify(
x => x.SaveSessionAsync(It.IsAny<ChatBot.Models.ChatSession>()),
Times.Never
);
}
[Fact]
public async Task ClearHistoryAsync_ShouldClearHistory_WhenSessionExists()
{
// Arrange
var chatId = 12345L;
var session = TestDataBuilder.ChatSessions.CreateSessionWithMessages(chatId, 5);
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns(session);
// Act
await _chatService.ClearHistoryAsync(chatId);
// Assert
session.GetMessageCount().Should().Be(0);
_sessionStorageMock.Verify(x => x.SaveSessionAsync(session), Times.Once);
}
[Fact]
public void GetSession_ShouldReturnSession_WhenSessionExists()
{
// Arrange
var chatId = 12345L;
var session = TestDataBuilder.ChatSessions.CreateBasicSession(chatId);
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns(session);
// Act
var result = _chatService.GetSession(chatId);
// Assert
result.Should().Be(session);
}
[Fact]
public void GetSession_ShouldReturnNull_WhenSessionDoesNotExist()
{
// Arrange
var chatId = 12345L;
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns((ChatBot.Models.ChatSession?)null);
// Act
var result = _chatService.GetSession(chatId);
// Assert
result.Should().BeNull();
}
[Fact]
public void RemoveSession_ShouldReturnTrue_WhenSessionExists()
{
// Arrange
var chatId = 12345L;
_sessionStorageMock.Setup(x => x.Remove(chatId)).Returns(true);
// Act
var result = _chatService.RemoveSession(chatId);
// Assert
result.Should().BeTrue();
_sessionStorageMock.Verify(x => x.Remove(chatId), Times.Once);
}
[Fact]
public void GetActiveSessionsCount_ShouldReturnCorrectCount()
{
// Arrange
var expectedCount = 5;
_sessionStorageMock.Setup(x => x.GetActiveSessionsCount()).Returns(expectedCount);
// Act
var result = _chatService.GetActiveSessionsCount();
// Assert
result.Should().Be(expectedCount);
}
[Fact]
public void CleanupOldSessions_ShouldReturnCleanedCount()
{
// Arrange
var hoursOld = 24;
var expectedCleaned = 3;
_sessionStorageMock.Setup(x => x.CleanupOldSessions(hoursOld)).Returns(expectedCleaned);
// Act
var result = _chatService.CleanupOldSessions(hoursOld);
// Assert
result.Should().Be(expectedCleaned);
_sessionStorageMock.Verify(x => x.CleanupOldSessions(hoursOld), Times.Once);
}
}