366 lines
16 KiB
C#
366 lines
16 KiB
C#
using ChatBot.Data;
|
|
using ChatBot.Models.Configuration;
|
|
using FluentAssertions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace ChatBot.Tests.Program;
|
|
|
|
public class ProgramConfigurationTests
|
|
{
|
|
[Fact]
|
|
public void Configuration_ShouldHaveValidSettings()
|
|
{
|
|
// Arrange
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{ "TelegramBot:BotToken", "1234567890123456789012345678901234567890" },
|
|
{ "Ollama:Url", "http://localhost:11434" },
|
|
{ "Ollama:DefaultModel", "llama3" },
|
|
{ "AI:CompressionThreshold", "100" },
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=localhost;Port=5432;Database=test;Username=test;Password=test"
|
|
},
|
|
{ "Database:CommandTimeout", "30" },
|
|
{ "Database:EnableSensitiveDataLogging", "false" },
|
|
}
|
|
)
|
|
.Build();
|
|
|
|
// Act
|
|
var telegramSettings = configuration.GetSection("TelegramBot").Get<TelegramBotSettings>();
|
|
var ollamaSettings = configuration.GetSection("Ollama").Get<OllamaSettings>();
|
|
var aiSettings = configuration.GetSection("AI").Get<AISettings>();
|
|
var databaseSettings = configuration.GetSection("Database").Get<DatabaseSettings>();
|
|
|
|
// Assert
|
|
telegramSettings.Should().NotBeNull();
|
|
telegramSettings!.BotToken.Should().Be("1234567890123456789012345678901234567890");
|
|
|
|
ollamaSettings.Should().NotBeNull();
|
|
ollamaSettings!.Url.Should().Be("http://localhost:11434");
|
|
ollamaSettings.DefaultModel.Should().Be("llama3");
|
|
|
|
aiSettings.Should().NotBeNull();
|
|
aiSettings!.CompressionThreshold.Should().Be(100);
|
|
|
|
databaseSettings.Should().NotBeNull();
|
|
databaseSettings!
|
|
.ConnectionString.Should()
|
|
.Be("Host=localhost;Port=5432;Database=test;Username=test;Password=test");
|
|
databaseSettings.CommandTimeout.Should().Be(30);
|
|
databaseSettings.EnableSensitiveDataLogging.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void EnvironmentVariableOverrides_ShouldWorkCorrectly()
|
|
{
|
|
// Arrange
|
|
Environment.SetEnvironmentVariable(
|
|
"TELEGRAM_BOT_TOKEN",
|
|
"env-token-1234567890123456789012345678901234567890"
|
|
);
|
|
Environment.SetEnvironmentVariable("OLLAMA_URL", "http://env-ollama:11434");
|
|
Environment.SetEnvironmentVariable("OLLAMA_DEFAULT_MODEL", "env-model");
|
|
Environment.SetEnvironmentVariable("DB_HOST", "env-host");
|
|
Environment.SetEnvironmentVariable("DB_PORT", "5433");
|
|
Environment.SetEnvironmentVariable("DB_NAME", "env-db");
|
|
Environment.SetEnvironmentVariable("DB_USER", "env-user");
|
|
Environment.SetEnvironmentVariable("DB_PASSWORD", "env-password");
|
|
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{
|
|
"TelegramBot:BotToken",
|
|
"config-token-1234567890123456789012345678901234567890"
|
|
},
|
|
{ "Ollama:Url", "http://config-ollama:11434" },
|
|
{ "Ollama:DefaultModel", "config-model" },
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=config-host;Port=5432;Database=config-db;Username=config-user;Password=config-password"
|
|
},
|
|
}
|
|
)
|
|
.AddEnvironmentVariables()
|
|
.Build();
|
|
|
|
// Act - Simulate the environment variable override logic from Program.cs
|
|
var telegramSettings = new TelegramBotSettings();
|
|
configuration.GetSection("TelegramBot").Bind(telegramSettings);
|
|
telegramSettings.BotToken =
|
|
Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN") ?? telegramSettings.BotToken;
|
|
|
|
var ollamaSettings = new OllamaSettings();
|
|
configuration.GetSection("Ollama").Bind(ollamaSettings);
|
|
ollamaSettings.Url = Environment.GetEnvironmentVariable("OLLAMA_URL") ?? ollamaSettings.Url;
|
|
ollamaSettings.DefaultModel =
|
|
Environment.GetEnvironmentVariable("OLLAMA_DEFAULT_MODEL")
|
|
?? ollamaSettings.DefaultModel;
|
|
|
|
var databaseSettings = new DatabaseSettings();
|
|
configuration.GetSection("Database").Bind(databaseSettings);
|
|
var host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
|
|
var port = Environment.GetEnvironmentVariable("DB_PORT") ?? "5432";
|
|
var name = Environment.GetEnvironmentVariable("DB_NAME") ?? "chatbot";
|
|
var user = Environment.GetEnvironmentVariable("DB_USER") ?? "postgres";
|
|
var password = Environment.GetEnvironmentVariable("DB_PASSWORD") ?? "postgres";
|
|
databaseSettings.ConnectionString =
|
|
$"Host={host};Port={port};Database={name};Username={user};Password={password}";
|
|
|
|
// Assert
|
|
telegramSettings
|
|
.BotToken.Should()
|
|
.Be("env-token-1234567890123456789012345678901234567890");
|
|
ollamaSettings.Url.Should().Be("http://env-ollama:11434");
|
|
ollamaSettings.DefaultModel.Should().Be("env-model");
|
|
databaseSettings
|
|
.ConnectionString.Should()
|
|
.Be("Host=env-host;Port=5433;Database=env-db;Username=env-user;Password=env-password");
|
|
|
|
// Cleanup
|
|
Environment.SetEnvironmentVariable("TELEGRAM_BOT_TOKEN", null);
|
|
Environment.SetEnvironmentVariable("OLLAMA_URL", null);
|
|
Environment.SetEnvironmentVariable("OLLAMA_DEFAULT_MODEL", null);
|
|
Environment.SetEnvironmentVariable("DB_HOST", null);
|
|
Environment.SetEnvironmentVariable("DB_PORT", null);
|
|
Environment.SetEnvironmentVariable("DB_NAME", null);
|
|
Environment.SetEnvironmentVariable("DB_USER", null);
|
|
Environment.SetEnvironmentVariable("DB_PASSWORD", null);
|
|
}
|
|
|
|
[Fact]
|
|
public void EnvironmentVariableFallbacks_ShouldUseConfigWhenEnvMissing()
|
|
{
|
|
// Arrange: ensure env vars are not set
|
|
Environment.SetEnvironmentVariable("TELEGRAM_BOT_TOKEN", null);
|
|
Environment.SetEnvironmentVariable("OLLAMA_URL", null);
|
|
Environment.SetEnvironmentVariable("OLLAMA_DEFAULT_MODEL", null);
|
|
Environment.SetEnvironmentVariable("DB_HOST", null);
|
|
Environment.SetEnvironmentVariable("DB_PORT", null);
|
|
Environment.SetEnvironmentVariable("DB_NAME", null);
|
|
Environment.SetEnvironmentVariable("DB_USER", null);
|
|
Environment.SetEnvironmentVariable("DB_PASSWORD", null);
|
|
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{
|
|
"TelegramBot:BotToken",
|
|
"config-token-0000000000000000000000000000000000000000"
|
|
},
|
|
{ "Ollama:Url", "http://config-ollama:11434" },
|
|
{ "Ollama:DefaultModel", "config-model" },
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=config-host;Port=5432;Database=config-db;Username=config-user;Password=config-password"
|
|
},
|
|
}
|
|
)
|
|
.Build();
|
|
|
|
// Act - Simulate Program.cs binding and env override logic
|
|
var telegramSettings = new TelegramBotSettings();
|
|
configuration.GetSection("TelegramBot").Bind(telegramSettings);
|
|
telegramSettings.BotToken =
|
|
Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN") ?? telegramSettings.BotToken;
|
|
|
|
var ollamaSettings = new OllamaSettings();
|
|
configuration.GetSection("Ollama").Bind(ollamaSettings);
|
|
ollamaSettings.Url = Environment.GetEnvironmentVariable("OLLAMA_URL") ?? ollamaSettings.Url;
|
|
ollamaSettings.DefaultModel =
|
|
Environment.GetEnvironmentVariable("OLLAMA_DEFAULT_MODEL")
|
|
?? ollamaSettings.DefaultModel;
|
|
|
|
var databaseSettings = new DatabaseSettings();
|
|
configuration.GetSection("Database").Bind(databaseSettings);
|
|
var host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
|
|
var port = Environment.GetEnvironmentVariable("DB_PORT") ?? "5432";
|
|
var name = Environment.GetEnvironmentVariable("DB_NAME") ?? "chatbot";
|
|
var user = Environment.GetEnvironmentVariable("DB_USER") ?? "postgres";
|
|
var password = Environment.GetEnvironmentVariable("DB_PASSWORD") ?? "postgres";
|
|
var expectedConnectionString =
|
|
$"Host={host};Port={port};Database={name};Username={user};Password={password}";
|
|
databaseSettings.ConnectionString =
|
|
$"Host={host};Port={port};Database={name};Username={user};Password={password}";
|
|
|
|
// Assert - values should remain from configuration when env vars are missing
|
|
telegramSettings
|
|
.BotToken.Should()
|
|
.Be("config-token-0000000000000000000000000000000000000000");
|
|
ollamaSettings.Url.Should().Be("http://config-ollama:11434");
|
|
ollamaSettings.DefaultModel.Should().Be("config-model");
|
|
// Because our fallback block reconstructs from env with defaults when missing,
|
|
// ensure it equals the configuration's original connection string when all envs are missing
|
|
databaseSettings.ConnectionString.Should().Be(expectedConnectionString);
|
|
}
|
|
|
|
[Fact]
|
|
public void DatabaseContext_ShouldBeConfiguredCorrectly()
|
|
{
|
|
// Arrange
|
|
var services = new ServiceCollection();
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=localhost;Port=5432;Database=test;Username=test;Password=test"
|
|
},
|
|
{ "Database:CommandTimeout", "60" },
|
|
{ "Database:EnableSensitiveDataLogging", "true" },
|
|
}
|
|
)
|
|
.Build();
|
|
|
|
services.AddSingleton<IConfiguration>(configuration);
|
|
services.Configure<DatabaseSettings>(configuration.GetSection("Database"));
|
|
|
|
// Act
|
|
services.AddDbContext<ChatBotDbContext>(
|
|
(serviceProvider, options) =>
|
|
{
|
|
var dbSettings = serviceProvider
|
|
.GetRequiredService<IOptions<DatabaseSettings>>()
|
|
.Value;
|
|
options.UseInMemoryDatabase("test-db");
|
|
|
|
if (dbSettings.EnableSensitiveDataLogging)
|
|
{
|
|
options.EnableSensitiveDataLogging();
|
|
}
|
|
}
|
|
);
|
|
|
|
var serviceProvider = services.BuildServiceProvider();
|
|
var context = serviceProvider.GetRequiredService<ChatBotDbContext>();
|
|
|
|
// Assert
|
|
context.Should().NotBeNull();
|
|
context.Database.Should().NotBeNull();
|
|
context.ChatSessions.Should().NotBeNull();
|
|
context.ChatMessages.Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void ServiceRegistration_ShouldWorkWithoutValidation()
|
|
{
|
|
// Arrange
|
|
var services = new ServiceCollection();
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{ "TelegramBot:BotToken", "1234567890123456789012345678901234567890" },
|
|
{ "Ollama:Url", "http://localhost:11434" },
|
|
{ "Ollama:DefaultModel", "llama3" },
|
|
{ "AI:CompressionThreshold", "100" },
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=localhost;Port=5432;Database=test;Username=test;Password=test"
|
|
},
|
|
{ "Database:CommandTimeout", "30" },
|
|
{ "Database:EnableSensitiveDataLogging", "false" },
|
|
}
|
|
)
|
|
.Build();
|
|
|
|
// Act - Register services without validation
|
|
services.AddSingleton<IConfiguration>(configuration);
|
|
services.AddLogging();
|
|
|
|
services.Configure<TelegramBotSettings>(configuration.GetSection("TelegramBot"));
|
|
services.Configure<OllamaSettings>(configuration.GetSection("Ollama"));
|
|
services.Configure<AISettings>(configuration.GetSection("AI"));
|
|
services.Configure<DatabaseSettings>(configuration.GetSection("Database"));
|
|
|
|
services.AddDbContext<ChatBotDbContext>(
|
|
(serviceProvider, options) =>
|
|
{
|
|
options.UseInMemoryDatabase("test-db");
|
|
}
|
|
);
|
|
|
|
var serviceProvider = services.BuildServiceProvider();
|
|
|
|
// Assert - Check that configuration services are registered
|
|
serviceProvider.GetRequiredService<IOptions<TelegramBotSettings>>().Should().NotBeNull();
|
|
serviceProvider.GetRequiredService<IOptions<OllamaSettings>>().Should().NotBeNull();
|
|
serviceProvider.GetRequiredService<IOptions<AISettings>>().Should().NotBeNull();
|
|
serviceProvider.GetRequiredService<IOptions<DatabaseSettings>>().Should().NotBeNull();
|
|
serviceProvider.GetRequiredService<ChatBotDbContext>().Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void ConfigurationSections_ShouldBeAccessible()
|
|
{
|
|
// Arrange
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(
|
|
new Dictionary<string, string?>
|
|
{
|
|
{ "TelegramBot:BotToken", "1234567890123456789012345678901234567890" },
|
|
{ "Ollama:Url", "http://localhost:11434" },
|
|
{ "AI:CompressionThreshold", "100" },
|
|
{
|
|
"Database:ConnectionString",
|
|
"Host=localhost;Port=5432;Database=test;Username=test;Password=test"
|
|
},
|
|
}
|
|
)
|
|
.Build();
|
|
|
|
// Act & Assert
|
|
configuration.GetSection("TelegramBot").Should().NotBeNull();
|
|
configuration.GetSection("Ollama").Should().NotBeNull();
|
|
configuration.GetSection("AI").Should().NotBeNull();
|
|
configuration.GetSection("Database").Should().NotBeNull();
|
|
|
|
configuration
|
|
.GetSection("TelegramBot")["BotToken"]
|
|
.Should()
|
|
.Be("1234567890123456789012345678901234567890");
|
|
configuration.GetSection("Ollama")["Url"].Should().Be("http://localhost:11434");
|
|
configuration.GetSection("AI")["CompressionThreshold"].Should().Be("100");
|
|
configuration
|
|
.GetSection("Database")["ConnectionString"]
|
|
.Should()
|
|
.Be("Host=localhost;Port=5432;Database=test;Username=test;Password=test");
|
|
}
|
|
|
|
[Fact]
|
|
public void DatabaseContext_ShouldHaveCorrectEntityTypes()
|
|
{
|
|
// Arrange
|
|
var services = new ServiceCollection();
|
|
services.AddDbContext<ChatBotDbContext>(options => options.UseInMemoryDatabase("test-db"));
|
|
var serviceProvider = services.BuildServiceProvider();
|
|
var context = serviceProvider.GetRequiredService<ChatBotDbContext>();
|
|
|
|
// Act
|
|
var model = context.Model;
|
|
|
|
// Assert
|
|
var chatSessionEntity = model.FindEntityType(
|
|
typeof(ChatBot.Models.Entities.ChatSessionEntity)
|
|
);
|
|
var chatMessageEntity = model.FindEntityType(
|
|
typeof(ChatBot.Models.Entities.ChatMessageEntity)
|
|
);
|
|
|
|
chatSessionEntity.Should().NotBeNull();
|
|
chatMessageEntity.Should().NotBeNull();
|
|
chatSessionEntity!.GetTableName().Should().Be("chat_sessions");
|
|
chatMessageEntity!.GetTableName().Should().Be("chat_messages");
|
|
}
|
|
}
|