Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Scanner.Triage;
|
||||
using StellaOps.Scanner.Triage.Entities;
|
||||
using StellaOps.Scanner.WebService.Contracts;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
public sealed class FindingsEvidenceControllerTests
|
||||
{
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsNotFound_WhenFindingMissing()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{Guid.NewGuid()}/evidence");
|
||||
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsForbidden_WhenRawScopeMissing()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{Guid.NewGuid()}/evidence?includeRaw=true");
|
||||
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetEvidence_ReturnsEvidence_WhenFindingExists()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var findingId = await SeedFindingAsync(factory);
|
||||
|
||||
var response = await client.GetAsync($"/api/v1/findings/{findingId}/evidence");
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<FindingEvidenceResponse>(SerializerOptions);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(findingId.ToString(), result!.FindingId);
|
||||
Assert.Equal("CVE-2024-12345", result.Cve);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BatchEvidence_ReturnsBadRequest_WhenTooMany()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var request = new BatchEvidenceRequest
|
||||
{
|
||||
FindingIds = Enumerable.Range(0, 101).Select(_ => Guid.NewGuid().ToString()).ToList()
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/api/v1/findings/evidence/batch", request);
|
||||
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BatchEvidence_ReturnsResults_ForExistingFindings()
|
||||
{
|
||||
using var secrets = new TestSurfaceSecretsScope();
|
||||
using var factory = new ScannerApplicationFactory().WithOverrides(configuration =>
|
||||
{
|
||||
configuration["scanner:authority:enabled"] = "false";
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var findingId = await SeedFindingAsync(factory);
|
||||
|
||||
var request = new BatchEvidenceRequest
|
||||
{
|
||||
FindingIds = new[] { findingId.ToString(), Guid.NewGuid().ToString() }
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/api/v1/findings/evidence/batch", request);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<BatchEvidenceResponse>(SerializerOptions);
|
||||
Assert.NotNull(result);
|
||||
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.MigrateAsync();
|
||||
|
||||
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",
|
||||
LastSeenAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
db.Findings.Add(finding);
|
||||
db.RiskResults.Add(new TriageRiskResult
|
||||
{
|
||||
FindingId = findingId,
|
||||
PolicyId = "policy-1",
|
||||
PolicyVersion = "1.0.0",
|
||||
InputsHash = "sha256:inputs",
|
||||
Score = 72,
|
||||
Verdict = TriageVerdict.Block,
|
||||
Lane = TriageLane.High,
|
||||
Why = "High risk score",
|
||||
ComputedAt = DateTimeOffset.UtcNow
|
||||
});
|
||||
db.EvidenceArtifacts.Add(new TriageEvidenceArtifact
|
||||
{
|
||||
FindingId = findingId,
|
||||
Type = TriageEvidenceType.Attestation,
|
||||
Title = "SBOM attestation",
|
||||
ContentHash = "sha256:attestation",
|
||||
Uri = "s3://evidence/attestation.json"
|
||||
});
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
return findingId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user