| 1 | using System.Net.Http.Json; |
| 2 | using System.Text.Json; |
| 3 | |
| 4 | namespace AgentForge.Tests; |
| 5 | |
| 6 | public sealed class ForgeMrDiffTests(ForgeWebApplicationFactory factory) : IClassFixture<ForgeWebApplicationFactory> |
| 7 | { |
| 8 | private readonly HttpClient _client = factory.CreateClient(); |
| 9 | private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; |
| 10 | |
| 11 | [Fact] |
| 12 | public async Task Merge_request_diff_returns_structured_files_not_raw_git_diff() |
| 13 | { |
| 14 | await _client.PostAsJsonAsync("/api/v1/repos", new { name = "diff-shape" }); |
| 15 | factory.Git.CreateCommitOnBranch("diff-shape", "main", "README.md", "main", "main"); |
| 16 | factory.Git.CreateCommitOnBranch("diff-shape", "feat", "pilot.txt", "pilot line", "feat"); |
| 17 | |
| 18 | await _client.PostAsJsonAsync("/api/v1/repos/diff-shape/merge-requests", new |
| 19 | { |
| 20 | title = "add pilot", |
| 21 | sourceBranch = "feat", |
| 22 | }); |
| 23 | |
| 24 | var diff = await _client.GetFromJsonAsync<JsonElement>( |
| 25 | "/api/v1/repos/diff-shape/merge-requests/1/diff", |
| 26 | JsonOptions); |
| 27 | |
| 28 | Assert.False(diff.TryGetProperty("diff", out _), "Top-level raw diff field should be removed."); |
| 29 | Assert.Equal("feat", diff.GetProperty("sourceBranch").GetString()); |
| 30 | Assert.Equal("main", diff.GetProperty("targetBranch").GetString()); |
| 31 | Assert.Equal(1, diff.GetProperty("stats").GetProperty("changedFiles").GetInt32()); |
| 32 | Assert.Equal(1, diff.GetProperty("stats").GetProperty("additions").GetInt32()); |
| 33 | |
| 34 | var file = diff.GetProperty("files")[0]; |
| 35 | Assert.Equal("pilot.txt", file.GetProperty("path").GetString()); |
| 36 | Assert.Equal("added", file.GetProperty("status").GetString()); |
| 37 | var patch = file.GetProperty("patch").GetString() ?? string.Empty; |
| 38 | Assert.StartsWith("@@", patch, StringComparison.Ordinal); |
| 39 | Assert.Contains("+pilot line", patch, StringComparison.Ordinal); |
| 40 | Assert.DoesNotContain("diff --git", patch, StringComparison.Ordinal); |
| 41 | } |
| 42 | |
| 43 | [Fact] |
| 44 | public async Task Merge_request_view_renders_structured_diff_summary() |
| 45 | { |
| 46 | await _client.PostAsJsonAsync("/api/v1/repos", new { name = "diff-view" }); |
| 47 | factory.Git.CreateCommitOnBranch("diff-view", "main", "README.md", "main", "main"); |
| 48 | factory.Git.CreateCommitOnBranch("diff-view", "feat", "a.txt", "a", "feat"); |
| 49 | await _client.PostAsJsonAsync("/api/v1/repos/diff-view/merge-requests", new |
| 50 | { |
| 51 | title = "t", |
| 52 | sourceBranch = "feat", |
| 53 | }); |
| 54 | |
| 55 | var view = await _client.GetAsync("/view/repos/diff-view/merge-requests/1"); |
| 56 | view.EnsureSuccessStatusCode(); |
| 57 | var html = await view.Content.ReadAsStringAsync(); |
| 58 | Assert.Contains("1 file changed", html, StringComparison.Ordinal); |
| 59 | Assert.Contains("a.txt", html, StringComparison.Ordinal); |
| 60 | Assert.Contains("added", html, StringComparison.Ordinal); |
| 61 | Assert.Contains("diff-file", html, StringComparison.Ordinal); |
| 62 | Assert.Contains("diff-add", html, StringComparison.Ordinal); |
| 63 | Assert.Contains("diff-hunk-header", html, StringComparison.Ordinal); |
| 64 | Assert.DoesNotContain("diff --git", html, StringComparison.Ordinal); |
| 65 | } |
| 66 | } |
| 67 | |