Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -9,6 +9,7 @@ using FluentAssertions;
|
||||
using StellaOps.Concelier.Interest.Models;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Interest.Tests;
|
||||
|
||||
public class InterestScoreCalculatorTests
|
||||
@@ -21,7 +22,8 @@ public class InterestScoreCalculatorTests
|
||||
_calculator = new InterestScoreCalculator(_defaultWeights);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithNoSignals_ReturnsBaseScore()
|
||||
{
|
||||
// Arrange
|
||||
@@ -43,7 +45,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithSbomMatch_AddsInSbomFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -72,7 +75,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithReachableSbomMatch_AddsReachableFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -102,7 +106,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithDeployedSbomMatch_AddsDeployedFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -132,7 +137,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithFullSbomMatch_AddsAllSbomFactors()
|
||||
{
|
||||
// Arrange
|
||||
@@ -163,7 +169,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithVexNotAffected_ExcludesVexFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -203,7 +210,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().NotContain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithRecentLastSeen_AddsRecentFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -233,7 +241,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("recent");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithOldLastSeen_DecaysRecentFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -263,7 +272,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().NotContain("recent"); // decayFactor < 0.5
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_WithVeryOldLastSeen_NoRecentFactor()
|
||||
{
|
||||
// Arrange
|
||||
@@ -284,7 +294,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().NotContain("recent");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_MaxScore_IsCappedAt1()
|
||||
{
|
||||
// Arrange - use custom weights that exceed 1.0
|
||||
@@ -322,7 +333,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Score.Should().Be(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_SetsComputedAtToNow()
|
||||
{
|
||||
// Arrange
|
||||
@@ -338,7 +350,8 @@ public class InterestScoreCalculatorTests
|
||||
result.ComputedAt.Should().BeOnOrBefore(after);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Calculate_PreservesCanonicalId()
|
||||
{
|
||||
// Arrange
|
||||
@@ -352,7 +365,8 @@ public class InterestScoreCalculatorTests
|
||||
result.CanonicalId.Should().Be(canonicalId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData(VexStatus.Affected)]
|
||||
[InlineData(VexStatus.Fixed)]
|
||||
[InlineData(VexStatus.UnderInvestigation)]
|
||||
@@ -379,7 +393,8 @@ public class InterestScoreCalculatorTests
|
||||
result.Reasons.Should().Contain("no_vex_na");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void InterestTier_HighScore_ReturnsHigh()
|
||||
{
|
||||
// Arrange
|
||||
@@ -395,7 +410,8 @@ public class InterestScoreCalculatorTests
|
||||
score.Tier.Should().Be(InterestTier.High);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void InterestTier_MediumScore_ReturnsMedium()
|
||||
{
|
||||
// Arrange
|
||||
@@ -411,7 +427,8 @@ public class InterestScoreCalculatorTests
|
||||
score.Tier.Should().Be(InterestTier.Medium);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void InterestTier_LowScore_ReturnsLow()
|
||||
{
|
||||
// Arrange
|
||||
@@ -427,7 +444,8 @@ public class InterestScoreCalculatorTests
|
||||
score.Tier.Should().Be(InterestTier.Low);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void InterestTier_NoneScore_ReturnsNone()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -13,6 +13,7 @@ using Moq;
|
||||
using StellaOps.Concelier.Interest.Models;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Interest.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -57,7 +58,8 @@ public class InterestScoringServiceTests
|
||||
|
||||
#region Task 18: Integration Tests - Score Persistence
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpdateScoreAsync_PersistsToRepository()
|
||||
{
|
||||
// Arrange
|
||||
@@ -72,7 +74,8 @@ public class InterestScoringServiceTests
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetScoreAsync_RetrievesFromRepository()
|
||||
{
|
||||
// Arrange
|
||||
@@ -92,7 +95,8 @@ public class InterestScoringServiceTests
|
||||
result.Score.Should().Be(0.5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetScoreAsync_ReturnsNull_WhenNotFound()
|
||||
{
|
||||
// Arrange
|
||||
@@ -107,7 +111,8 @@ public class InterestScoringServiceTests
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BatchUpdateAsync_UpdatesMultipleScores()
|
||||
{
|
||||
// Arrange
|
||||
@@ -122,7 +127,8 @@ public class InterestScoringServiceTests
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BatchUpdateAsync_HandlesEmptyInput()
|
||||
{
|
||||
// Act
|
||||
@@ -138,7 +144,8 @@ public class InterestScoringServiceTests
|
||||
|
||||
#region Task 23: Job Execution and Score Consistency
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RecalculateAllAsync_ReturnsZero_WhenNoAdvisoryStore()
|
||||
{
|
||||
// The service is created without an ICanonicalAdvisoryStore,
|
||||
@@ -152,7 +159,8 @@ public class InterestScoringServiceTests
|
||||
result.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ComputeScoreAsync_ProducesDeterministicResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -167,7 +175,8 @@ public class InterestScoringServiceTests
|
||||
result1.Reasons.Should().BeEquivalentTo(result2.Reasons);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ComputeScoreAsync_ReturnsValidScoreRange()
|
||||
{
|
||||
// Arrange
|
||||
@@ -182,7 +191,8 @@ public class InterestScoringServiceTests
|
||||
result.ComputedAt.Should().BeCloseTo(DateTimeOffset.UtcNow, TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpdateScoreAsync_PreservesScoreConsistency()
|
||||
{
|
||||
// Arrange
|
||||
@@ -206,7 +216,8 @@ public class InterestScoringServiceTests
|
||||
savedScore.Reasons.Should().BeEquivalentTo(["in_sbom", "reachable"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BatchUpdateAsync_MaintainsScoreOrdering()
|
||||
{
|
||||
// Arrange
|
||||
@@ -232,7 +243,8 @@ public class InterestScoringServiceTests
|
||||
|
||||
#region Task 28: Degradation/Restoration Cycle
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DegradeToStubsAsync_ReturnsZero_WhenNoAdvisoryStore()
|
||||
{
|
||||
// The service is created without an ICanonicalAdvisoryStore,
|
||||
@@ -246,7 +258,8 @@ public class InterestScoringServiceTests
|
||||
result.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RestoreFromStubsAsync_ReturnsZero_WhenNoAdvisoryStore()
|
||||
{
|
||||
// The service is created without an ICanonicalAdvisoryStore,
|
||||
@@ -259,7 +272,8 @@ public class InterestScoringServiceTests
|
||||
result.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DegradeRestoreCycle_MaintainsDataIntegrity()
|
||||
{
|
||||
// Arrange
|
||||
@@ -293,7 +307,8 @@ public class InterestScoringServiceTests
|
||||
stored.Reasons.Should().Contain("in_sbom");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DegradeToStubsAsync_ReturnsZero_WhenNoLowScores()
|
||||
{
|
||||
// Arrange
|
||||
@@ -312,7 +327,8 @@ public class InterestScoringServiceTests
|
||||
result.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RestoreFromStubsAsync_ReturnsZero_WhenNoHighScores()
|
||||
{
|
||||
// Arrange
|
||||
@@ -334,7 +350,8 @@ public class InterestScoringServiceTests
|
||||
|
||||
#region Edge Cases
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpdateScoreAsync_HandlesBoundaryScores()
|
||||
{
|
||||
// Arrange
|
||||
@@ -350,7 +367,8 @@ public class InterestScoringServiceTests
|
||||
Times.Exactly(2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ComputeScoreAsync_HandlesNullInputGracefully()
|
||||
{
|
||||
// Act
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user