205 lines
5.4 KiB
C#
Executable File
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"));
|
|
}
|
|
}
|
|
} |