Forge
csharp3407750f
1using System.Net.Http.Json;
2using System.Text.Json;
3using AgentForge.Abstractions;
4
5namespace AgentForge.Tests;
6
7public sealed class ForgeMcpInvokeTests(ForgeWebApplicationFactory factory) : IClassFixture<ForgeWebApplicationFactory>
8{
9 private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true };
10
11 [Fact]
12 public async Task Invoke_plugin_tool_get_human_view_url()
13 {
14 var http = factory.CreateClient();
15 var result = await InvokeAsync(http, ForgeMcpToolNames.ViewUrl);
16 Assert.True(result.GetProperty("success").GetBoolean());
17 using var doc = JsonDocument.Parse(result.GetProperty("body").GetString()!);
18 Assert.Equal("http://test.local/view", doc.RootElement.GetProperty("viewBaseUrl").GetString());
19 }
20
21 [Fact]
22 public async Task Invoke_create_repo_and_list()
23 {
24 var http = factory.CreateClient();
25
26 var create = await InvokeAsync(http, "create_repo", new Dictionary<string, JsonElement>
27 {
28 ["name"] = JsonSerializer.SerializeToElement("invoke-repo"),
29 ["description"] = JsonSerializer.SerializeToElement("invoke test"),
30 ["visibility"] = JsonSerializer.SerializeToElement("public"),
31 });
32 Assert.True(create.GetProperty("success").GetBoolean());
33
34 var list = await InvokeAsync(http, "list_repos");
35 Assert.True(list.GetProperty("success").GetBoolean());
36 using var listBody = JsonDocument.Parse(list.GetProperty("body").GetString()!);
37 Assert.Equal(1, listBody.RootElement.GetProperty("total").GetInt32());
38 }
39
40 [Fact]
41 public async Task Invoke_unknown_tool_returns_bad_request()
42 {
43 var http = factory.CreateClient();
44 var response = await http.PostAsJsonAsync("/api/v1/mcp/invoke", new { tool = "not_a_real_tool" });
45 Assert.Equal(System.Net.HttpStatusCode.BadRequest, response.StatusCode);
46 }
47
48 [Fact]
49 public async Task Capabilities_create_repo_schema_includes_org_and_visibility()
50 {
51 var caps = await factory.CreateClient().GetFromJsonAsync<JsonElement>("/api/v1/capabilities", JsonOptions);
52 var createRepo = caps!.GetProperty("tools").EnumerateArray()
53 .First(t => t.GetProperty("name").GetString() == "create_repo");
54 var props = createRepo.GetProperty("inputSchema").GetProperty("properties");
55 Assert.True(props.TryGetProperty("org", out _));
56 Assert.True(props.TryGetProperty("visibility", out _));
57 }
58
59 [Fact]
60 public async Task Capabilities_tools_include_schemas()
61 {
62 var caps = await factory.CreateClient().GetFromJsonAsync<JsonElement>("/api/v1/capabilities", JsonOptions);
63 var tools = caps!.GetProperty("tools").EnumerateArray().ToList();
64 Assert.NotEmpty(tools);
65
66 var createIssue = tools.First(t => t.GetProperty("name").GetString() == ForgeMcpToolNames.IssueCreate);
67 Assert.True(createIssue.TryGetProperty("inputSchema", out var schema));
68 Assert.Equal("object", schema.GetProperty("type").GetString());
69 }
70
71 private static async Task<JsonElement> InvokeAsync(
72 HttpClient http,
73 string tool,
74 Dictionary<string, JsonElement>? arguments = null)
75 {
76 var response = await http.PostAsJsonAsync("/api/v1/mcp/invoke", new { tool, arguments });
77 var payload = await response.Content.ReadFromJsonAsync<JsonElement>(JsonOptions);
78 return payload;
79 }
80}
81
View only · write via MCP/CIDE