Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
using Xunit;
|
||||
using StellaOps.Policy.Engine.AdvisoryAI;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class AdvisoryAiKnobsServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Get_ReturnsDefaultsWithHash()
|
||||
{
|
||||
var service = new AdvisoryAiKnobsService(TimeProvider.System);
|
||||
@@ -15,7 +17,8 @@ public sealed class AdvisoryAiKnobsServiceTests
|
||||
Assert.False(string.IsNullOrWhiteSpace(profile.ProfileHash));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Set_NormalizesOrdering()
|
||||
{
|
||||
var service = new AdvisoryAiKnobsService(TimeProvider.System);
|
||||
|
||||
@@ -2,11 +2,13 @@ using Xunit;
|
||||
using StellaOps.Policy.Engine.Domain;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class EvidenceSummaryServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Summarize_BuildsDeterministicSummary()
|
||||
{
|
||||
var timeProvider = new FixedTimeProvider(new DateTimeOffset(2025, 11, 26, 0, 0, 0, TimeSpan.Zero));
|
||||
@@ -33,7 +35,8 @@ public sealed class EvidenceSummaryServiceTests
|
||||
response.Summary.Signals);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Summarize_RequiresEvidenceHash()
|
||||
{
|
||||
var timeProvider = new FixedTimeProvider(DateTimeOffset.UnixEpoch);
|
||||
|
||||
@@ -3,11 +3,13 @@ using Microsoft.Extensions.Time.Testing;
|
||||
using StellaOps.Policy.Engine.Ledger;
|
||||
using StellaOps.Policy.Engine.Orchestration;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class LedgerExportServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildAsync_ProducesOrderedNdjson()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T15:00:00Z"));
|
||||
|
||||
@@ -2,11 +2,13 @@ using Xunit;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using StellaOps.Policy.Engine.Orchestration;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class OrchestratorJobServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SubmitAsync_NormalizesOrderingAndHashes()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T10:00:00Z"));
|
||||
@@ -39,7 +41,8 @@ public sealed class OrchestratorJobServiceTests
|
||||
Assert.False(string.IsNullOrWhiteSpace(job.DeterminismHash));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SubmitAsync_IsDeterministicAcrossOrdering()
|
||||
{
|
||||
var requestedAt = DateTimeOffset.Parse("2025-11-24T11:00:00Z");
|
||||
@@ -75,7 +78,8 @@ public sealed class OrchestratorJobServiceTests
|
||||
Assert.Equal(first.DeterminismHash, second.DeterminismHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Preview_DoesNotPersist()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T12:00:00Z"));
|
||||
|
||||
@@ -4,11 +4,13 @@ using StellaOps.Policy.Engine.Overlay;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using StellaOps.Policy.Engine.Streaming;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class OverlayProjectionServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildSnapshotAsync_ProducesHeaderAndSortedProjections()
|
||||
{
|
||||
var service = new OverlayProjectionService(new PolicyEvaluationService(), TimeProvider.System);
|
||||
|
||||
@@ -6,13 +6,15 @@ using StellaOps.Policy.Engine.Tests.Fakes;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using StellaOps.Policy.Engine.Streaming;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PathScopeSimulationBridgeServiceTests
|
||||
{
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SimulateAsync_OrdersByInputAndProducesMetrics()
|
||||
{
|
||||
var bridge = CreateBridge();
|
||||
@@ -37,7 +39,8 @@ public sealed class PathScopeSimulationBridgeServiceTests
|
||||
Assert.Equal(2, result.Metrics.Evaluated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SimulateAsync_WhatIfProducesDeltas()
|
||||
{
|
||||
var bridge = CreateBridge();
|
||||
@@ -57,7 +60,8 @@ public sealed class PathScopeSimulationBridgeServiceTests
|
||||
Assert.Single(result.Deltas!);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SimulateAsync_PublishesEventsAndSavesOverlays()
|
||||
{
|
||||
var sink = new FakeOverlayEventSink();
|
||||
|
||||
@@ -3,11 +3,13 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Policy.Engine.Streaming;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PathScopeSimulationServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StreamAsync_ReturnsDeterministicOrdering()
|
||||
{
|
||||
var service = new PathScopeSimulationService();
|
||||
@@ -32,7 +34,8 @@ public sealed class PathScopeSimulationServiceTests
|
||||
Assert.Contains("\"filePath\":\"b/file.js\"", lines[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StreamAsync_ThrowsOnMissingTarget()
|
||||
{
|
||||
var service = new PathScopeSimulationService();
|
||||
|
||||
@@ -6,11 +6,13 @@ using StellaOps.Policy.Engine.Options;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public class PolicyActivationAuditorTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RecordActivation_WhenDisabled_DoesNothing()
|
||||
{
|
||||
var options = new PolicyEngineOptions();
|
||||
@@ -24,7 +26,8 @@ public class PolicyActivationAuditorTests
|
||||
Assert.Empty(logger.Entries);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RecordActivation_WhenEnabled_WritesScopedLog()
|
||||
{
|
||||
var options = new PolicyEngineOptions();
|
||||
|
||||
@@ -2,11 +2,13 @@ using StellaOps.Policy.Engine.Options;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public class PolicyActivationSettingsTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ResolveRequirement_WhenForceEnabled_IgnoresRequest()
|
||||
{
|
||||
var options = new PolicyEngineOptions();
|
||||
@@ -17,7 +19,8 @@ public class PolicyActivationSettingsTests
|
||||
Assert.True(settings.ResolveRequirement(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ResolveRequirement_UsesRequestedValue_WhenProvided()
|
||||
{
|
||||
var options = new PolicyEngineOptions();
|
||||
@@ -27,7 +30,8 @@ public class PolicyActivationSettingsTests
|
||||
Assert.False(settings.ResolveRequirement(false));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ResolveRequirement_FallsBackToDefault_WhenRequestMissing()
|
||||
{
|
||||
var options = new PolicyEngineOptions();
|
||||
|
||||
@@ -8,6 +8,7 @@ using StellaOps.Policy.Engine.Options;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using StellaOps.PolicyDsl;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyBundleServiceTests
|
||||
@@ -18,7 +19,8 @@ public sealed class PolicyBundleServiceTests
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_SucceedsAndStoresBundle()
|
||||
{
|
||||
var services = CreateServices();
|
||||
@@ -32,7 +34,8 @@ public sealed class PolicyBundleServiceTests
|
||||
Assert.True(response.SizeBytes > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_FailsWithBadSyntax()
|
||||
{
|
||||
var services = CreateServices();
|
||||
@@ -45,7 +48,8 @@ public sealed class PolicyBundleServiceTests
|
||||
Assert.NotEmpty(response.Diagnostics);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_ReturnsAocMetadata()
|
||||
{
|
||||
var services = CreateServices();
|
||||
@@ -63,7 +67,8 @@ public sealed class PolicyBundleServiceTests
|
||||
Assert.True(response.AocMetadata.ComplexityScore >= 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_IncludesProvenanceWhenProvided()
|
||||
{
|
||||
var services = CreateServices();
|
||||
@@ -95,7 +100,8 @@ public sealed class PolicyBundleServiceTests
|
||||
Assert.Equal("main", bundle.AocMetadata.Provenance.Branch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_NullAocMetadataOnFailure()
|
||||
{
|
||||
var services = CreateServices();
|
||||
@@ -107,7 +113,8 @@ public sealed class PolicyBundleServiceTests
|
||||
Assert.Null(response.AocMetadata);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CompileAndStoreAsync_SourceDigestIsDeterministic()
|
||||
{
|
||||
var services = CreateServices();
|
||||
|
||||
@@ -7,6 +7,7 @@ using StellaOps.Policy.Engine.Services;
|
||||
using StellaOps.PolicyDsl;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyCompilationServiceTests
|
||||
@@ -27,7 +28,8 @@ public sealed class PolicyCompilationServiceTests
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Compile_ReturnsComplexityReport_WhenWithinLimits()
|
||||
{
|
||||
var service = CreateService(maxComplexityScore: 1000, maxDurationMilliseconds: 1000, simulatedDurationMilliseconds: 12.3);
|
||||
@@ -44,7 +46,8 @@ public sealed class PolicyCompilationServiceTests
|
||||
Assert.True(result.Diagnostics.IsDefaultOrEmpty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Compile_Fails_WhenComplexityExceedsThreshold()
|
||||
{
|
||||
var service = CreateService(maxComplexityScore: 1, maxDurationMilliseconds: 1000, simulatedDurationMilliseconds: 2);
|
||||
@@ -60,7 +63,8 @@ public sealed class PolicyCompilationServiceTests
|
||||
Assert.Equal(PolicyIssueSeverity.Error, diagnostic.Severity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Compile_Fails_WhenDurationExceedsThreshold()
|
||||
{
|
||||
var service = CreateService(maxComplexityScore: 1000, maxDurationMilliseconds: 1, simulatedDurationMilliseconds: 5.2);
|
||||
|
||||
@@ -5,11 +5,13 @@ using StellaOps.PolicyDsl;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyCompilerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Compile_BaselinePolicy_Succeeds()
|
||||
{
|
||||
const string source = """
|
||||
@@ -79,7 +81,8 @@ public sealed class PolicyCompilerTests
|
||||
Assert.Equal("status", firstAction.Target[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Compile_MissingBecause_ReportsDiagnostic()
|
||||
{
|
||||
const string source = """
|
||||
|
||||
@@ -8,6 +8,7 @@ using StellaOps.Policy.Engine.Snapshots;
|
||||
using StellaOps.Policy.Engine.TrustWeighting;
|
||||
using StellaOps.Policy.Engine.Violations;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyDecisionServiceTests
|
||||
@@ -78,7 +79,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
return (decisionService, snapshot.SnapshotId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_ReturnsDecisionsWithEvidence()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -97,7 +99,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_BuildsSummaryStatistics()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -110,7 +113,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
Assert.NotEmpty(response.Summary.TopSeveritySources);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_FiltersById()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -124,7 +128,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
Assert.Equal("CVE-2021-44228", response.Decisions[0].AdvisoryId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_FiltersByTenant()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -137,7 +142,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
Assert.All(response.Decisions, d => Assert.Equal("acme", d.TenantId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_LimitsTopSources()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -153,7 +159,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_ExcludesEvidenceWhenNotRequested()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -166,7 +173,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
Assert.All(response.Decisions, d => Assert.Null(d.Evidence));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_ReturnsDeterministicOrder()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
@@ -180,7 +188,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
response2.Decisions.Select(d => d.ComponentPurl));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_ThrowsOnEmptySnapshotId()
|
||||
{
|
||||
var (service, _) = BuildService();
|
||||
@@ -189,7 +198,8 @@ public sealed class PolicyDecisionServiceTests
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => service.GetDecisionsAsync(request));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetDecisionsAsync_TopSourcesHaveRanks()
|
||||
{
|
||||
var (service, snapshotId) = BuildService();
|
||||
|
||||
@@ -15,6 +15,7 @@ using StellaOps.Policy.Unknowns.Services;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyEvaluatorTests
|
||||
@@ -81,7 +82,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
private readonly PolicyCompiler compiler = new();
|
||||
private readonly PolicyEvaluationService evaluationService = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_BlockCriticalRuleMatches()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -94,7 +96,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("blocked", result.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_EscalateAdjustsSeverity()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -108,7 +111,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("Critical", result.Severity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_VexOverrideSetsStatusAndAnnotation()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -127,7 +131,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("stmt-001", result.Annotations["winning_statement"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_WarnRuleEmitsWarning()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -145,7 +150,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Contains(result.Warnings, message => message.Contains("EOL", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_ExceptionSuppressesCriticalFinding()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -183,7 +189,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("suppressed", result.Annotations["exception.status"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_ExceptionDowngradesSeverity()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -223,7 +230,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("Medium", result.Annotations["exception.severity"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MoreSpecificExceptionWins()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -283,7 +291,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("alice", result.Annotations["exception.meta.requestedBy"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_RubyDevComponentBlocked()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -309,7 +318,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("blocked", result.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_RubyGitComponentWarns()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -337,7 +347,8 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
|
||||
Assert.Contains(result.Warnings, warning => warning.Contains("Git-sourced", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_UnknownBudgetExceeded_BlocksEvaluation()
|
||||
{
|
||||
var document = CompileBaseline();
|
||||
@@ -602,7 +613,8 @@ policy "macOS Security Policy" syntax "stella-dsl@1" {
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MacOs_UnsignedAppBlocked()
|
||||
{
|
||||
var document = compiler.Compile(MacOsPolicy);
|
||||
@@ -632,7 +644,8 @@ policy "macOS Security Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("blocked", result.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MacOs_SignedAppPasses()
|
||||
{
|
||||
var document = compiler.Compile(MacOsPolicy);
|
||||
@@ -660,7 +673,8 @@ policy "macOS Security Policy" syntax "stella-dsl@1" {
|
||||
Assert.False(result.Matched && result.Status == "blocked");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MacOs_HighRiskEntitlementsWarns()
|
||||
{
|
||||
var document = compiler.Compile(MacOsPolicy);
|
||||
@@ -693,7 +707,8 @@ policy "macOS Security Policy" syntax "stella-dsl@1" {
|
||||
Assert.Equal("warned", result.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MacOs_CategoryMatchesCameraAccess()
|
||||
{
|
||||
var document = compiler.Compile(MacOsPolicy);
|
||||
@@ -727,7 +742,8 @@ policy "macOS Security Policy" syntax "stella-dsl@1" {
|
||||
result.Status == "warned");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_MacOs_HardenedRuntimeWarnsWhenMissing()
|
||||
{
|
||||
var document = compiler.Compile(MacOsPolicy);
|
||||
|
||||
@@ -2,13 +2,15 @@ using StellaOps.Policy.Engine.Domain;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public class PolicyPackRepositoryTests
|
||||
{
|
||||
private readonly InMemoryPolicyPackRepository repository = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ActivateRevision_WithSingleApprover_ActivatesImmediately()
|
||||
{
|
||||
await repository.CreateAsync("pack-1", "Pack", CancellationToken.None);
|
||||
@@ -22,7 +24,8 @@ public class PolicyPackRepositoryTests
|
||||
Assert.Single(result.Revision.Approvals);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ActivateRevision_WithTwoPersonRequirement_ReturnsPendingUntilSecondApproval()
|
||||
{
|
||||
await repository.CreateAsync("pack-2", "Pack", CancellationToken.None);
|
||||
|
||||
@@ -12,6 +12,7 @@ using StellaOps.Policy.Engine.Signals.Entropy;
|
||||
using StellaOps.PolicyDsl;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
@@ -38,7 +39,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_ReturnsDecisionFromCompiledPolicy()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -55,7 +57,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.False(response.Cached);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_UsesCacheOnSecondCall()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -75,7 +78,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal(response1.CorrelationId, response2.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_BypassCacheWhenRequested()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -93,7 +97,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.False(response2.Cached);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_ThrowsOnMissingBundle()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -103,7 +108,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
() => harness.Service.EvaluateAsync(request, CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_GeneratesDeterministicCorrelationId()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -123,7 +129,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal(response1.CorrelationId, response2.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateBatchAsync_ReturnsMultipleResults()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -141,7 +148,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal(3, responses.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateBatchAsync_UsesCacheForDuplicates()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -164,7 +172,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Contains(responses, r => !r.Cached);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_DifferentContextsGetDifferentCacheKeys()
|
||||
{
|
||||
var harness = CreateHarness();
|
||||
@@ -183,7 +192,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.NotEqual(response1.CorrelationId, response2.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_EnrichesReachabilityFromFacts()
|
||||
{
|
||||
const string policy = """
|
||||
@@ -232,7 +242,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal("warn", response.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_GatesUnreachableWithoutEvidenceRef_ToUnderInvestigation()
|
||||
{
|
||||
const string policy = """
|
||||
@@ -286,7 +297,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal("under_investigation", response.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_GatesUnreachableWithLowConfidence_ToUnderInvestigation()
|
||||
{
|
||||
const string policy = """
|
||||
@@ -340,7 +352,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.Equal("under_investigation", response.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_AllowsUnreachableWithEvidenceRefAndHighConfidence()
|
||||
{
|
||||
const string policy = """
|
||||
|
||||
@@ -3,11 +3,13 @@ using System.Collections.Immutable;
|
||||
using StellaOps.Policy.Engine.Domain;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyRuntimeEvaluatorTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_ReturnsDeterministicDecisionAndCaches()
|
||||
{
|
||||
var repo = new InMemoryPolicyPackRepository();
|
||||
@@ -35,7 +37,8 @@ public sealed class PolicyRuntimeEvaluatorTests
|
||||
Assert.Equal(1, first.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_ThrowsWhenBundleMissing()
|
||||
{
|
||||
var evaluator = new PolicyRuntimeEvaluator(new InMemoryPolicyPackRepository());
|
||||
|
||||
@@ -2,11 +2,13 @@ using Xunit;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using StellaOps.Policy.Engine.Orchestration;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class PolicyWorkerServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_ReturnsDeterministicResults()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T13:00:00Z"));
|
||||
@@ -45,7 +47,8 @@ public sealed class PolicyWorkerServiceTests
|
||||
Assert.Equal(result.ResultHash, fetched!.ResultHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_IsIdempotentOnRetry()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T14:00:00Z"));
|
||||
|
||||
@@ -12,6 +12,7 @@ using StellaOps.Policy.Engine.Options;
|
||||
using StellaOps.Provcache;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -49,7 +50,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
NullLogger<ProvcachePolicyEvaluationCache>.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAsync_CacheHit_ReturnsEntry()
|
||||
{
|
||||
// Arrange
|
||||
@@ -69,7 +71,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
result.Source.Should().Be(CacheSource.Redis);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAsync_CacheMiss_ReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
@@ -88,7 +91,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
result.Source.Should().Be(CacheSource.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAsync_BypassHeader_SkipsCache()
|
||||
{
|
||||
// Arrange
|
||||
@@ -106,7 +110,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SetAsync_StoresEntryInProvcache()
|
||||
{
|
||||
// Arrange
|
||||
@@ -127,7 +132,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SetAsync_FailureDoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
@@ -142,7 +148,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
await _cache.SetAsync(key, entry);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task InvalidateAsync_CallsProvcache()
|
||||
{
|
||||
// Arrange
|
||||
@@ -161,7 +168,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task InvalidateByPolicyDigestAsync_InvalidatesAllMatchingEntries()
|
||||
{
|
||||
// Arrange
|
||||
@@ -194,7 +202,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetBatchAsync_ProcessesAllKeys()
|
||||
{
|
||||
// Arrange
|
||||
@@ -224,7 +233,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
result.NotFound.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GetStats_ReturnsAccumulatedStatistics()
|
||||
{
|
||||
// Act
|
||||
@@ -235,7 +245,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
stats.TotalRequests.Should().BeGreaterThanOrEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAsync_WhenProvcacheThrows_TreatsAsMiss()
|
||||
{
|
||||
// Arrange
|
||||
@@ -253,7 +264,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
result.Entry.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VeriKey_Construction_IsDeterministic()
|
||||
{
|
||||
// Arrange
|
||||
@@ -334,7 +346,8 @@ public sealed class ProvcachePolicyEvaluationCacheTests
|
||||
/// </summary>
|
||||
public sealed class CacheBypassAccessorTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void HttpCacheBypassAccessor_NoHeader_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
@@ -348,7 +361,8 @@ public sealed class CacheBypassAccessorTests
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void HttpCacheBypassAccessor_BypassHeaderTrue_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
@@ -363,7 +377,8 @@ public sealed class CacheBypassAccessorTests
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void HttpCacheBypassAccessor_BypassHeaderFalse_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
@@ -378,7 +393,8 @@ public sealed class CacheBypassAccessorTests
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void HttpCacheBypassAccessor_RefreshHeaderTrue_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
@@ -393,7 +409,8 @@ public sealed class CacheBypassAccessorTests
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void HttpCacheBypassAccessor_BypassDisabledInOptions_AlwaysReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
@@ -408,7 +425,8 @@ public sealed class CacheBypassAccessorTests
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void NullCacheBypassAccessor_AlwaysReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -4,11 +4,13 @@ using StellaOps.Policy.Engine.Ledger;
|
||||
using StellaOps.Policy.Engine.Orchestration;
|
||||
using StellaOps.Policy.Engine.Snapshots;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class SnapshotServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAsync_ProducesSnapshotFromLedger()
|
||||
{
|
||||
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T16:00:00Z"));
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using Xunit;
|
||||
using StellaOps.Policy.Engine.TrustWeighting;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class TrustWeightingServiceTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Get_ReturnsDefaultsWithHash()
|
||||
{
|
||||
var service = new TrustWeightingService(TimeProvider.System);
|
||||
@@ -16,7 +18,8 @@ public sealed class TrustWeightingServiceTests
|
||||
Assert.False(string.IsNullOrWhiteSpace(profile.ProfileHash));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Set_NormalizesOrderingAndScale()
|
||||
{
|
||||
var service = new TrustWeightingService(TimeProvider.System);
|
||||
|
||||
@@ -6,6 +6,7 @@ using StellaOps.Policy.Engine.Snapshots;
|
||||
using StellaOps.Policy.Engine.TrustWeighting;
|
||||
using StellaOps.Policy.Engine.Violations;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Policy.Engine.Tests;
|
||||
|
||||
public sealed class ViolationServicesTests
|
||||
@@ -62,7 +63,8 @@ public sealed class ViolationServicesTests
|
||||
return (eventService, fusionService, conflictService, snapshot.SnapshotId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task EmitAsync_BuildsEvents()
|
||||
{
|
||||
var (eventService, _, _, snapshotId) = BuildPipeline();
|
||||
@@ -73,7 +75,8 @@ public sealed class ViolationServicesTests
|
||||
Assert.All(events, e => Assert.Equal("policy.violation.detected", e.ViolationCode));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task FuseAsync_ProducesWeightedSeverity()
|
||||
{
|
||||
var (eventService, fusionService, _, snapshotId) = BuildPipeline();
|
||||
@@ -85,7 +88,8 @@ public sealed class ViolationServicesTests
|
||||
Assert.All(fused, f => Assert.False(string.IsNullOrWhiteSpace(f.SeverityFused)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ConflictsAsync_DetectsDivergentSeverities()
|
||||
{
|
||||
var (eventService, fusionService, conflictService, snapshotId) = BuildPipeline();
|
||||
|
||||
Reference in New Issue
Block a user