Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -6,11 +6,13 @@ using StellaOps.Findings.Ledger.Infrastructure.Merkle;
|
||||
using StellaOps.Findings.Ledger.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class AirgapAndOrchestratorServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AirgapImportService_AppendsLedgerEvent_AndPersistsRecord()
|
||||
{
|
||||
var ledgerRepo = new InMemoryLedgerEventRepository();
|
||||
@@ -38,7 +40,8 @@ public sealed class AirgapAndOrchestratorServiceTests
|
||||
Assert.Equal(input.MirrorGeneration, store.LastRecord.MirrorGeneration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task OrchestratorExportService_ComputesMerkleRoot()
|
||||
{
|
||||
var repo = new InMemoryOrchestratorExportRepository();
|
||||
|
||||
@@ -14,6 +14,8 @@ using StellaOps.Findings.Ledger.Core.Events;
|
||||
using StellaOps.Findings.Ledger.Core.Projection;
|
||||
using StellaOps.Findings.Ledger.Core.Repositories;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -24,7 +26,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
{
|
||||
#region FINDINGS-5100-005: Event Stream → Ledger State → Replay → Verify Identical
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EventStream_ToLedgerState_Replay_ProducesIdenticalState()
|
||||
{
|
||||
// Arrange
|
||||
@@ -90,7 +93,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
firstProjection.LastEventTimestamp.Should().Be(secondProjection.LastEventTimestamp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EventStream_WithSameEvents_ProducesSameStateHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -119,7 +123,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
projection1.CycleHash.Should().Be(projection2.CycleHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EventStream_DifferentEvents_ProducesDifferentStateHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -149,7 +154,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
projection1.CycleHash.Should().NotBe(projection2.CycleHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReplayMultipleTimes_AlwaysProducesIdenticalState()
|
||||
{
|
||||
// Arrange
|
||||
@@ -177,7 +183,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
projections.Should().AllSatisfy(p => p.CycleHash.Should().Be(firstHash));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EventStream_AfterAppendingMore_StateUpdatesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
@@ -231,7 +238,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
updatedProjection.LastEventTimestamp.Should().Be(now.AddMinutes(5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ConcurrentReplays_ProduceIdenticalResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -262,7 +270,8 @@ public sealed class FindingsLedgerIntegrationTests
|
||||
|
||||
#region Snapshot Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task LedgerState_AtPointInTime_IsReproducible()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -13,6 +13,8 @@ using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -40,7 +42,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region GET /api/v1/findings/{findingId}/summary
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummary_ValidId_Returns_Expected_Schema()
|
||||
{
|
||||
// Arrange
|
||||
@@ -65,7 +68,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummary_InvalidGuid_Returns_BadRequest()
|
||||
{
|
||||
// Arrange
|
||||
@@ -78,7 +82,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummary_NotFound_Returns_404()
|
||||
{
|
||||
// Arrange
|
||||
@@ -96,7 +101,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region GET /api/v1/findings/summaries (Paginated)
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummaries_Returns_Paginated_Schema()
|
||||
{
|
||||
// Arrange
|
||||
@@ -121,7 +127,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
root.TryGetProperty("pageSize", out _).Should().BeTrue("pageSize should be present");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummaries_With_Filters_Returns_Filtered_Results()
|
||||
{
|
||||
// Arrange
|
||||
@@ -135,7 +142,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummaries_PageSize_Clamped_To_100()
|
||||
{
|
||||
// Arrange
|
||||
@@ -159,7 +167,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region Auth Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummary_Without_Auth_Returns_Unauthorized()
|
||||
{
|
||||
// Arrange - No auth headers
|
||||
@@ -172,7 +181,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetFindingSummaries_Without_Auth_Returns_Unauthorized()
|
||||
{
|
||||
// Arrange - No auth headers
|
||||
@@ -189,7 +199,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region Evidence Graph Endpoints
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvidenceGraph_Endpoint_Exists()
|
||||
{
|
||||
// Arrange
|
||||
@@ -206,7 +217,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region Reachability Map Endpoints
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReachabilityMap_Endpoint_Exists()
|
||||
{
|
||||
// Arrange
|
||||
@@ -223,7 +235,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region Runtime Timeline Endpoints
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RuntimeTimeline_Endpoint_Exists()
|
||||
{
|
||||
// Arrange
|
||||
@@ -240,7 +253,8 @@ public sealed class FindingsLedgerWebServiceContractTests : IDisposable
|
||||
|
||||
#region Contract Schema Validation
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task FindingSummary_Schema_Has_Required_Fields()
|
||||
{
|
||||
// This test validates the FindingSummary contract has all expected fields
|
||||
|
||||
@@ -3,11 +3,13 @@ using StellaOps.Findings.Ledger.Domain;
|
||||
using StellaOps.Findings.Ledger.Hashing;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class ProjectionHashingTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ComputeCycleHash_IncludesRiskFields()
|
||||
{
|
||||
var projection = CreateProjection(riskScore: 5.5m, riskSeverity: "high");
|
||||
@@ -19,7 +21,8 @@ public sealed class ProjectionHashingTests
|
||||
Assert.NotEqual(hashWithRisk, hashChangedRisk);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ComputeCycleHash_ChangesWhenRiskExplanationChanges()
|
||||
{
|
||||
var projection = CreateProjection(riskExplanationId: Guid.NewGuid());
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../StellaOps.Findings.Ledger/StellaOps.Findings.Ledger.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="8.0.0" />
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Findings.Ledger.Infrastructure.Attestation;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class AttestationStatusCalculatorTests
|
||||
{
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData(0, 0, OverallVerificationStatus.NoAttestations)]
|
||||
[InlineData(3, 3, OverallVerificationStatus.AllVerified)]
|
||||
[InlineData(4, 1, OverallVerificationStatus.PartiallyVerified)]
|
||||
|
||||
@@ -2,11 +2,13 @@ using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using StellaOps.Findings.Ledger;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class DeprecationHeadersTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Apply_SetsStandardDeprecationHeaders()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
@@ -11,6 +11,7 @@ using StellaOps.Findings.Ledger.Services;
|
||||
using StellaOps.Findings.Ledger.Workflow;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class FindingWorkflowServiceTests
|
||||
@@ -49,7 +50,8 @@ public sealed class FindingWorkflowServiceTests
|
||||
NullLogger<FindingWorkflowService>.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AssignAsync_WritesLedgerEventWithAssigneeAndAttachments()
|
||||
{
|
||||
var request = new AssignWorkflowRequest
|
||||
@@ -95,7 +97,8 @@ public sealed class FindingWorkflowServiceTests
|
||||
attachmentNode["envelope"]!.AsObject()["algorithm"]!.GetValue<string>().Should().Be("AES-256-GCM");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AcceptRiskAsync_DefaultsStatusAndPersistsJustification()
|
||||
{
|
||||
var request = new AcceptRiskWorkflowRequest
|
||||
@@ -121,7 +124,8 @@ public sealed class FindingWorkflowServiceTests
|
||||
payload.TryGetPropertyValue("attachments", out _).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CommentAsync_ValidatesCommentPresence()
|
||||
{
|
||||
var request = new CommentWorkflowRequest
|
||||
|
||||
@@ -3,11 +3,14 @@ using LedgerReplayHarness;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class HarnessRunnerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task HarnessRunner_WritesReportAndValidatesHashes()
|
||||
{
|
||||
var fixturePath = Path.Combine(AppContext.BaseDirectory, "fixtures", "sample.ndjson");
|
||||
|
||||
@@ -7,13 +7,15 @@ using StellaOps.Findings.Ledger.Infrastructure.Policy;
|
||||
using StellaOps.Findings.Ledger.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class InlinePolicyEvaluationServiceTests
|
||||
{
|
||||
private readonly InlinePolicyEvaluationService _service = new(NullLogger<InlinePolicyEvaluationService>.Instance);
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_UsesPayloadValues_WhenPresent()
|
||||
{
|
||||
var payload = new JsonObject
|
||||
@@ -63,7 +65,8 @@ public sealed class InlinePolicyEvaluationServiceTests
|
||||
result.Rationale[1]!.GetValue<string>().Should().Be("policy://tenant/pol/version/rationale");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_FallsBack_WhenEventMissing()
|
||||
{
|
||||
var existingRationale = new JsonArray("explain://existing/rationale");
|
||||
|
||||
@@ -10,6 +10,7 @@ using StellaOps.Findings.Ledger.Infrastructure.Merkle;
|
||||
using StellaOps.Findings.Ledger.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class LedgerEventWriteServiceTests
|
||||
@@ -23,7 +24,8 @@ public sealed class LedgerEventWriteServiceTests
|
||||
_service = new LedgerEventWriteService(_repository, _scheduler, NullLogger<LedgerEventWriteService>.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AppendAsync_ComputesExpectedHashes()
|
||||
{
|
||||
var draft = CreateDraft();
|
||||
@@ -39,7 +41,8 @@ public sealed class LedgerEventWriteServiceTests
|
||||
result.Record.PreviousHash.Should().Be(LedgerEventConstants.EmptyHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AppendAsync_ReturnsConflict_WhenSequenceOutOfOrder()
|
||||
{
|
||||
var initial = CreateDraft();
|
||||
@@ -53,7 +56,8 @@ public sealed class LedgerEventWriteServiceTests
|
||||
result.Errors.Should().NotBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AppendAsync_ReturnsIdempotent_WhenExistingRecordMatches()
|
||||
{
|
||||
var draft = CreateDraft();
|
||||
|
||||
@@ -4,11 +4,14 @@ using FluentAssertions;
|
||||
using StellaOps.Findings.Ledger.Observability;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class LedgerMetricsTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ProjectionLagGauge_RecordsLatestPerTenant()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -32,7 +35,8 @@ public class LedgerMetricsTests
|
||||
.Should().Contain(new KeyValuePair<string, object?>("tenant", "tenant-a"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void MerkleAnchorDuration_EmitsHistogramMeasurement()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -54,7 +58,8 @@ public class LedgerMetricsTests
|
||||
.Should().Contain(new KeyValuePair<string, object?>("tenant", "tenant-b"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void MerkleAnchorFailure_IncrementsCounter()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -77,7 +82,8 @@ public class LedgerMetricsTests
|
||||
tags.Should().Contain(new KeyValuePair<string, object?>("reason", "persist_failure"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void AttachmentFailure_IncrementsCounter()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -100,7 +106,8 @@ public class LedgerMetricsTests
|
||||
tags.Should().Contain(new KeyValuePair<string, object?>("stage", "encrypt"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BacklogGauge_ReflectsOutstandingQueue()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -129,7 +136,8 @@ public class LedgerMetricsTests
|
||||
.Should().Contain(new KeyValuePair<string, object?>("tenant", "tenant-q"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ProjectionRebuildHistogram_RecordsScenarioTags()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -152,7 +160,8 @@ public class LedgerMetricsTests
|
||||
tags.Should().Contain(new KeyValuePair<string, object?>("scenario", "replay"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void DbConnectionsGauge_TracksRoleCounts()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
@@ -181,7 +190,8 @@ public class LedgerMetricsTests
|
||||
LedgerMetrics.DecrementDbConnection("writer");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VersionInfoGauge_EmitsConstantOne()
|
||||
{
|
||||
using var listener = CreateListener();
|
||||
|
||||
@@ -8,11 +8,13 @@ using StellaOps.Findings.Ledger.Infrastructure.Policy;
|
||||
using StellaOps.Findings.Ledger.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class LedgerProjectionReducerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Reduce_WhenFindingCreated_InitialisesProjection()
|
||||
{
|
||||
var payload = new JsonObject
|
||||
@@ -58,7 +60,8 @@ public sealed class LedgerProjectionReducerTests
|
||||
result.Action.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Reduce_StatusChange_ProducesHistoryAndAction()
|
||||
{
|
||||
var existing = new FindingProjection(
|
||||
@@ -111,7 +114,8 @@ public sealed class LedgerProjectionReducerTests
|
||||
result.Action.Payload["justification"]!.GetValue<string>().Should().Be("Approved by CISO");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Reduce_LabelUpdates_RemoveKeys()
|
||||
{
|
||||
var labels = new JsonObject
|
||||
|
||||
@@ -2,11 +2,13 @@ using System.Text;
|
||||
using FluentAssertions;
|
||||
using StellaOps.Findings.Ledger.OpenApi;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class OpenApiMetadataFactoryTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ComputeEtag_IsDeterministicAndWeak()
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes("spec-content");
|
||||
@@ -19,7 +21,8 @@ public class OpenApiMetadataFactoryTests
|
||||
etag1.Length.Should().BeGreaterThan(6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GetSpecPath_ResolvesExistingSpec()
|
||||
{
|
||||
var path = OpenApiMetadataFactory.GetSpecPath(AppContext.BaseDirectory);
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Text;
|
||||
using FluentAssertions;
|
||||
using StellaOps.Findings.Ledger.OpenApi;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class OpenApiSdkSurfaceTests
|
||||
@@ -14,7 +15,8 @@ public class OpenApiSdkSurfaceTests
|
||||
_specContent = File.ReadAllText(path, Encoding.UTF8);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingsEndpoints_ExposePaginationAndFilters()
|
||||
{
|
||||
_specContent.Should().Contain("/findings");
|
||||
@@ -22,14 +24,16 @@ public class OpenApiSdkSurfaceTests
|
||||
_specContent.Should().MatchRegex("nextPageToken|next_page_token");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EvidenceSchemas_ExposeEvidenceLinks()
|
||||
{
|
||||
_specContent.Should().Contain("evidenceBundleRef");
|
||||
_specContent.Should().Contain("ExportProvenance");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void AttestationPointers_ExposeProvenanceMetadata()
|
||||
{
|
||||
_specContent.Should().Contain("/v1/ledger/attestations");
|
||||
|
||||
@@ -8,6 +8,8 @@ using StellaOps.Findings.Ledger.Infrastructure.Policy;
|
||||
using StellaOps.Findings.Ledger.Options;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public sealed class PolicyEngineEvaluationServiceTests
|
||||
@@ -15,7 +17,8 @@ public sealed class PolicyEngineEvaluationServiceTests
|
||||
private const string TenantId = "tenant-1";
|
||||
private static readonly DateTimeOffset Now = DateTimeOffset.UtcNow;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_UsesPolicyEngineAndCachesResult()
|
||||
{
|
||||
var handler = new StubHttpHandler(_ => new HttpResponseMessage(HttpStatusCode.OK)
|
||||
@@ -59,7 +62,8 @@ public sealed class PolicyEngineEvaluationServiceTests
|
||||
Assert.Equal("policy://explain/123", second.Rationale[0]?.GetValue<string>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_FallsBackToInlineWhenRequestFails()
|
||||
{
|
||||
var handler = new StubHttpHandler(_ => new HttpResponseMessage(HttpStatusCode.InternalServerError));
|
||||
@@ -78,7 +82,8 @@ public sealed class PolicyEngineEvaluationServiceTests
|
||||
Assert.Equal(1, handler.CallCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_UsesInlineWhenNoBaseAddressConfigured()
|
||||
{
|
||||
var handler = new StubHttpHandler(_ => throw new InvalidOperationException("Handler should not be invoked."));
|
||||
|
||||
@@ -6,11 +6,13 @@ using StellaOps.Findings.Ledger.Infrastructure.Attestation;
|
||||
using StellaOps.Findings.Ledger.Services;
|
||||
using FluentAssertions;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Findings.Ledger.Tests;
|
||||
|
||||
public class ScoredFindingsQueryServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task QueryAsync_MapsAttestationMetadata()
|
||||
{
|
||||
var projection = new FindingProjection(
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\StellaOps.Findings.Ledger\StellaOps.Findings.Ledger.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Findings.Ledger.WebService\StellaOps.Findings.Ledger.WebService.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0-preview.3.25171.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
Reference in New Issue
Block a user