MarketAlly.AIPlugin.Extensions/MarketAlly.AIPlugin.Learnin.../Configuration/ConfigurationTests.cs

431 lines
15 KiB
C#
Executable File

using MarketAlly.AIPlugin.Learning.Configuration;
using System.ComponentModel.DataAnnotations;
namespace MarketAlly.AIPlugin.Learning.Tests.Configuration
{
[TestClass]
public class ConfigurationTests
{
[TestMethod]
public void LearningConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new LearningConfiguration();
// Assert
Assert.IsNotNull(config.Git);
Assert.IsNotNull(config.Security);
Assert.IsNotNull(config.Performance);
Assert.IsNotNull(config.Logging);
Assert.IsNotNull(config.AI);
Assert.IsNotNull(config.LearningModes);
}
[TestMethod]
public void GitConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new GitConfiguration();
// Assert
Assert.AreEqual("ai-refactoring", config.BranchPrefix);
Assert.AreEqual("AI Learning System", config.CommitterName);
Assert.AreEqual("ai@learning.system", config.CommitterEmail);
Assert.IsFalse(config.AutoMerge);
Assert.IsTrue(config.RequireCleanWorkingDirectory);
Assert.AreEqual(30, config.MaxBranchRetentionDays);
}
[TestMethod]
public void GitConfiguration_ValidEmail_PassesValidation()
{
// Arrange
var config = new GitConfiguration
{
BranchPrefix = "test-branch",
CommitterName = "Test User",
CommitterEmail = "test@example.com",
AutoMerge = false,
RequireCleanWorkingDirectory = true,
MaxBranchRetentionDays = 15
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.AreEqual(0, validationResults.Count);
}
[TestMethod]
public void GitConfiguration_InvalidEmail_FailsValidation()
{
// Arrange
var config = new GitConfiguration
{
BranchPrefix = "test-branch",
CommitterName = "Test User",
CommitterEmail = "invalid-email-format",
AutoMerge = false,
RequireCleanWorkingDirectory = true,
MaxBranchRetentionDays = 15
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
// Check for any email-related validation error (the exact message varies by framework version)
var hasEmailError = validationResults.Any(r =>
r.ErrorMessage?.ToLower().Contains("email") == true ||
r.ErrorMessage?.Contains("EmailAddress") == true ||
r.MemberNames?.Contains("CommitterEmail") == true);
Assert.IsTrue(hasEmailError, $"Expected email validation error. Actual errors: {string.Join(", ", validationResults.Select(r => r.ErrorMessage))}");
}
[TestMethod]
public void GitConfiguration_MaxDepthOutOfRange_FailsValidation()
{
// Arrange
var config = new GitConfiguration
{
BranchPrefix = "test-branch",
CommitterName = "Test User",
CommitterEmail = "test@example.com",
MaxBranchRetentionDays = 150 // Out of range (1-90)
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
Assert.IsTrue(validationResults.Any(r => r.ErrorMessage?.Contains("range") == true || r.ErrorMessage?.Contains("1") == true));
}
[TestMethod]
public void SecurityConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new SecurityConfiguration();
// Assert
Assert.IsNotNull(config.ForbiddenDirectories);
Assert.IsTrue(config.ForbiddenDirectories.Contains("bin"));
Assert.IsTrue(config.ForbiddenDirectories.Contains("obj"));
Assert.IsNotNull(config.AllowedFileExtensions);
Assert.IsTrue(config.AllowedFileExtensions.Contains(".cs"));
Assert.AreEqual(10 * 1024 * 1024, config.MaxFileSizeBytes);
Assert.AreEqual(1000, config.MaxFilesPerSession);
Assert.IsTrue(config.EnablePathValidation);
Assert.IsTrue(config.EnableInputSanitization);
}
[TestMethod]
public void SecurityConfiguration_ValidConfiguration_PassesValidation()
{
// Arrange
var config = new SecurityConfiguration
{
ForbiddenDirectories = new string[] { "bin", "obj", ".git" },
AllowedFileExtensions = new string[] { ".cs", ".csproj", ".sln" },
MaxFileSizeBytes = 5 * 1024 * 1024, // 5MB
MaxFilesPerSession = 500,
EnablePathValidation = true,
EnableInputSanitization = true
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.AreEqual(0, validationResults.Count);
}
[TestMethod]
public void SecurityConfiguration_InvalidMaxFileSize_FailsValidation()
{
// Arrange
var config = new SecurityConfiguration
{
MaxFileSizeBytes = 500 // Too small, minimum is 1024
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
Assert.IsTrue(validationResults.Any(r => r.ErrorMessage?.Contains("range") == true || r.ErrorMessage?.Contains("1024") == true));
}
[TestMethod]
public void SecurityConfiguration_InvalidMaxPathLength_FailsValidation()
{
// Arrange
var config = new SecurityConfiguration
{
MaxFilesPerSession = 0 // Invalid, must be positive (1-10000)
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
Assert.IsTrue(validationResults.Any(r => r.ErrorMessage?.Contains("range") == true || r.ErrorMessage?.Contains("1") == true));
}
[TestMethod]
public void AIConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new AIConfiguration();
// Assert
Assert.IsTrue(config.EnableSemanticSearch);
Assert.AreEqual(10, config.MaxSearchResults);
Assert.AreEqual(0.7, config.MinSimilarityScore, 0.001);
Assert.AreEqual(8000, config.MaxContextTokens);
Assert.IsTrue(config.EnableContextPreparation);
Assert.IsTrue(config.EnableDependencyTracking);
Assert.IsTrue(config.EnableChangeImpactAnalysis);
}
[TestMethod]
public void AIConfiguration_ValidConfiguration_PassesValidation()
{
// Arrange
var config = new AIConfiguration
{
EnableSemanticSearch = true,
MaxSearchResults = 20,
MinSimilarityScore = 0.8,
MaxContextTokens = 16000,
EnableContextPreparation = false,
MaxContextDepth = 5
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.AreEqual(0, validationResults.Count);
}
[TestMethod]
public void AIConfiguration_InvalidMaxSearchResults_FailsValidation()
{
// Arrange
var config = new AIConfiguration
{
MaxSearchResults = 150 // Out of range [1, 100]
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
}
[TestMethod]
public void AIConfiguration_InvalidMinSimilarityScore_FailsValidation()
{
// Arrange
var config = new AIConfiguration
{
MinSimilarityScore = 1.5 // Out of range [0.0, 1.0]
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
}
[TestMethod]
public void LearningModeConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new LearningModeConfiguration();
// Assert
Assert.IsNotNull(config.Conservative);
Assert.IsNotNull(config.Moderate);
Assert.IsNotNull(config.Aggressive);
// Conservative mode should be most restrictive
Assert.AreEqual(10, config.Conservative.MaxIterations);
Assert.AreEqual(2, config.Conservative.MaxAttemptsPerFile);
Assert.AreEqual(30, config.Conservative.TimeoutMinutes);
Assert.AreEqual(0.1, config.Conservative.RiskThreshold, 0.001);
// Moderate mode should be balanced
Assert.AreEqual(20, config.Moderate.MaxIterations);
Assert.AreEqual(3, config.Moderate.MaxAttemptsPerFile);
Assert.AreEqual(60, config.Moderate.TimeoutMinutes);
Assert.AreEqual(0.3, config.Moderate.RiskThreshold, 0.001);
// Aggressive mode should be most permissive
Assert.AreEqual(50, config.Aggressive.MaxIterations);
Assert.AreEqual(5, config.Aggressive.MaxAttemptsPerFile);
Assert.AreEqual(120, config.Aggressive.TimeoutMinutes);
Assert.AreEqual(0.5, config.Aggressive.RiskThreshold, 0.001);
}
[TestMethod]
public void LearningModeSettings_ValidConfiguration_PassesValidation()
{
// Arrange
var config = new LearningModeSettings
{
Name = "Test",
MaxIterations = 15,
MaxAttemptsPerFile = 4,
TimeoutMinutes = 10,
AllowedApproaches = new string[] { "RenameVariable", "AddDocumentation" },
RiskThreshold = 0.2
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.AreEqual(0, validationResults.Count);
}
[TestMethod]
public void LearningModeSettings_InvalidMaxIterations_FailsValidation()
{
// Arrange
var config = new LearningModeSettings
{
Name = "Test",
MaxIterations = 1500, // Out of range [1, 1000]
AllowedApproaches = new string[] { "RenameVariable" }
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
}
[TestMethod]
public void LearningModeSettings_InvalidMaxAttemptsPerFile_FailsValidation()
{
// Arrange
var config = new LearningModeSettings
{
Name = "Test",
MaxAttemptsPerFile = 15, // Out of range [1, 10]
AllowedApproaches = new string[] { "RenameVariable" }
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
}
[TestMethod]
public void LearningModeSettings_InvalidIterationTimeout_FailsValidation()
{
// Arrange
var config = new LearningModeSettings
{
Name = "Test",
TimeoutMinutes = 600, // Out of range [1, 480]
AllowedApproaches = new string[] { "RenameVariable" }
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
}
[TestMethod]
public void PerformanceConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new PerformanceConfiguration();
// Assert
Assert.AreEqual(Environment.ProcessorCount, config.MaxConcurrentOperations);
Assert.AreEqual(10, config.BatchSize);
Assert.IsTrue(config.EnableCaching);
Assert.AreEqual(60, config.CacheExpirationMinutes);
Assert.AreEqual(3, config.RetryAttempts);
}
[TestMethod]
public void LoggingConfiguration_DefaultValues_AreValid()
{
// Arrange & Act
var config = new LoggingConfiguration();
// Assert
Assert.IsTrue(config.EnableStructuredLogging);
Assert.IsTrue(config.EnableCorrelationIds);
Assert.AreEqual("Information", config.LogLevel);
Assert.IsTrue(config.LogToFile);
Assert.AreEqual("Logs", config.LogDirectory);
}
[TestMethod]
public void CompleteConfiguration_AllDefaults_PassesValidation()
{
// Arrange
var config = new LearningConfiguration();
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.AreEqual(0, validationResults.Count);
}
[TestMethod]
public void CompleteConfiguration_MissingRequiredProperties_FailsValidation()
{
// Arrange
var config = new LearningConfiguration
{
Git = null!, // Required property set to null
Security = new SecurityConfiguration(),
Performance = new PerformanceConfiguration(),
AI = new AIConfiguration(),
LearningModes = new LearningModeConfiguration()
};
// Act
var validationResults = ValidateObject(config);
// Assert
Assert.IsTrue(validationResults.Count > 0);
Assert.IsTrue(validationResults.Any(r => r.ErrorMessage?.Contains("required") == true || r.ErrorMessage?.Contains("Required") == true));
}
[TestMethod]
public void ConfigurationSectionName_IsCorrect()
{
// Act & Assert
Assert.AreEqual("Learning", LearningConfiguration.SectionName);
}
private static List<ValidationResult> ValidateObject(object obj)
{
var validationResults = new List<ValidationResult>();
var validationContext = new ValidationContext(obj);
Validator.TryValidateObject(obj, validationContext, validationResults, true);
return validationResults;
}
}
}