Forge
csharp3407750f
1using System.Net.Http.Json;
2using AgentForge.Services;
3
4namespace AgentForge.Tests;
5
6public sealed class ForgeCommitTrailerTests
7{
8 [Fact]
9 public void TryParse_reads_actor_issue_and_anchor_trailers()
10 {
11 const string message = """
12 feat: zone split
13
14 Forge-Actor: oar:Comet
15 Forge-Issue: 3, 7
16 Forge-Anchors: [F:src/Zones.cs; M:Apply; L:12-14]
17 """;
18
19 Assert.True(ForgeCommitTrailerParser.TryParse(message, "feat/x", out var request));
20 Assert.Equal("oar:Comet", request.Actor);
21 Assert.Equal([3, 7], request.IssueNumbers);
22 Assert.Single(request.Anchors!);
23 Assert.Equal("src/Zones.cs", request.Anchors![0].File);
24 }
25
26 [Fact]
27 public void FormatTrailers_round_trips_through_TryParse()
28 {
29 var original = new Contracts.CommitProvenanceRequest(
30 "oar:LineB",
31 "main",
32 [2],
33 MrNumber: 4,
34 RunId: "run-1",
35 Anchors: [new Contracts.CodeAnchor("src/A.cs", 10, 12)],
36 LogicalLineId: "line-9");
37
38 var message = ForgeCommitTrailerParser.AppendToMessage("subject", original);
39 Assert.True(ForgeCommitTrailerParser.TryParse(message, "main", out var parsed));
40 Assert.Equal(original.Actor, parsed.Actor);
41 Assert.Equal(original.IssueNumbers, parsed.IssueNumbers);
42 Assert.Equal(original.MrNumber, parsed.MrNumber);
43 Assert.Equal(original.RunId, parsed.RunId);
44 Assert.Equal(original.LogicalLineId, parsed.LogicalLineId);
45 Assert.Equal(original.Anchors![0].File, parsed.Anchors![0].File);
46 }
47
48 [Fact]
49 public async Task Git_push_without_body_provenance_reads_commit_trailers()
50 {
51 using var factory = new ForgeWebApplicationFactory();
52 using var client = factory.CreateClient();
53
54 await client.PostAsJsonAsync("/api/v1/repos", new { name = "trailer-repo", driveMode = "agent-driven" });
55
56 factory.Git.CreateCommitOnBranch(
57 "trailer-repo",
58 "feat",
59 "README.md",
60 "hello",
61 ForgeCommitTrailerParser.AppendToMessage("init with trailers", new Contracts.CommitProvenanceRequest(
62 "oar:Comet",
63 "feat",
64 [1],
65 Anchors: [new Contracts.CodeAnchor("README.md", 1)])));
66
67 var tip = factory.Git.GetBranchTipCommit("trailer-repo", "feat")!;
68 var push = await client.PostAsJsonAsync("/api/v1/git/push", new
69 {
70 repo = "trailer-repo",
71 branch = "feat",
72 commit = tip,
73 });
74 push.EnsureSuccessStatusCode();
75
76 var get = await client.GetAsync($"/api/v1/repos/trailer-repo/commits/{tip}/provenance");
77 get.EnsureSuccessStatusCode();
78 var body = await get.Content.ReadAsStringAsync();
79 Assert.Contains("oar:Comet", body, StringComparison.Ordinal);
80 Assert.Contains("README.md", body, StringComparison.Ordinal);
81 }
82}
83
View only · write via MCP/CIDE