- Renamed all directories: OpenHarbor.MCP.* → Svrnty.MCP.* - Updated all namespaces in 179 C# files - Renamed 20 .csproj files and 3 .sln files - Updated 193 documentation references - Updated 33 references in main CODEX codebase - Updated Codex.sln with new paths - Build verified: 0 errors Preparing for extraction to standalone repositories. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
213 lines
5.8 KiB
C#
213 lines
5.8 KiB
C#
using Xunit;
|
|
using Moq;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using System.Linq;
|
|
|
|
namespace Svrnty.MCP.Core.Tests;
|
|
|
|
/// <summary>
|
|
/// Unit tests for ToolRegistry following TDD approach.
|
|
/// Tests dynamic tool registration and retrieval.
|
|
/// </summary>
|
|
public class ToolRegistryTests
|
|
{
|
|
[Fact]
|
|
public void ToolRegistry_ShouldInitializeEmpty()
|
|
{
|
|
// Arrange & Act
|
|
var registry = new ToolRegistry();
|
|
|
|
// Assert
|
|
Assert.NotNull(registry);
|
|
Assert.Empty(registry.GetAllTools());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldAddTool()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var mockTool = CreateMockTool("test_tool", "A test tool");
|
|
|
|
// Act
|
|
registry.AddTool(mockTool.Object);
|
|
|
|
// Assert
|
|
Assert.Single(registry.GetAllTools());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldGetToolByName()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var mockTool = CreateMockTool("search_codex", "Search CODEX documents");
|
|
registry.AddTool(mockTool.Object);
|
|
|
|
// Act
|
|
var retrieved = registry.GetTool("search_codex");
|
|
|
|
// Assert
|
|
Assert.NotNull(retrieved);
|
|
Assert.Equal("search_codex", retrieved.Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_GetTool_WithInvalidName_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var mockTool = CreateMockTool("existing_tool", "Exists");
|
|
registry.AddTool(mockTool.Object);
|
|
|
|
// Act
|
|
var result = registry.GetTool("nonexistent_tool");
|
|
|
|
// Assert
|
|
Assert.Null(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldAddMultipleTools()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var tool1 = CreateMockTool("tool1", "First tool");
|
|
var tool2 = CreateMockTool("tool2", "Second tool");
|
|
var tool3 = CreateMockTool("tool3", "Third tool");
|
|
|
|
// Act
|
|
registry.AddTool(tool1.Object);
|
|
registry.AddTool(tool2.Object);
|
|
registry.AddTool(tool3.Object);
|
|
|
|
// Assert
|
|
var allTools = registry.GetAllTools();
|
|
Assert.Equal(3, allTools.Count());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldPreventDuplicateToolNames()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var tool1 = CreateMockTool("duplicate", "First");
|
|
var tool2 = CreateMockTool("duplicate", "Second");
|
|
|
|
registry.AddTool(tool1.Object);
|
|
|
|
// Act & Assert
|
|
var exception = Assert.Throws<ArgumentException>(() =>
|
|
registry.AddTool(tool2.Object)
|
|
);
|
|
Assert.Contains("already registered", exception.Message);
|
|
Assert.Single(registry.GetAllTools());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldRemoveTool()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
var mockTool = CreateMockTool("temp_tool", "Temporary");
|
|
registry.AddTool(mockTool.Object);
|
|
|
|
// Act
|
|
var removed = registry.RemoveTool("temp_tool");
|
|
|
|
// Assert
|
|
Assert.True(removed);
|
|
Assert.Empty(registry.GetAllTools());
|
|
Assert.Null(registry.GetTool("temp_tool"));
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_RemoveTool_WithInvalidName_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
|
|
// Act
|
|
var removed = registry.RemoveTool("nonexistent");
|
|
|
|
// Assert
|
|
Assert.False(removed);
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldListAllToolNames()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(CreateMockTool("tool_a", "A").Object);
|
|
registry.AddTool(CreateMockTool("tool_b", "B").Object);
|
|
registry.AddTool(CreateMockTool("tool_c", "C").Object);
|
|
|
|
// Act
|
|
var names = registry.GetToolNames();
|
|
|
|
// Assert
|
|
Assert.Equal(3, names.Count());
|
|
Assert.Contains("tool_a", names);
|
|
Assert.Contains("tool_b", names);
|
|
Assert.Contains("tool_c", names);
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldHaveTool()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(CreateMockTool("exists", "Tool").Object);
|
|
|
|
// Act & Assert
|
|
Assert.True(registry.HasTool("exists"));
|
|
Assert.False(registry.HasTool("not_exists"));
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_ShouldClearAllTools()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(CreateMockTool("tool1", "1").Object);
|
|
registry.AddTool(CreateMockTool("tool2", "2").Object);
|
|
|
|
// Act
|
|
registry.Clear();
|
|
|
|
// Assert
|
|
Assert.Empty(registry.GetAllTools());
|
|
Assert.Empty(registry.GetToolNames());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToolRegistry_GetAllTools_ShouldReturnReadOnlyCollection()
|
|
{
|
|
// Arrange
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(CreateMockTool("tool", "Tool").Object);
|
|
|
|
// Act
|
|
var tools = registry.GetAllTools();
|
|
|
|
// Assert
|
|
Assert.NotNull(tools);
|
|
// Ensure modifying returned collection doesn't affect registry
|
|
Assert.IsAssignableFrom<System.Collections.Generic.IEnumerable<IMcpTool>>(tools);
|
|
}
|
|
|
|
// Helper method to create mock tools
|
|
private Mock<IMcpTool> CreateMockTool(string name, string description)
|
|
{
|
|
var mockTool = new Mock<IMcpTool>();
|
|
mockTool.Setup(t => t.Name).Returns(name);
|
|
mockTool.Setup(t => t.Description).Returns(description);
|
|
mockTool.Setup(t => t.Schema).Returns(JsonDocument.Parse("""{"type": "object"}"""));
|
|
mockTool.Setup(t => t.ExecuteAsync(It.IsAny<JsonDocument>()))
|
|
.ReturnsAsync(JsonDocument.Parse("""{"status": "ok"}"""));
|
|
return mockTool;
|
|
}
|
|
}
|