Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
using System.Collections.Immutable;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Policy.Exceptions.Models;
|
||||
using StellaOps.Policy.Exceptions.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Policy.Exceptions.Tests;
|
||||
|
||||
public sealed class EvidenceRequirementValidatorTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ValidateForApprovalAsync_NoHooks_ReturnsValid()
|
||||
{
|
||||
var validator = CreateValidator(new StubHookRegistry([]));
|
||||
var exception = CreateException();
|
||||
|
||||
var result = await validator.ValidateForApprovalAsync(exception);
|
||||
|
||||
result.IsValid.Should().BeTrue();
|
||||
result.MissingEvidence.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateForApprovalAsync_MissingEvidence_ReturnsInvalid()
|
||||
{
|
||||
var hooks = ImmutableArray.Create(new EvidenceHook
|
||||
{
|
||||
HookId = "hook-1",
|
||||
Type = EvidenceType.FeatureFlagDisabled,
|
||||
Description = "Feature flag disabled",
|
||||
IsMandatory = true
|
||||
});
|
||||
|
||||
var validator = CreateValidator(new StubHookRegistry(hooks));
|
||||
var exception = CreateException();
|
||||
|
||||
var result = await validator.ValidateForApprovalAsync(exception);
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
result.MissingEvidence.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateForApprovalAsync_TrustScoreTooLow_ReturnsInvalid()
|
||||
{
|
||||
var hooks = ImmutableArray.Create(new EvidenceHook
|
||||
{
|
||||
HookId = "hook-1",
|
||||
Type = EvidenceType.BackportMerged,
|
||||
Description = "Backport merged",
|
||||
IsMandatory = true,
|
||||
MinTrustScore = 0.8m
|
||||
});
|
||||
|
||||
var validator = CreateValidator(
|
||||
new StubHookRegistry(hooks),
|
||||
trustScore: 0.5m);
|
||||
|
||||
var exception = CreateException(new EvidenceRequirements
|
||||
{
|
||||
Hooks = hooks,
|
||||
SubmittedEvidence = ImmutableArray.Create(new SubmittedEvidence
|
||||
{
|
||||
EvidenceId = "e-1",
|
||||
HookId = "hook-1",
|
||||
Type = EvidenceType.BackportMerged,
|
||||
Reference = "ref",
|
||||
SubmittedAt = DateTimeOffset.UtcNow,
|
||||
SubmittedBy = "tester",
|
||||
ValidationStatus = EvidenceValidationStatus.Valid
|
||||
})
|
||||
});
|
||||
|
||||
var result = await validator.ValidateForApprovalAsync(exception);
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
result.InvalidEvidence.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
private static EvidenceRequirementValidator CreateValidator(
|
||||
IEvidenceHookRegistry registry,
|
||||
decimal trustScore = 1.0m,
|
||||
bool schemaValid = true,
|
||||
bool signatureValid = true)
|
||||
{
|
||||
return new EvidenceRequirementValidator(
|
||||
registry,
|
||||
new StubAttestationVerifier(signatureValid),
|
||||
new StubTrustScoreService(trustScore),
|
||||
new StubSchemaValidator(schemaValid),
|
||||
NullLogger<EvidenceRequirementValidator>.Instance);
|
||||
}
|
||||
|
||||
private static ExceptionObject CreateException(EvidenceRequirements? requirements = null)
|
||||
{
|
||||
return new ExceptionObject
|
||||
{
|
||||
ExceptionId = "EXC-TEST",
|
||||
Version = 1,
|
||||
Status = ExceptionStatus.Active,
|
||||
Type = ExceptionType.Vulnerability,
|
||||
Scope = new ExceptionScope { VulnerabilityId = "CVE-2024-0001" },
|
||||
OwnerId = "owner",
|
||||
RequesterId = "requester",
|
||||
CreatedAt = DateTimeOffset.UtcNow,
|
||||
UpdatedAt = DateTimeOffset.UtcNow,
|
||||
ExpiresAt = DateTimeOffset.UtcNow.AddDays(30),
|
||||
ReasonCode = ExceptionReason.AcceptedRisk,
|
||||
Rationale = "This rationale is long enough to satisfy the minimum character requirement.",
|
||||
EvidenceRequirements = requirements
|
||||
};
|
||||
}
|
||||
|
||||
private sealed class StubHookRegistry(ImmutableArray<EvidenceHook> hooks) : IEvidenceHookRegistry
|
||||
{
|
||||
public Task<ImmutableArray<EvidenceHook>> GetRequiredHooksAsync(
|
||||
ExceptionType exceptionType,
|
||||
ExceptionScope scope,
|
||||
CancellationToken ct = default) => Task.FromResult(hooks);
|
||||
}
|
||||
|
||||
private sealed class StubAttestationVerifier(bool isValid) : IAttestationVerifier
|
||||
{
|
||||
public Task<EvidenceVerificationResult> VerifyAsync(string dsseEnvelope, CancellationToken ct = default) =>
|
||||
Task.FromResult(new EvidenceVerificationResult(isValid, isValid ? null : "invalid"));
|
||||
}
|
||||
|
||||
private sealed class StubTrustScoreService(decimal score) : ITrustScoreService
|
||||
{
|
||||
public Task<decimal> GetScoreAsync(string reference, CancellationToken ct = default) => Task.FromResult(score);
|
||||
}
|
||||
|
||||
private sealed class StubSchemaValidator(bool isValid) : IEvidenceSchemaValidator
|
||||
{
|
||||
public Task<EvidenceSchemaValidationResult> ValidateAsync(
|
||||
string schemaId,
|
||||
string? content,
|
||||
CancellationToken ct = default) =>
|
||||
Task.FromResult(new EvidenceSchemaValidationResult(isValid, isValid ? null : "schema invalid"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user