Repair triage artifact scope and evidence contracts
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using StellaOps.Scanner.WebService.Contracts;
|
||||
using StellaOps.TestKit;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
public sealed class TriageControllerDemoContractsTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ArtifactGatedBuckets_ReturnsDeterministicSummaryForArtifactWorkspace()
|
||||
{
|
||||
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync(
|
||||
"/api/v1/triage/artifacts/asset-web-prod/gated-buckets",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var payload = await response.Content.ReadFromJsonAsync<GatedBucketsSummaryDto>(cancellationToken: TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(payload);
|
||||
Assert.True(payload!.TotalHiddenCount >= 1);
|
||||
Assert.True(payload.UnreachableCount >= 1);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DemoFindingEvidence_ReturnsUnifiedEvidenceWithoutDatabaseBacking()
|
||||
{
|
||||
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
const string findingId = "11111111-1111-1111-1111-111111111111";
|
||||
var response = await client.GetAsync(
|
||||
$"/api/v1/triage/findings/{findingId}/evidence?includeReplayCommand=true&includeReachability=true&includeVex=true&includeAttestations=true&includeDeltas=true",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var payload = await response.Content.ReadFromJsonAsync<UnifiedEvidenceResponseDto>(cancellationToken: TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(payload);
|
||||
Assert.Equal(findingId, payload!.FindingId);
|
||||
Assert.NotNull(payload.Reachability);
|
||||
Assert.NotEmpty(payload.Attestations ?? []);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using StellaOps.Scanner.WebService.Controllers;
|
||||
using StellaOps.TestKit;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
public sealed class VulnerabilitiesControllerTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_ReturnsDeterministicReachabilityAwarePayload()
|
||||
{
|
||||
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var firstResponse = await client.GetAsync("/api/v1/vulnerabilities?includeReachability=true", TestContext.Current.CancellationToken);
|
||||
var secondResponse = await client.GetAsync("/api/v1/vulnerabilities?includeReachability=true", TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, firstResponse.StatusCode);
|
||||
Assert.Equal(HttpStatusCode.OK, secondResponse.StatusCode);
|
||||
|
||||
var first = await firstResponse.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var second = await secondResponse.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
Assert.Equal(first, second);
|
||||
|
||||
var payload = await firstResponse.Content.ReadFromJsonAsync<ScannerVulnerabilitiesResponseDto>(cancellationToken: TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(payload);
|
||||
Assert.NotEmpty(payload!.Items);
|
||||
Assert.All(payload.Items, item => Assert.False(string.IsNullOrWhiteSpace(item.VulnId)));
|
||||
Assert.Contains(payload.Items, item => item.ReachabilityStatus is not null);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_AppliesSeverityAndReachabilityFilters()
|
||||
{
|
||||
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var payload = await client.GetFromJsonAsync<ScannerVulnerabilitiesResponseDto>(
|
||||
"/api/v1/vulnerabilities?severity=critical&reachability=reachable&includeReachability=true",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(payload);
|
||||
Assert.NotEmpty(payload!.Items);
|
||||
Assert.All(payload.Items, item =>
|
||||
{
|
||||
Assert.Equal("critical", item.Severity);
|
||||
Assert.Equal("reachable", item.ReachabilityStatus);
|
||||
});
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DetailAndStats_ReturnExpectedContracts()
|
||||
{
|
||||
await using var factory = ScannerApplicationFactory.CreateLightweight();
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var detail = await client.GetFromJsonAsync<ScannerVulnerabilityDto>(
|
||||
"/api/v1/vulnerabilities/vuln-001",
|
||||
TestContext.Current.CancellationToken);
|
||||
var stats = await client.GetFromJsonAsync<ScannerVulnerabilityStatsDto>(
|
||||
"/api/v1/vulnerabilities/status",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(detail);
|
||||
Assert.Equal("CVE-2021-44228", detail!.CveId);
|
||||
Assert.False(string.IsNullOrWhiteSpace(detail.FindingId));
|
||||
Assert.NotEmpty(detail.AffectedComponents);
|
||||
|
||||
Assert.NotNull(stats);
|
||||
Assert.True(stats!.Total >= 1);
|
||||
Assert.Equal(stats.BySeverity.Values.Sum(), stats.Total);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user