247 lines
8.2 KiB
C#
247 lines
8.2 KiB
C#
using System.Linq;
|
|
using ChatBot.Models;
|
|
using ChatBot.Models.Configuration;
|
|
using ChatBot.Models.Dto;
|
|
using ChatBot.Services;
|
|
using ChatBot.Services.Interfaces;
|
|
using ChatBot.Tests.TestUtilities;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using Moq;
|
|
using OllamaSharp.Models.Chat;
|
|
|
|
namespace ChatBot.Tests.Integration;
|
|
|
|
public class ChatServiceIntegrationTests : TestBase
|
|
{
|
|
private ChatService _chatService = null!;
|
|
private Mock<ISessionStorage> _sessionStorageMock = null!;
|
|
private Mock<IAIService> _aiServiceMock = null!;
|
|
|
|
public ChatServiceIntegrationTests()
|
|
{
|
|
SetupServices();
|
|
}
|
|
|
|
protected override void ConfigureServices(IServiceCollection services)
|
|
{
|
|
// Add mocked services
|
|
_sessionStorageMock = TestDataBuilder.Mocks.CreateSessionStorageMock();
|
|
_aiServiceMock = TestDataBuilder.Mocks.CreateAIServiceMock();
|
|
|
|
services.AddSingleton(_sessionStorageMock.Object);
|
|
services.AddSingleton(_aiServiceMock.Object);
|
|
services.AddSingleton(Mock.Of<ILogger<ChatService>>());
|
|
services.AddSingleton(
|
|
TestDataBuilder
|
|
.Mocks.CreateOptionsMock(TestDataBuilder.Configurations.CreateAISettings())
|
|
.Object
|
|
);
|
|
services.AddSingleton(TestDataBuilder.Mocks.CreateCompressionServiceMock().Object);
|
|
services.AddScoped<ChatService>();
|
|
}
|
|
|
|
protected override void SetupServices()
|
|
{
|
|
base.SetupServices();
|
|
_chatService = ServiceProvider.GetRequiredService<ChatService>();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProcessMessageAsync_ShouldProcessUserMessage_WhenSessionExists()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
var username = "testuser";
|
|
var message = "Hello, how are you?";
|
|
var expectedResponse = "I'm doing well, thank you!";
|
|
|
|
var session = TestDataBuilder.ChatSessions.CreateBasicSession(chatId);
|
|
_sessionStorageMock.Setup(x => x.GetOrCreate(chatId, "private", "")).Returns(session);
|
|
|
|
_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);
|
|
session.GetAllMessages().Should().HaveCount(2); // User message + AI response
|
|
session.GetAllMessages()[0].Content.Should().Be(message);
|
|
session.GetAllMessages()[0].Role.Should().Be(ChatRole.User);
|
|
session.GetAllMessages()[1].Content.Should().Be(expectedResponse);
|
|
session.GetAllMessages()[1].Role.Should().Be(ChatRole.Assistant);
|
|
|
|
_sessionStorageMock.Verify(x => x.SaveSessionAsync(session), Times.Exactly(2));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProcessMessageAsync_ShouldCreateNewSession_WhenSessionDoesNotExist()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
var username = "testuser";
|
|
var message = "Hello";
|
|
var expectedResponse = "Hi there!";
|
|
|
|
_sessionStorageMock
|
|
.Setup(x => x.GetOrCreate(chatId, "private", ""))
|
|
.Returns(TestDataBuilder.ChatSessions.CreateBasicSession(chatId));
|
|
|
|
_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.GetOrCreate(chatId, "private", ""), Times.Once);
|
|
_sessionStorageMock.Verify(
|
|
x => x.SaveSessionAsync(It.IsAny<ChatBot.Models.ChatSession>()),
|
|
Times.Exactly(2)
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProcessMessageAsync_ShouldHandleEmptyMessage()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
var username = "testuser";
|
|
var message = "";
|
|
var expectedResponse = "I didn't receive a message. Could you please try again?";
|
|
|
|
var session = TestDataBuilder.ChatSessions.CreateBasicSession(chatId);
|
|
_sessionStorageMock.Setup(x => x.GetOrCreate(chatId, "private", "")).Returns(session);
|
|
|
|
_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);
|
|
session.GetAllMessages().Should().HaveCount(2);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProcessMessageAsync_ShouldHandleAIServiceException()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
var username = "testuser";
|
|
var message = "Hello";
|
|
|
|
var session = TestDataBuilder.ChatSessions.CreateBasicSession(chatId);
|
|
_sessionStorageMock.Setup(x => x.GetOrCreate(chatId, "private", "")).Returns(session);
|
|
|
|
_aiServiceMock
|
|
.Setup(x =>
|
|
x.GenerateChatCompletionWithCompressionAsync(
|
|
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
|
|
It.IsAny<CancellationToken>()
|
|
)
|
|
)
|
|
.ThrowsAsync(new Exception("AI service error"));
|
|
|
|
// Act
|
|
var result = await _chatService.ProcessMessageAsync(chatId, username, message);
|
|
|
|
// Assert - should return error message instead of throwing
|
|
result.Should().Contain("ошибка");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProcessMessageAsync_ShouldUseCompression_WhenEnabled()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
var username = "testuser";
|
|
var message = "Hello";
|
|
var expectedResponse = "Hi there!";
|
|
|
|
var session = TestDataBuilder.ChatSessions.CreateSessionWithMessages(chatId, 10); // 10 messages
|
|
_sessionStorageMock.Setup(x => x.GetOrCreate(chatId, "private", "")).Returns(session);
|
|
|
|
_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);
|
|
_aiServiceMock.Verify(
|
|
x =>
|
|
x.GenerateChatCompletionWithCompressionAsync(
|
|
It.IsAny<List<ChatBot.Models.Dto.ChatMessage>>(),
|
|
It.IsAny<CancellationToken>()
|
|
),
|
|
Times.Once
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClearHistoryAsync_ShouldClearSessionMessages()
|
|
{
|
|
// 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.GetAllMessages().Should().BeEmpty();
|
|
_sessionStorageMock.Verify(x => x.SaveSessionAsync(session), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClearHistoryAsync_ShouldHandleNonExistentSession()
|
|
{
|
|
// Arrange
|
|
var chatId = 12345L;
|
|
_sessionStorageMock.Setup(x => x.Get(chatId)).Returns((ChatBot.Models.ChatSession?)null);
|
|
|
|
// Act
|
|
await _chatService.ClearHistoryAsync(chatId);
|
|
|
|
// Assert
|
|
_sessionStorageMock.Verify(
|
|
x => x.SaveSessionAsync(It.IsAny<ChatBot.Models.ChatSession>()),
|
|
Times.Never
|
|
);
|
|
}
|
|
}
|