431 lines
15 KiB
C#
Executable File
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;
|
|
}
|
|
}
|
|
} |