Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -11,6 +11,7 @@ using StellaOps.Scanner.Triage.Entities;
|
||||
using StellaOps.Scanner.WebService.Contracts;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -22,7 +23,8 @@ public sealed class GatingReasonServiceTests
|
||||
{
|
||||
#region GTR-9200-019: Gating Reason Path Tests - Entity Model Validation
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData(GatingReason.None, false)]
|
||||
[InlineData(GatingReason.Unreachable, true)]
|
||||
[InlineData(GatingReason.PolicyDismissed, true)]
|
||||
@@ -44,7 +46,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.IsHiddenByDefault.Should().Be(expectedHidden);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_UserMuted_HasExpectedExplanation()
|
||||
{
|
||||
// Arrange
|
||||
@@ -62,7 +65,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.WouldShowIf.Should().Contain("Un-mute the finding in triage settings");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_PolicyDismissed_HasPolicyIdInExplanation()
|
||||
{
|
||||
// Arrange
|
||||
@@ -80,7 +84,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.WouldShowIf.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_VexNotAffected_IncludesTrustInfo()
|
||||
{
|
||||
// Arrange
|
||||
@@ -97,7 +102,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatingExplanation.Should().Contain("trust");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_Backported_IncludesFixedVersion()
|
||||
{
|
||||
// Arrange
|
||||
@@ -114,7 +120,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatingExplanation.Should().Contain(fixedVersion);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_Superseded_IncludesSupersedingCve()
|
||||
{
|
||||
// Arrange
|
||||
@@ -131,7 +138,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatingExplanation.Should().Contain(supersedingCve);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_Unreachable_HasSubgraphId()
|
||||
{
|
||||
// Arrange
|
||||
@@ -150,7 +158,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatingExplanation.Should().Contain("not reachable");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingGatingStatusDto_None_IsNotHidden()
|
||||
{
|
||||
// Arrange
|
||||
@@ -170,7 +179,8 @@ public sealed class GatingReasonServiceTests
|
||||
|
||||
#region GTR-9200-020: Bucket Counting Logic Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GatedBucketsSummaryDto_Empty_ReturnsZeroCounts()
|
||||
{
|
||||
// Arrange & Act
|
||||
@@ -186,7 +196,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.TotalHiddenCount.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GatedBucketsSummaryDto_TotalHiddenCount_SumsAllBuckets()
|
||||
{
|
||||
// Arrange
|
||||
@@ -204,7 +215,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.TotalHiddenCount.Should().Be(28);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GatedBucketsSummaryDto_WithMixedCounts_CalculatesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
@@ -224,7 +236,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.VexNotAffectedCount.Should().Be(12);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BulkTriageQueryWithGatingResponseDto_IncludesGatedBuckets()
|
||||
{
|
||||
// Arrange
|
||||
@@ -249,7 +262,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatedBuckets!.TotalHiddenCount.Should().Be(28);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BulkTriageQueryWithGatingRequestDto_SupportsGatingReasonFilter()
|
||||
{
|
||||
// Arrange
|
||||
@@ -267,7 +281,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.GatingReasonFilter.Should().Contain(GatingReason.VexNotAffected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BulkTriageQueryWithGatingRequestDto_DefaultsToNotIncludeHidden()
|
||||
{
|
||||
// Arrange
|
||||
@@ -285,7 +300,8 @@ public sealed class GatingReasonServiceTests
|
||||
|
||||
#region GTR-9200-021: VEX Trust Threshold Comparison Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexTrustBreakdownDto_AllComponents_SumToCompositeScore()
|
||||
{
|
||||
// Arrange - weights: issuer=0.4, recency=0.2, justification=0.2, evidence=0.2
|
||||
@@ -305,7 +321,8 @@ public sealed class GatingReasonServiceTests
|
||||
compositeScore.Should().Be(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexTrustBreakdownDto_LowIssuerTrust_ReducesCompositeScore()
|
||||
{
|
||||
// Arrange - unknown issuer has low trust (0.5)
|
||||
@@ -325,7 +342,8 @@ public sealed class GatingReasonServiceTests
|
||||
compositeScore.Should().Be(0.8);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageVexTrustStatusDto_MeetsPolicyThreshold_WhenTrustExceedsThreshold()
|
||||
{
|
||||
// Arrange
|
||||
@@ -344,7 +362,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.MeetsPolicyThreshold.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageVexTrustStatusDto_DoesNotMeetThreshold_WhenTrustBelowThreshold()
|
||||
{
|
||||
// Arrange
|
||||
@@ -363,7 +382,8 @@ public sealed class GatingReasonServiceTests
|
||||
dto.MeetsPolicyThreshold.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("nvd", 1.0)]
|
||||
[InlineData("redhat", 0.95)]
|
||||
[InlineData("canonical", 0.95)]
|
||||
@@ -377,7 +397,8 @@ public sealed class GatingReasonServiceTests
|
||||
expectedTrust.Should().BeGreaterOrEqualTo(0.9);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexRecencyTrust_RecentStatement_HasHighTrust()
|
||||
{
|
||||
// Arrange - VEX from within a week
|
||||
@@ -388,7 +409,8 @@ public sealed class GatingReasonServiceTests
|
||||
age.TotalDays.Should().BeLessThan(7);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexRecencyTrust_OldStatement_HasLowTrust()
|
||||
{
|
||||
// Arrange - VEX from over a year ago
|
||||
@@ -399,7 +421,8 @@ public sealed class GatingReasonServiceTests
|
||||
age.TotalDays.Should().BeGreaterThan(365);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexJustificationTrust_DetailedJustification_HasHighTrust()
|
||||
{
|
||||
// Arrange - 500+ chars = trust 1.0
|
||||
@@ -409,7 +432,8 @@ public sealed class GatingReasonServiceTests
|
||||
justification.Length.Should().BeGreaterOrEqualTo(500);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexJustificationTrust_ShortJustification_HasLowTrust()
|
||||
{
|
||||
// Arrange - < 50 chars = trust 0.4
|
||||
@@ -419,7 +443,8 @@ public sealed class GatingReasonServiceTests
|
||||
justification.Length.Should().BeLessThan(50);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexEvidenceTrust_SignedWithLedger_HasHighTrust()
|
||||
{
|
||||
// Arrange - DSSE envelope + signature ref + source ref
|
||||
@@ -439,7 +464,8 @@ public sealed class GatingReasonServiceTests
|
||||
vex.SourceRef.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexEvidenceTrust_NoEvidence_HasBaseTrust()
|
||||
{
|
||||
// Arrange - no signature, no ledger, no source
|
||||
@@ -462,7 +488,8 @@ public sealed class GatingReasonServiceTests
|
||||
|
||||
#region Edge Cases and Entity Model Validation
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageFinding_RequiredFields_AreSet()
|
||||
{
|
||||
// Arrange
|
||||
@@ -479,7 +506,8 @@ public sealed class GatingReasonServiceTests
|
||||
finding.Purl.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriagePolicyDecision_PolicyActions_AreValid()
|
||||
{
|
||||
// Valid actions: dismiss, waive, tolerate, block
|
||||
@@ -498,7 +526,8 @@ public sealed class GatingReasonServiceTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageEffectiveVex_VexStatuses_AreAllDefined()
|
||||
{
|
||||
// Arrange
|
||||
@@ -510,7 +539,8 @@ public sealed class GatingReasonServiceTests
|
||||
statuses.Should().Contain(TriageVexStatus.UnderInvestigation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageReachability_Values_AreAllDefined()
|
||||
{
|
||||
// Arrange
|
||||
@@ -522,7 +552,8 @@ public sealed class GatingReasonServiceTests
|
||||
values.Should().Contain(TriageReachability.Unknown);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TriageReachabilityResult_RequiredInputsHash_IsSet()
|
||||
{
|
||||
// Arrange
|
||||
@@ -538,7 +569,8 @@ public sealed class GatingReasonServiceTests
|
||||
result.InputsHash.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GatingReason_AllValues_HaveCorrectNumericMapping()
|
||||
{
|
||||
// Document the enum values for API stability
|
||||
@@ -551,7 +583,8 @@ public sealed class GatingReasonServiceTests
|
||||
GatingReason.UserMuted.Should().Be((GatingReason)6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FindingTriageStatusWithGatingDto_CombinesBaseStatusWithGating()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
Reference in New Issue
Block a user