Refactor code structure and optimize performance across multiple modules

This commit is contained in:
StellaOps Bot
2025-12-26 20:03:22 +02:00
parent c786faae84
commit b4fc66feb6
3353 changed files with 88254 additions and 1590657 deletions

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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());

View File

@@ -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" />

View File

@@ -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)]

View File

@@ -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();

View File

@@ -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

View File

@@ -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");

View File

@@ -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");

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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");

View File

@@ -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."));

View File

@@ -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(

View File

@@ -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>