up
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Scanner.ProofSpine;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
public sealed class ProofSpineEndpointsTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task GetSpine_ReturnsSpine_WithVerification()
|
||||
{
|
||||
await using var factory = new ScannerApplicationFactory();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
|
||||
var builder = scope.ServiceProvider.GetRequiredService<ProofSpineBuilder>();
|
||||
var repository = scope.ServiceProvider.GetRequiredService<IProofSpineRepository>();
|
||||
|
||||
var spine = await builder
|
||||
.ForArtifact("sha256:feedface")
|
||||
.ForVulnerability("CVE-2025-0001")
|
||||
.WithPolicyProfile("default")
|
||||
.WithScanRun("scan-001")
|
||||
.AddSbomSlice("sha256:sbom", new[] { "pkg:a", "pkg:b" }, toolId: "sbom", toolVersion: "1.0.0")
|
||||
.AddPolicyEval(
|
||||
policyDigest: "sha256:policy",
|
||||
factors: new Dictionary<string, string> { ["policy"] = "default" },
|
||||
verdict: "not_affected",
|
||||
verdictReason: "component_not_present",
|
||||
toolId: "policy",
|
||||
toolVersion: "1.0.0")
|
||||
.BuildAsync();
|
||||
|
||||
await repository.SaveAsync(spine);
|
||||
|
||||
var client = factory.CreateClient();
|
||||
var response = await client.GetAsync($"/api/v1/spines/{spine.SpineId}");
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadFromJsonAsync<JsonElement>();
|
||||
Assert.Equal(spine.SpineId, body.GetProperty("spineId").GetString());
|
||||
|
||||
var segments = body.GetProperty("segments");
|
||||
Assert.True(segments.GetArrayLength() > 0);
|
||||
Assert.True(body.TryGetProperty("verification", out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListSpinesByScan_ReturnsSummaries_WithSegmentCount()
|
||||
{
|
||||
await using var factory = new ScannerApplicationFactory();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
|
||||
var builder = scope.ServiceProvider.GetRequiredService<ProofSpineBuilder>();
|
||||
var repository = scope.ServiceProvider.GetRequiredService<IProofSpineRepository>();
|
||||
|
||||
var spine = await builder
|
||||
.ForArtifact("sha256:feedface")
|
||||
.ForVulnerability("CVE-2025-0002")
|
||||
.WithPolicyProfile("default")
|
||||
.WithScanRun("scan-002")
|
||||
.AddSbomSlice("sha256:sbom", new[] { "pkg:a" }, toolId: "sbom", toolVersion: "1.0.0")
|
||||
.AddPolicyEval(
|
||||
policyDigest: "sha256:policy",
|
||||
factors: new Dictionary<string, string> { ["policy"] = "default" },
|
||||
verdict: "affected",
|
||||
verdictReason: "reachable",
|
||||
toolId: "policy",
|
||||
toolVersion: "1.0.0")
|
||||
.BuildAsync();
|
||||
|
||||
await repository.SaveAsync(spine);
|
||||
|
||||
var client = factory.CreateClient();
|
||||
var response = await client.GetAsync("/api/v1/scans/scan-002/spines");
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadFromJsonAsync<JsonElement>();
|
||||
var items = body.GetProperty("items");
|
||||
Assert.Equal(1, items.GetArrayLength());
|
||||
Assert.Equal(spine.SpineId, items[0].GetProperty("spineId").GetString());
|
||||
Assert.True(items[0].GetProperty("segmentCount").GetInt32() > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSpine_ReturnsInvalidStatus_WhenSegmentTampered()
|
||||
{
|
||||
await using var factory = new ScannerApplicationFactory();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
|
||||
var builder = scope.ServiceProvider.GetRequiredService<ProofSpineBuilder>();
|
||||
var repository = scope.ServiceProvider.GetRequiredService<IProofSpineRepository>();
|
||||
|
||||
var spine = await builder
|
||||
.ForArtifact("sha256:feedface")
|
||||
.ForVulnerability("CVE-2025-0003")
|
||||
.WithPolicyProfile("default")
|
||||
.WithScanRun("scan-003")
|
||||
.AddSbomSlice("sha256:sbom", new[] { "pkg:a" }, toolId: "sbom", toolVersion: "1.0.0")
|
||||
.AddPolicyEval(
|
||||
policyDigest: "sha256:policy",
|
||||
factors: new Dictionary<string, string> { ["policy"] = "default" },
|
||||
verdict: "affected",
|
||||
verdictReason: "reachable",
|
||||
toolId: "policy",
|
||||
toolVersion: "1.0.0")
|
||||
.BuildAsync();
|
||||
|
||||
var tamperedSegment = spine.Segments[0] with { ResultHash = spine.Segments[0].ResultHash + "00" };
|
||||
var tampered = spine with { Segments = new[] { tamperedSegment, spine.Segments[1] } };
|
||||
|
||||
await repository.SaveAsync(tampered);
|
||||
|
||||
var client = factory.CreateClient();
|
||||
var response = await client.GetAsync($"/api/v1/spines/{spine.SpineId}");
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadFromJsonAsync<JsonElement>();
|
||||
var segments = body.GetProperty("segments");
|
||||
Assert.Equal("invalid", segments[0].GetProperty("status").GetString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user