using MarketAlly.AIPlugin; using MarketAlly.AIPlugin.Analysis.Infrastructure; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; namespace MarketAlly.AIPlugin.Analysis.Tests.Infrastructure { [TestClass] public class PluginDiscoveryServiceTests { private PluginDiscoveryService _service = null!; private ILogger? _logger; [TestInitialize] public void Setup() { _logger = null; // In real tests, you might use a mock logger _service = new PluginDiscoveryService(_logger); } [TestMethod] public async Task DiscoverPluginsAsync_NonExistentDirectory_ShouldReturnEmptyList() { // Arrange var nonExistentDirectory = "/non/existent/directory"; // Act var plugins = await _service.DiscoverPluginsAsync(nonExistentDirectory); // Assert Assert.IsNotNull(plugins); Assert.AreEqual(0, plugins.Count()); } [TestMethod] public void GetBuiltInPlugins_ShouldReturnAllBuiltInPlugins() { // Act var plugins = _service.GetBuiltInPlugins(); // Assert Assert.IsNotNull(plugins); var pluginList = plugins.ToList(); Assert.IsTrue(pluginList.Count >= 6); // We expect at least 6 built-in plugins // Verify we have the main analysis plugins var pluginNames = pluginList.Select(p => p.GetType().Name).ToList(); Assert.IsTrue(pluginNames.Contains("PerformanceAnalyzerPlugin")); Assert.IsTrue(pluginNames.Contains("ArchitectureValidatorPlugin")); Assert.IsTrue(pluginNames.Contains("TechnicalDebtPlugin")); Assert.IsTrue(pluginNames.Contains("ComplexityAnalyzerPlugin")); Assert.IsTrue(pluginNames.Contains("TestAnalysisPlugin")); Assert.IsTrue(pluginNames.Contains("BehaviorAnalysisPlugin")); Assert.IsTrue(pluginNames.Contains("SQLiteSchemaReaderPlugin")); } [TestMethod] public void ValidatePlugin_NullPlugin_ShouldReturnFalse() { // Act var isValid = _service.ValidatePlugin(null!); // Assert Assert.IsFalse(isValid); } [TestMethod] public void ValidatePlugin_ValidBuiltInPlugin_ShouldReturnTrue() { // Arrange var plugins = _service.GetBuiltInPlugins(); var plugin = plugins.First(); // Act var isValid = _service.ValidatePlugin(plugin); // Assert Assert.IsTrue(isValid); } [TestMethod] public void ValidatePlugin_PluginWithNullSupportedParameters_ShouldReturnFalse() { // Arrange var mockPlugin = new MockPluginWithNullParameters(); // Act var isValid = _service.ValidatePlugin(mockPlugin); // Assert Assert.IsFalse(isValid); } [TestMethod] public async Task LoadPluginAsync_NonExistentAssembly_ShouldThrowFileNotFoundException() { // Arrange var nonExistentPath = "/non/existent/assembly.dll"; var typeName = "SomeType"; // Act & Assert await Assert.ThrowsExceptionAsync(async () => { await _service.LoadPluginAsync(nonExistentPath, typeName); }); } [TestMethod] public void Constructor_WithNullLogger_ShouldNotThrow() { // Act & Assert - Should not throw var service = new PluginDiscoveryService(null); Assert.IsNotNull(service); } [TestMethod] public void Constructor_WithLogger_ShouldNotThrow() { // Act & Assert - Should not throw var service = new PluginDiscoveryService(_logger); Assert.IsNotNull(service); } [TestMethod] public async Task DiscoverPluginsAsync_EmptyDirectory_ShouldReturnEmptyList() { // Arrange var tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(tempDirectory); try { // Act var plugins = await _service.DiscoverPluginsAsync(tempDirectory); // Assert Assert.IsNotNull(plugins); Assert.AreEqual(0, plugins.Count()); } finally { // Cleanup if (Directory.Exists(tempDirectory)) { Directory.Delete(tempDirectory, true); } } } } // Test helper classes internal class MockPluginWithNullParameters : IAIPlugin { public IReadOnlyDictionary SupportedParameters => null!; public Task ExecuteAsync(IReadOnlyDictionary parameters) { return Task.FromResult(new AIPluginResult("test", "test")); } } internal class MockValidPlugin : IAIPlugin { public IReadOnlyDictionary SupportedParameters => new Dictionary { ["testParam"] = typeof(string) }; public Task ExecuteAsync(IReadOnlyDictionary parameters) { return Task.FromResult(new AIPluginResult("test", "test")); } } }