tests fixes and sprints work
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Moq;
|
||||
using StellaOps.Scanner.Triage;
|
||||
using StellaOps.Scanner.Triage.Entities;
|
||||
using StellaOps.Scanner.WebService.Contracts;
|
||||
using StellaOps.Scanner.WebService.Services;
|
||||
using Xunit;
|
||||
|
||||
|
||||
@@ -17,16 +19,22 @@ public sealed class FindingsEvidenceControllerTests
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact(Skip = "Requires full evidence service chain - InternalServerError without proper service mocking")]
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsNotFound_WhenFindingMissing()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
var mockTriageService = new Mock<ITriageQueryService>();
|
||||
mockTriageService.Setup(s => s.GetFindingAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((TriageFinding?)null);
|
||||
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(
|
||||
configuration => { configuration["scanner:authority:enabled"] = "false"; },
|
||||
configureServices: services =>
|
||||
{
|
||||
services.RemoveAll<ITriageQueryService>();
|
||||
services.AddSingleton(mockTriageService.Object);
|
||||
});
|
||||
await factory.InitializeAsync();
|
||||
await EnsureTriageSchemaAsync(factory);
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{Guid.NewGuid()}/evidence");
|
||||
@@ -35,16 +43,13 @@ public sealed class FindingsEvidenceControllerTests
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact(Skip = "Requires full evidence service chain - InternalServerError without proper service mocking")]
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsForbidden_WhenRawScopeMissing()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(
|
||||
configuration => { configuration["scanner:authority:enabled"] = "false"; });
|
||||
await factory.InitializeAsync();
|
||||
await EnsureTriageSchemaAsync(factory);
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{Guid.NewGuid()}/evidence?includeRaw=true");
|
||||
@@ -53,19 +58,50 @@ public sealed class FindingsEvidenceControllerTests
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact(Skip = "Requires full evidence service chain - InternalServerError without proper service mocking")]
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsEvidence_WhenFindingExists()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
var findingId = Guid.NewGuid();
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
await factory.InitializeAsync();
|
||||
await EnsureTriageSchemaAsync(factory);
|
||||
using var client = factory.CreateClient();
|
||||
Id = findingId,
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2024-12345",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
var mockTriageService = new Mock<ITriageQueryService>();
|
||||
mockTriageService.Setup(s => s.GetFindingAsync(findingId.ToString(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(finding);
|
||||
|
||||
var findingId = await SeedFindingAsync(factory);
|
||||
var mockEvidenceService = new Mock<IEvidenceCompositionService>();
|
||||
mockEvidenceService.Setup(s => s.ComposeAsync(It.IsAny<TriageFinding>(), false, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new FindingEvidenceResponse
|
||||
{
|
||||
FindingId = findingId.ToString(),
|
||||
Cve = "CVE-2024-12345",
|
||||
Component = new ComponentInfo { Name = "lodash", Version = "4.17.20", Purl = "pkg:npm/lodash@4.17.20" },
|
||||
LastSeen = now
|
||||
});
|
||||
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(
|
||||
configuration => { configuration["scanner:authority:enabled"] = "false"; },
|
||||
configureServices: services =>
|
||||
{
|
||||
services.RemoveAll<ITriageQueryService>();
|
||||
services.AddSingleton(mockTriageService.Object);
|
||||
services.RemoveAll<IEvidenceCompositionService>();
|
||||
services.AddSingleton(mockEvidenceService.Object);
|
||||
});
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{findingId}/evidence");
|
||||
|
||||
@@ -82,12 +118,9 @@ public sealed class FindingsEvidenceControllerTests
|
||||
public async Task BatchEvidence_ReturnsBadRequest_WhenTooMany()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(
|
||||
configuration => { configuration["scanner:authority:enabled"] = "false"; });
|
||||
await factory.InitializeAsync();
|
||||
await EnsureTriageSchemaAsync(factory);
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var request = new BatchEvidenceRequest
|
||||
@@ -101,19 +134,52 @@ public sealed class FindingsEvidenceControllerTests
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact(Skip = "Requires full evidence service chain - InternalServerError without proper service mocking")]
|
||||
[Fact]
|
||||
public async Task BatchEvidence_ReturnsResults_ForExistingFindings()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
var findingId = Guid.NewGuid();
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
await factory.InitializeAsync();
|
||||
await EnsureTriageSchemaAsync(factory);
|
||||
using var client = factory.CreateClient();
|
||||
Id = findingId,
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2024-12345",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
var mockTriageService = new Mock<ITriageQueryService>();
|
||||
mockTriageService.Setup(s => s.GetFindingAsync(findingId.ToString(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(finding);
|
||||
mockTriageService.Setup(s => s.GetFindingAsync(It.Is<string>(id => id != findingId.ToString()), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((TriageFinding?)null);
|
||||
|
||||
var findingId = await SeedFindingAsync(factory);
|
||||
var mockEvidenceService = new Mock<IEvidenceCompositionService>();
|
||||
mockEvidenceService.Setup(s => s.ComposeAsync(It.IsAny<TriageFinding>(), false, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new FindingEvidenceResponse
|
||||
{
|
||||
FindingId = findingId.ToString(),
|
||||
Cve = "CVE-2024-12345",
|
||||
Component = new ComponentInfo { Name = "lodash", Version = "4.17.20", Purl = "pkg:npm/lodash@4.17.20" },
|
||||
LastSeen = now
|
||||
});
|
||||
|
||||
await using var factory = new ScannerApplicationFactory().WithOverrides(
|
||||
configuration => { configuration["scanner:authority:enabled"] = "false"; },
|
||||
configureServices: services =>
|
||||
{
|
||||
services.RemoveAll<ITriageQueryService>();
|
||||
services.AddSingleton(mockTriageService.Object);
|
||||
services.RemoveAll<IEvidenceCompositionService>();
|
||||
services.AddSingleton(mockEvidenceService.Object);
|
||||
});
|
||||
await factory.InitializeAsync();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var request = new BatchEvidenceRequest
|
||||
{
|
||||
@@ -129,61 +195,4 @@ public sealed class FindingsEvidenceControllerTests
|
||||
Assert.Single(result!.Findings);
|
||||
Assert.Equal(findingId.ToString(), result.Findings[0].FindingId);
|
||||
}
|
||||
|
||||
private static async Task<Guid> SeedFindingAsync(ScannerApplicationFactory factory)
|
||||
{
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<TriageDbContext>();
|
||||
|
||||
await db.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var findingId = Guid.NewGuid();
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = findingId,
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2024-12345",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
db.Findings.Add(finding);
|
||||
db.RiskResults.Add(new TriageRiskResult
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = findingId,
|
||||
PolicyId = "policy-1",
|
||||
PolicyVersion = "1.0.0",
|
||||
InputsHash = "sha256:inputs",
|
||||
Score = 72,
|
||||
Verdict = TriageVerdict.Block,
|
||||
Lane = TriageLane.Blocked,
|
||||
Why = "High risk score",
|
||||
ComputedAt = now
|
||||
});
|
||||
db.EvidenceArtifacts.Add(new TriageEvidenceArtifact
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = findingId,
|
||||
Type = TriageEvidenceType.Provenance,
|
||||
Title = "SBOM attestation",
|
||||
ContentHash = "sha256:attestation",
|
||||
Uri = "s3://evidence/attestation.json",
|
||||
CreatedAt = now
|
||||
});
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
return findingId;
|
||||
}
|
||||
|
||||
private static async Task EnsureTriageSchemaAsync(ScannerApplicationFactory factory)
|
||||
{
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<TriageDbContext>();
|
||||
await db.Database.EnsureCreatedAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user