using ChatBot.Tests.TestUtilities; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Moq; namespace ChatBot.Tests.Integration; public class ProgramIntegrationTests : TestBase { protected override void ConfigureServices(IServiceCollection services) { // Add configuration var configuration = new ConfigurationBuilder() .AddInMemoryCollection( new Dictionary { ["TelegramBot:BotToken"] = "test_token", ["Ollama:Url"] = "http://localhost:11434", ["Ollama:DefaultModel"] = "llama2", ["AI:MaxTokens"] = "1000", ["AI:Temperature"] = "0.7", ["Database:ConnectionString"] = "Host=localhost;Port=5432;Database=test_chatbot;Username=postgres;Password=postgres", ["Database:CommandTimeout"] = "30", ["Database:EnableSensitiveDataLogging"] = "false", } ) .Build(); services.AddSingleton(configuration); services.AddLogging(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Debug)); } [Fact] public void Program_ShouldHaveRequiredUsingStatements() { // This test verifies that Program.cs has the necessary using statements // by checking if the types can be resolved var services = new ServiceCollection(); ConfigureServices(services); var serviceProvider = services.BuildServiceProvider(); // Verify that key services can be resolved Assert.NotNull(serviceProvider.GetService()); Assert.NotNull(serviceProvider.GetService()); } [Fact] public void Program_ShouldConfigureTelegramBotSettings() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); // Assert var botToken = serviceProvider.GetRequiredService()["TelegramBot:BotToken"]; Assert.Equal("test_token", botToken); } [Fact] public void Program_ShouldConfigureOllamaSettings() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert var ollamaUrl = configuration["Ollama:Url"]; var defaultModel = configuration["Ollama:DefaultModel"]; Assert.Equal("http://localhost:11434", ollamaUrl); Assert.Equal("llama2", defaultModel); } [Fact] public void Program_ShouldConfigureAISettings() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert var maxTokens = configuration["AI:MaxTokens"]; var temperature = configuration["AI:Temperature"]; Assert.Equal("1000", maxTokens); Assert.Equal("0.7", temperature); } [Fact] public void Program_ShouldConfigureDatabaseSettings() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert var connectionString = configuration["Database:ConnectionString"]; var commandTimeout = configuration["Database:CommandTimeout"]; Assert.Equal( "Host=localhost;Port=5432;Database=test_chatbot;Username=postgres;Password=postgres", connectionString ); Assert.Equal("30", commandTimeout); Assert.Equal("false", configuration["Database:EnableSensitiveDataLogging"]); } [Fact] public void Program_ShouldHandleEnvironmentVariables() { // Arrange Environment.SetEnvironmentVariable("TELEGRAM_BOT_TOKEN", "env_token"); Environment.SetEnvironmentVariable("OLLAMA_URL", "http://env:11434"); Environment.SetEnvironmentVariable("OLLAMA_DEFAULT_MODEL", "env_model"); Environment.SetEnvironmentVariable("DB_HOST", "env_host"); Environment.SetEnvironmentVariable("DB_PORT", "8080"); Environment.SetEnvironmentVariable("DB_NAME", "env_db"); Environment.SetEnvironmentVariable("DB_USER", "env_user"); Environment.SetEnvironmentVariable("DB_PASSWORD", "env_pass"); try { // Act var services = new ServiceCollection(); ConfigureServices(services); // Assert Assert.Equal("env_token", Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN")); Assert.Equal("http://env:11434", Environment.GetEnvironmentVariable("OLLAMA_URL")); Assert.Equal("env_model", Environment.GetEnvironmentVariable("OLLAMA_DEFAULT_MODEL")); Assert.Equal("env_host", Environment.GetEnvironmentVariable("DB_HOST")); Assert.Equal("8080", Environment.GetEnvironmentVariable("DB_PORT")); Assert.Equal("env_db", Environment.GetEnvironmentVariable("DB_NAME")); Assert.Equal("env_user", Environment.GetEnvironmentVariable("DB_USER")); Assert.Equal("env_pass", Environment.GetEnvironmentVariable("DB_PASSWORD")); } finally { // 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 Program_ShouldHaveValidConfigurationStructure() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert - Check that all required configuration sections exist Assert.NotNull(configuration.GetSection("TelegramBot")); Assert.NotNull(configuration.GetSection("Ollama")); Assert.NotNull(configuration.GetSection("AI")); Assert.NotNull(configuration.GetSection("Database")); } [Fact] public void Program_ShouldHaveRequiredConfigurationValues() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert - Check that all required configuration values are present Assert.NotNull(configuration["TelegramBot:BotToken"]); Assert.NotNull(configuration["Ollama:Url"]); Assert.NotNull(configuration["Ollama:DefaultModel"]); Assert.NotNull(configuration["AI:MaxTokens"]); Assert.NotNull(configuration["AI:Temperature"]); Assert.NotNull(configuration["Database:ConnectionString"]); Assert.NotNull(configuration["Database:CommandTimeout"]); Assert.NotNull(configuration["Database:EnableSensitiveDataLogging"]); } [Fact] public void Program_ShouldHaveValidNumericConfigurationValues() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert - Check that numeric values can be parsed var maxTokensValue = configuration["AI:MaxTokens"]; Assert.NotNull(maxTokensValue); Assert.True(int.TryParse(maxTokensValue, out var maxTokens)); Assert.True(maxTokens > 0); var temperatureValue = configuration["AI:Temperature"]; Assert.NotNull(temperatureValue); Assert.True( double.TryParse( temperatureValue, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out var temperature ) ); Assert.True(temperature >= 0 && temperature <= 2); Assert.True(int.TryParse(configuration["Database:CommandTimeout"], out var commandTimeout)); Assert.True(commandTimeout > 0); Assert.True(bool.TryParse(configuration["Database:EnableSensitiveDataLogging"], out _)); } [Fact] public void Program_ShouldHaveValidUrlConfigurationValues() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert - Check that URL values are valid var ollamaUrl = configuration["Ollama:Url"]; Assert.NotNull(ollamaUrl); Assert.True(Uri.TryCreate(ollamaUrl, UriKind.Absolute, out var uri)); Assert.True(uri.Scheme == "http" || uri.Scheme == "https"); } [Fact] public void Program_ShouldHaveValidDatabaseConnectionString() { // Arrange var services = new ServiceCollection(); ConfigureServices(services); // Act var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService(); // Assert - Check that connection string has required components var connectionString = configuration["Database:ConnectionString"]; Assert.NotNull(connectionString); Assert.Contains("Host=", connectionString); Assert.Contains("Port=", connectionString); Assert.Contains("Database=", connectionString); Assert.Contains("Username=", connectionString); Assert.Contains("Password=", connectionString); } }