- 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>
219 lines
6.5 KiB
C#
219 lines
6.5 KiB
C#
using Xunit;
|
|
using Moq;
|
|
using Moq.Protected;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Svrnty.MCP.Core;
|
|
using CodexMcpServer.Tools;
|
|
|
|
namespace CodexMcpServer.Tests;
|
|
|
|
/// <summary>
|
|
/// Unit tests for GetDocumentSectionsTool following TDD approach.
|
|
/// Tests integration with CODEX API for retrieving document sections.
|
|
/// </summary>
|
|
public class GetDocumentSectionsToolTests
|
|
{
|
|
[Fact]
|
|
public void GetDocumentSectionsTool_ShouldHaveCorrectName()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
// Act
|
|
var name = tool.Name;
|
|
|
|
// Assert
|
|
Assert.Equal("get_document_sections", name);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetDocumentSectionsTool_ShouldHaveDescription()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
// Act
|
|
var description = tool.Description;
|
|
|
|
// Assert
|
|
Assert.NotNull(description);
|
|
Assert.NotEmpty(description);
|
|
Assert.Contains("section", description.ToLower());
|
|
}
|
|
|
|
[Fact]
|
|
public void GetDocumentSectionsTool_ShouldHaveValidSchema()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
// Act
|
|
var schema = tool.Schema;
|
|
|
|
// Assert
|
|
Assert.NotNull(schema);
|
|
var root = schema.RootElement;
|
|
Assert.Equal(JsonValueKind.Object, root.ValueKind);
|
|
|
|
// Schema should define required "id" parameter
|
|
Assert.True(root.TryGetProperty("properties", out var properties));
|
|
Assert.True(properties.TryGetProperty("id", out var idProp));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDocumentSectionsTool_ExecuteAsync_WithValidId_ShouldCallCodexApi()
|
|
{
|
|
// Arrange
|
|
var mockResponse = new
|
|
{
|
|
sections = new[]
|
|
{
|
|
new { id = "section1", title = "Introduction", content = "Intro text" },
|
|
new { id = "section2", title = "Body", content = "Body text" }
|
|
},
|
|
documentId = "doc123"
|
|
};
|
|
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
|
|
mockHttpMessageHandler
|
|
.Protected()
|
|
.Setup<Task<HttpResponseMessage>>(
|
|
"SendAsync",
|
|
ItExpr.Is<HttpRequestMessage>(req =>
|
|
req.Method == HttpMethod.Get &&
|
|
req.RequestUri.ToString().Contains("/api/documents/") &&
|
|
req.RequestUri.ToString().Contains("/sections")
|
|
),
|
|
ItExpr.IsAny<CancellationToken>()
|
|
)
|
|
.ReturnsAsync(new HttpResponseMessage
|
|
{
|
|
StatusCode = HttpStatusCode.OK,
|
|
Content = new StringContent(JsonSerializer.Serialize(mockResponse))
|
|
});
|
|
|
|
var httpClient = new HttpClient(mockHttpMessageHandler.Object)
|
|
{
|
|
BaseAddress = new System.Uri("http://localhost:5050")
|
|
};
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
var arguments = JsonDocument.Parse("""{"id": "doc123"}""");
|
|
|
|
// Act
|
|
var result = await tool.ExecuteAsync(arguments);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
var root = result.RootElement;
|
|
Assert.True(root.TryGetProperty("sections", out _));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDocumentSectionsTool_ExecuteAsync_WithEmptyId_ShouldReturnError()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
var arguments = JsonDocument.Parse("""{"id": ""}""");
|
|
|
|
// Act
|
|
var result = await tool.ExecuteAsync(arguments);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
var root = result.RootElement;
|
|
Assert.True(root.TryGetProperty("error", out _));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDocumentSectionsTool_ExecuteAsync_WithNullArguments_ShouldReturnError()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
// Act
|
|
var result = await tool.ExecuteAsync(null);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
var root = result.RootElement;
|
|
Assert.True(root.TryGetProperty("error", out _));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDocumentSectionsTool_ExecuteAsync_WithMissingIdProperty_ShouldReturnError()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
var arguments = JsonDocument.Parse("""{"other": "value"}""");
|
|
|
|
// Act
|
|
var result = await tool.ExecuteAsync(arguments);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
var root = result.RootElement;
|
|
Assert.True(root.TryGetProperty("error", out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void GetDocumentSectionsTool_ShouldImplementIMcpTool()
|
|
{
|
|
// Arrange
|
|
var httpClient = new HttpClient();
|
|
|
|
// Act
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
|
|
// Assert
|
|
Assert.IsAssignableFrom<IMcpTool>(tool);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetDocumentSectionsTool_ExecuteAsync_ShouldUseCorrectEndpoint()
|
|
{
|
|
// Arrange
|
|
string capturedUri = null;
|
|
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
|
|
mockHttpMessageHandler
|
|
.Protected()
|
|
.Setup<Task<HttpResponseMessage>>(
|
|
"SendAsync",
|
|
ItExpr.IsAny<HttpRequestMessage>(),
|
|
ItExpr.IsAny<CancellationToken>()
|
|
)
|
|
.ReturnsAsync((HttpRequestMessage req, CancellationToken ct) =>
|
|
{
|
|
capturedUri = req.RequestUri?.ToString();
|
|
return new HttpResponseMessage
|
|
{
|
|
StatusCode = HttpStatusCode.OK,
|
|
Content = new StringContent("""{"sections": []}""")
|
|
};
|
|
});
|
|
|
|
var httpClient = new HttpClient(mockHttpMessageHandler.Object)
|
|
{
|
|
BaseAddress = new System.Uri("http://localhost:5050")
|
|
};
|
|
var tool = new GetDocumentSectionsTool(httpClient);
|
|
var arguments = JsonDocument.Parse("""{"id": "doc123"}""");
|
|
|
|
// Act
|
|
await tool.ExecuteAsync(arguments);
|
|
|
|
// Assert
|
|
Assert.NotNull(capturedUri);
|
|
Assert.Contains("/api/documents/doc123/sections", capturedUri);
|
|
}
|
|
}
|