save work
This commit is contained in:
@@ -232,6 +232,161 @@ public sealed class CommandHandlersTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleGraphExplainAsync_SetsExitCode4WhenNoFilters()
|
||||
{
|
||||
var originalExit = Environment.ExitCode;
|
||||
var backend = new StubBackendClient(new JobTriggerResult(true, "ok", null, null));
|
||||
var provider = BuildServiceProvider(backend);
|
||||
|
||||
try
|
||||
{
|
||||
var output = await CaptureTestConsoleAsync(console => CommandHandlers.HandleGraphExplainAsync(
|
||||
provider,
|
||||
tenant: null,
|
||||
graphId: "graph-123",
|
||||
vulnerabilityId: null,
|
||||
packagePurl: null,
|
||||
includeCallPaths: false,
|
||||
includeRuntimeHits: false,
|
||||
includePredicates: false,
|
||||
includeDsse: false,
|
||||
includeCounterfactuals: false,
|
||||
emitJson: false,
|
||||
verbose: false,
|
||||
cancellationToken: CancellationToken.None));
|
||||
|
||||
Assert.Equal(4, Environment.ExitCode);
|
||||
Assert.Contains("--vuln-id", output.Combined, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Null(backend.LastGraphExplainRequest);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.ExitCode = originalExit;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleGraphExplainAsync_CallsBackendAndRendersJson()
|
||||
{
|
||||
var originalExit = Environment.ExitCode;
|
||||
var backend = new StubBackendClient(new JobTriggerResult(true, "ok", null, null))
|
||||
{
|
||||
GraphExplainResponse = new GraphExplainResult
|
||||
{
|
||||
GraphId = "graph-123",
|
||||
GraphHash = "blake3:abc123",
|
||||
VulnerabilityId = "CVE-2025-0001",
|
||||
ReachabilityState = "reachable",
|
||||
Confidence = "high"
|
||||
}
|
||||
};
|
||||
var provider = BuildServiceProvider(backend);
|
||||
|
||||
try
|
||||
{
|
||||
var output = await CaptureTestConsoleAsync(console => CommandHandlers.HandleGraphExplainAsync(
|
||||
provider,
|
||||
tenant: "t-1",
|
||||
graphId: "graph-123",
|
||||
vulnerabilityId: "CVE-2025-0001",
|
||||
packagePurl: null,
|
||||
includeCallPaths: true,
|
||||
includeRuntimeHits: false,
|
||||
includePredicates: false,
|
||||
includeDsse: true,
|
||||
includeCounterfactuals: false,
|
||||
emitJson: true,
|
||||
verbose: false,
|
||||
cancellationToken: CancellationToken.None));
|
||||
|
||||
Assert.Equal(0, Environment.ExitCode);
|
||||
Assert.NotNull(backend.LastGraphExplainRequest);
|
||||
Assert.Equal("graph-123", backend.LastGraphExplainRequest!.GraphId);
|
||||
Assert.Equal("CVE-2025-0001", backend.LastGraphExplainRequest!.VulnerabilityId);
|
||||
Assert.True(backend.LastGraphExplainRequest!.IncludeCallPaths);
|
||||
Assert.True(backend.LastGraphExplainRequest!.IncludeDsseEnvelopes);
|
||||
Assert.Equal("t-1", backend.LastGraphExplainRequest!.Tenant);
|
||||
|
||||
using var document = JsonDocument.Parse(output.SpectreBuffer.Trim());
|
||||
var root = document.RootElement;
|
||||
Assert.Equal("graph-123", root.GetProperty("graphId").GetString());
|
||||
Assert.Equal("blake3:abc123", root.GetProperty("graphHash").GetString());
|
||||
Assert.Equal("reachable", root.GetProperty("reachabilityState").GetString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.ExitCode = originalExit;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleGraphVerifyAsync_EmitsJsonWithExpectedFields()
|
||||
{
|
||||
var originalExit = Environment.ExitCode;
|
||||
var provider = BuildServiceProvider(new StubBackendClient(new JobTriggerResult(true, "ok", null, null)));
|
||||
|
||||
try
|
||||
{
|
||||
var output = await CaptureTestConsoleAsync(console => CommandHandlers.HandleGraphVerifyAsync(
|
||||
provider,
|
||||
tenant: null,
|
||||
hash: "blake3:deadbeef",
|
||||
includeBundles: true,
|
||||
specificBundle: null,
|
||||
verifyRekor: true,
|
||||
casRoot: "C:\\offline-cas",
|
||||
format: "json",
|
||||
verbose: false,
|
||||
cancellationToken: CancellationToken.None));
|
||||
|
||||
Assert.Equal(0, Environment.ExitCode);
|
||||
|
||||
using var document = JsonDocument.Parse(output.SpectreBuffer.Trim());
|
||||
var root = document.RootElement;
|
||||
Assert.Equal("blake3:deadbeef", root.GetProperty("hash").GetString());
|
||||
Assert.Equal("VERIFIED", root.GetProperty("status").GetString());
|
||||
Assert.True(root.GetProperty("offlineMode").GetBoolean());
|
||||
Assert.True(root.GetProperty("rekorIncluded").GetBoolean());
|
||||
Assert.Equal(2, root.GetProperty("bundlesVerified").GetInt32());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.ExitCode = originalExit;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleGraphBundlesAsync_EmitsJsonWithBundles()
|
||||
{
|
||||
var originalExit = Environment.ExitCode;
|
||||
var provider = BuildServiceProvider(new StubBackendClient(new JobTriggerResult(true, "ok", null, null)));
|
||||
|
||||
try
|
||||
{
|
||||
var output = await CaptureTestConsoleAsync(console => CommandHandlers.HandleGraphBundlesAsync(
|
||||
provider,
|
||||
tenant: null,
|
||||
graphHash: "blake3:deadbeef",
|
||||
emitJson: true,
|
||||
verbose: false,
|
||||
cancellationToken: CancellationToken.None));
|
||||
|
||||
Assert.Equal(0, Environment.ExitCode);
|
||||
|
||||
using var document = JsonDocument.Parse(output.SpectreBuffer.Trim());
|
||||
var root = document.RootElement;
|
||||
Assert.Equal("blake3:deadbeef", root.GetProperty("graphHash").GetString());
|
||||
Assert.Equal(2, root.GetProperty("bundles").GetArrayLength());
|
||||
Assert.Contains(root.GetProperty("bundles").EnumerateArray(), bundle =>
|
||||
string.Equals(bundle.GetProperty("bundleId").GetString(), "bundle:001", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.ExitCode = originalExit;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleNodeLockValidateAsync_RendersDeclaredOnlyAndMissingLock()
|
||||
{
|
||||
@@ -4669,8 +4824,15 @@ spec:
|
||||
public Task<ReachabilityExplainResult> ExplainReachabilityAsync(ReachabilityExplainRequest request, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new ReachabilityExplainResult());
|
||||
|
||||
public GraphExplainRequest? LastGraphExplainRequest { get; private set; }
|
||||
|
||||
public GraphExplainResult GraphExplainResponse { get; set; } = new GraphExplainResult();
|
||||
|
||||
public Task<GraphExplainResult> ExplainGraphAsync(GraphExplainRequest request, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new GraphExplainResult());
|
||||
{
|
||||
LastGraphExplainRequest = request;
|
||||
return Task.FromResult(GraphExplainResponse);
|
||||
}
|
||||
|
||||
public Task<ApiSpecListResponse> ListApiSpecsAsync(string? tenant, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new ApiSpecListResponse());
|
||||
|
||||
Reference in New Issue
Block a user