Forge
csharp3407750f
1using System.Net;
2using System.Net.Http.Json;
3using System.Text.Json;
4using AgentForge.Abstractions;
5
6namespace AgentForge.Tests;
7
8public sealed class ForgeGitHubOrgMembersImportTests
9{
10 private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true };
11
12 private static void ResetForgeAuthEnv()
13 {
14 Environment.SetEnvironmentVariable("FORGE_REQUIRE_AUTH", null);
15 Environment.SetEnvironmentVariable("FORGE_BOOTSTRAP_TOKEN", null);
16 Environment.SetEnvironmentVariable("FORGE_GITHUB_IMPORT_TOKEN", null);
17 }
18
19 [Fact]
20 public async Task Ams_showcase_bundle_includes_org_members_import_plugin()
21 {
22 ResetForgeAuthEnv();
23 using var factory = new ForgeWebApplicationFactory { PluginBundle = "ams-showcase" };
24 using var client = factory.CreateClient();
25
26 var caps = await client.GetFromJsonAsync<JsonElement>("/api/v1/capabilities", JsonOptions);
27 var plugins = caps.GetProperty("plugins").EnumerateArray()
28 .Select(p => p.GetProperty("id").GetString())
29 .ToList();
30 var features = caps.GetProperty("features").EnumerateArray()
31 .Select(f => f.GetString())
32 .ToList();
33
34 Assert.Contains("org-import-github", plugins);
35 Assert.Contains("repository-import-org-github", plugins);
36 Assert.Contains("org_import_github", features);
37 }
38
39 [Fact]
40 public async Task Standard_bundle_does_not_load_org_members_import_plugin()
41 {
42 ResetForgeAuthEnv();
43 using var factory = new ForgeWebApplicationFactory();
44 using var client = factory.CreateClient();
45
46 var caps = await client.GetFromJsonAsync<JsonElement>("/api/v1/capabilities", JsonOptions);
47 var plugins = caps.GetProperty("plugins").EnumerateArray()
48 .Select(p => p.GetProperty("id").GetString())
49 .ToList();
50
51 Assert.DoesNotContain("org-import-github", plugins);
52 }
53
54 [Fact]
55 public async Task Members_import_requires_bootstrap_token()
56 {
57 ResetForgeAuthEnv();
58 Environment.SetEnvironmentVariable("FORGE_REQUIRE_AUTH", "true");
59 Environment.SetEnvironmentVariable("FORGE_BOOTSTRAP_TOKEN", "bootstrap-members-auth");
60 using var factory = new ForgeWebApplicationFactory { PluginBundle = "ams-showcase" };
61 using var client = factory.CreateClient();
62
63 var response = await client.PostAsJsonAsync(
64 "/api/v1/orgs/ai-guiders/import/github/members",
65 new { dryRun = true },
66 JsonOptions);
67 Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
68
69 ResetForgeAuthEnv();
70 }
71
72 [Fact]
73 public async Task Members_import_dry_run_without_github_token_returns_empty_planned()
74 {
75 ResetForgeAuthEnv();
76 Environment.SetEnvironmentVariable("FORGE_BOOTSTRAP_TOKEN", "bootstrap-members-dry");
77 using var factory = new ForgeWebApplicationFactory { PluginBundle = "ams-showcase" };
78 using var client = factory.CreateClient();
79 client.DefaultRequestHeaders.Authorization = new("Bearer", "bootstrap-members-dry");
80
81 using (var bootstrap = factory.CreateClient())
82 {
83 bootstrap.DefaultRequestHeaders.Authorization = new("Bearer", "bootstrap-members-dry");
84 (await bootstrap.PostAsJsonAsync(
85 "/api/v1/orgs",
86 new { slug = "members-dry-org", displayName = "Members Dry Org" },
87 JsonOptions)).EnsureSuccessStatusCode();
88 }
89
90 var response = await client.PostAsJsonAsync(
91 "/api/v1/orgs/members-dry-org/import/github/members",
92 new { externalOrg = "AI-Guiders", dryRun = true },
93 JsonOptions);
94 response.EnsureSuccessStatusCode();
95
96 var body = await response.Content.ReadFromJsonAsync<ForgeOrgImportResponse>(JsonOptions);
97 Assert.NotNull(body);
98 Assert.Equal("members-dry-org", body.ForgeOrg);
99 Assert.Equal("AI-Guiders", body.ExternalOrg);
100 Assert.Equal(0, body.Total);
101
102 ResetForgeAuthEnv();
103 }
104}
105
View only · write via MCP/CIDE