MarketAlly.AIPlugin.Extensions/MarketAlly.AIPlugin.Tests/Validation/ParameterValidatorTests.cs

205 lines
5.4 KiB
C#
Executable File

using Microsoft.VisualStudio.TestTools.UnitTesting;
using MarketAlly.AIPlugin.Validation;
using MarketAlly.AIPlugin.Security;
using MarketAlly.AIPlugin.Plugins;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace MarketAlly.AIPlugin.Tests.Validation
{
[TestClass]
public class ParameterValidatorTests
{
private SecurityConfiguration _testConfig;
private TestPlugin _testPlugin;
private string _testDirectory;
[TestInitialize]
public void Setup()
{
_testDirectory = Path.Combine(Path.GetTempPath(), "AIPlugin_Tests", Guid.NewGuid().ToString());
Directory.CreateDirectory(_testDirectory);
_testConfig = new SecurityConfiguration
{
AllowedDirectories = new List<string> { _testDirectory },
AllowedFileExtensions = new List<string> { ".txt", ".json" },
MaxFileSizeBytes = 1024 * 1024
};
_testPlugin = new TestPlugin();
}
[TestCleanup]
public void Cleanup()
{
if (Directory.Exists(_testDirectory))
{
Directory.Delete(_testDirectory, true);
}
}
[TestMethod]
public void ValidateParameters_ValidParameters_ReturnsValid()
{
// Arrange
var parameters = new Dictionary<string, object>
{
["requiredParam"] = "test value",
["optionalParam"] = 42
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsTrue(result.IsValid);
Assert.AreEqual(0, result.Errors.Count);
}
[TestMethod]
public void ValidateParameters_MissingRequiredParameter_ReturnsInvalid()
{
// Arrange
var parameters = new Dictionary<string, object>
{
["optionalParam"] = 42
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.AreEqual(1, result.Errors.Count);
Assert.AreEqual("MISSING_REQUIRED_PARAMETER", result.Errors[0].ErrorCode);
}
[TestMethod]
public void ValidateParameters_UnsupportedParameter_ReturnsInvalid()
{
// Arrange
var parameters = new Dictionary<string, object>
{
["requiredParam"] = "test value",
["unsupportedParam"] = "value"
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.IsTrue(result.Errors.Any(e => e.ErrorCode == "UNSUPPORTED_PARAMETER"));
}
[TestMethod]
public void ValidateParameters_InvalidType_ReturnsInvalid()
{
// Arrange
var parameters = new Dictionary<string, object>
{
["requiredParam"] = "test value",
["optionalParam"] = "not a number" // Should be int
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.IsTrue(result.Errors.Any(e => e.ErrorCode == "INVALID_PARAMETER_TYPE"));
}
[TestMethod]
public void ValidateParameters_NullPlugin_ReturnsInvalid()
{
// Arrange
var parameters = new Dictionary<string, object>();
// Act
var result = ParameterValidator.ValidateParameters(null, parameters, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.AreEqual("NULL_PLUGIN", result.Errors[0].ErrorCode);
}
[TestMethod]
public void ValidateParameters_NullParameters_ReturnsInvalid()
{
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, null, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.AreEqual("NULL_PARAMETERS", result.Errors[0].ErrorCode);
}
[TestMethod]
public void ValidateParameters_UnsafeCharacters_AddsWarning()
{
// Arrange
var parameters = new Dictionary<string, object>
{
["requiredParam"] = "test\x00value", // Contains null character
["optionalParam"] = 42
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsTrue(result.IsValid); // Still valid, but has warnings
Assert.IsTrue(result.Warnings.Any(w => w.WarningCode == "UNSAFE_CHARACTERS"));
}
[TestMethod]
public void ValidateParameters_TooLongString_ReturnsInvalid()
{
// Arrange
var longString = new string('A', 100001); // Exceeds 100KB limit
var parameters = new Dictionary<string, object>
{
["requiredParam"] = longString,
["optionalParam"] = 42
};
// Act
var result = ParameterValidator.ValidateParameters(_testPlugin, parameters, _testConfig);
// Assert
Assert.IsFalse(result.IsValid);
Assert.IsTrue(result.Errors.Any(e => e.ErrorCode == "PARAMETER_TOO_LONG"));
}
}
// Test plugin for validation tests
[AIPlugin("TestPlugin", "A plugin for testing parameter validation")]
public class TestPlugin : IAIPlugin
{
[AIParameter("A required parameter", required: true)]
public string RequiredParam { get; set; }
[AIParameter("An optional parameter", required: false)]
public int OptionalParam { get; set; }
[AIParameter("A file path parameter", required: false)]
public string FilePath { get; set; }
public IReadOnlyDictionary<string, Type> SupportedParameters => new Dictionary<string, Type>
{
["requiredParam"] = typeof(string),
["optionalParam"] = typeof(int),
["filePath"] = typeof(string)
};
public Task<AIPluginResult> ExecuteAsync(IReadOnlyDictionary<string, object> parameters)
{
return Task.FromResult(new AIPluginResult("Test execution"));
}
}
}