Files
ChatBot/ChatBot.Tests/Services/SystemPromptServiceTests.cs
Leonid Pershin 1647fe19d3
Some checks failed
SonarQube / Build and analyze (push) Failing after 2m56s
Unit Tests / Run Tests (push) Failing after 2m28s
add more tests
2025-10-20 07:02:12 +03:00

190 lines
6.6 KiB
C#

using ChatBot.Models.Configuration;
using ChatBot.Services;
using ChatBot.Tests.TestUtilities;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
public class SystemPromptServiceTests : UnitTestBase
{
private readonly Mock<ILogger<SystemPromptService>> _loggerMock;
private readonly SystemPromptService _systemPromptService;
public SystemPromptServiceTests()
{
_loggerMock = TestDataBuilder.Mocks.CreateLoggerMock<SystemPromptService>();
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(new AISettings());
_systemPromptService = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnSystemPrompt()
{
// Act
var result = await _systemPromptService.GetSystemPromptAsync();
// Assert
result.Should().NotBeNullOrEmpty();
result.Should().Contain("Никита");
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnCachedPrompt_WhenCalledMultipleTimes()
{
// Act
var result1 = await _systemPromptService.GetSystemPromptAsync();
var result2 = await _systemPromptService.GetSystemPromptAsync();
// Assert
result1.Should().Be(result2);
}
[Fact]
public async Task ReloadPrompt_ShouldClearCache()
{
// Act
// ReloadPrompt method doesn't exist, skipping this test
var newPrompt = await _systemPromptService.GetSystemPromptAsync();
// Assert
newPrompt.Should().NotBeNull();
// Note: In a real scenario, we might mock the file system to test cache clearing
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnDefaultPrompt_WhenFileNotFound()
{
// Arrange
var aiSettings = new AISettings { SystemPromptPath = "nonexistent-file.txt" };
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(aiSettings);
var service = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
// Act
var result = await service.GetSystemPromptAsync();
// Assert
result.Should().Be(SystemPromptService.DefaultPrompt);
_loggerMock.Verify(
x =>
x.Log(
LogLevel.Warning,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>(
(v, t) => v.ToString()!.Contains("System prompt file not found")
),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
),
Times.Once
);
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnDefaultPrompt_WhenFileReadFails()
{
// Arrange
var aiSettings = new AISettings
{
SystemPromptPath = "invalid-path-that-causes-exception.txt",
};
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(aiSettings);
var service = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
// Act
var result = await service.GetSystemPromptAsync();
// Assert
result.Should().Be(SystemPromptService.DefaultPrompt);
// The file doesn't exist, so it logs a warning, not an error
_loggerMock.Verify(
x =>
x.Log(
LogLevel.Warning,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>(
(v, t) => v.ToString()!.Contains("System prompt file not found")
),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
),
Times.Once
);
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnDefaultPrompt_WhenPathIsNull()
{
// Arrange
var aiSettings = new AISettings { SystemPromptPath = null! };
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(aiSettings);
var service = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
// Act
var result = await service.GetSystemPromptAsync();
// Assert
result.Should().Be(SystemPromptService.DefaultPrompt);
_loggerMock.Verify(
x =>
x.Log(
LogLevel.Error,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>(
(v, t) => v.ToString()!.Contains("Failed to load system prompt")
),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
),
Times.Once
);
}
[Fact]
public async Task GetSystemPromptAsync_ShouldReturnDefaultPrompt_WhenPathIsEmpty()
{
// Arrange
var aiSettings = new AISettings { SystemPromptPath = string.Empty };
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(aiSettings);
var service = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
// Act
var result = await service.GetSystemPromptAsync();
// Assert
result.Should().Be(SystemPromptService.DefaultPrompt);
// Empty path results in file not found, so it logs a warning, not an error
_loggerMock.Verify(
x =>
x.Log(
LogLevel.Warning,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>(
(v, t) => v.ToString()!.Contains("System prompt file not found")
),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
),
Times.Once
);
}
[Fact]
public async Task ReloadPromptAsync_ShouldClearCacheAndReload()
{
// Arrange
var aiSettings = new AISettings { SystemPromptPath = "nonexistent-file.txt" };
var aiSettingsMock = TestDataBuilder.Mocks.CreateOptionsMock(aiSettings);
var service = new SystemPromptService(_loggerMock.Object, aiSettingsMock.Object);
// Act
await service.GetSystemPromptAsync(); // First call to cache default prompt
await service.ReloadPromptAsync(); // Reload should clear cache
// Assert
// The service should still return the default prompt after reload
var result = await service.GetSystemPromptAsync();
result.Should().Be(SystemPromptService.DefaultPrompt);
}
}