using System; using FluentAssertions; using StellaOps.Concelier.Merge.Services; using StellaOps.Concelier.Models; using Xunit; using StellaOps.TestKit; namespace StellaOps.Concelier.Merge.Tests; public sealed class AffectedPackagePrecedenceResolverTests { [Trait("Category", TestCategories.Unit)] [Fact] public void Merge_PrefersRedHatOverNvdForSameCpe() { var redHat = new AffectedPackage( type: AffectedPackageTypes.Cpe, identifier: "cpe:2.3:o:redhat:enterprise_linux:9:*:*:*:*:*:*:*", platform: "RHEL 9", versionRanges: Array.Empty(), statuses: new[] { new AffectedPackageStatus( status: "known_affected", provenance: new AdvisoryProvenance("redhat", "oval", "RHEL-9", DateTimeOffset.Parse("2025-10-01T00:00:00Z"))) }, provenance: new[] { new AdvisoryProvenance("redhat", "oval", "RHEL-9", DateTimeOffset.Parse("2025-10-01T00:00:00Z")) }); var nvd = new AffectedPackage( type: AffectedPackageTypes.Cpe, identifier: "cpe:2.3:o:redhat:enterprise_linux:9:*:*:*:*:*:*:*", platform: "RHEL 9", versionRanges: new[] { new AffectedVersionRange( rangeKind: "cpe", introducedVersion: null, fixedVersion: null, lastAffectedVersion: null, rangeExpression: "<=9.0", provenance: new AdvisoryProvenance("nvd", "cpe_match", "RHEL-9", DateTimeOffset.Parse("2025-09-30T00:00:00Z"))) }, provenance: new[] { new AdvisoryProvenance("nvd", "cpe_match", "RHEL-9", DateTimeOffset.Parse("2025-09-30T00:00:00Z")) }); var resolver = new AffectedPackagePrecedenceResolver(); var result = resolver.Merge(new[] { nvd, redHat }); var package = Assert.Single(result.Packages); Assert.Equal("cpe:2.3:o:redhat:enterprise_linux:9:*:*:*:*:*:*:*", package.Identifier); Assert.Empty(package.VersionRanges); // NVD range overridden Assert.Contains(package.Statuses, status => status.Status == "known_affected"); Assert.Contains(package.Provenance, provenance => provenance.Source == "redhat"); Assert.Contains(package.Provenance, provenance => provenance.Source == "nvd"); var rangeOverride = Assert.Single(result.Overrides); Assert.Equal("cpe:2.3:o:redhat:enterprise_linux:9:*:*:*:*:*:*:*", rangeOverride.Identifier); Assert.Equal(0, rangeOverride.PrimaryRank); Assert.True(rangeOverride.SuppressedRank >= rangeOverride.PrimaryRank); Assert.Equal(0, rangeOverride.PrimaryRangeCount); Assert.Equal(1, rangeOverride.SuppressedRangeCount); } [Trait("Category", TestCategories.Unit)] [Fact] public void Merge_KeepsNvdWhenNoHigherPrecedence() { var nvd = new AffectedPackage( type: AffectedPackageTypes.Cpe, identifier: "cpe:2.3:a:example:product:1.0:*:*:*:*:*:*:*", platform: null, versionRanges: new[] { new AffectedVersionRange( rangeKind: "semver", introducedVersion: null, fixedVersion: "1.0.1", lastAffectedVersion: null, rangeExpression: "<1.0.1", provenance: new AdvisoryProvenance("nvd", "cpe_match", "product", DateTimeOffset.Parse("2025-09-01T00:00:00Z"))) }, provenance: new[] { new AdvisoryProvenance("nvd", "cpe_match", "product", DateTimeOffset.Parse("2025-09-01T00:00:00Z")) }); var resolver = new AffectedPackagePrecedenceResolver(); var result = resolver.Merge(new[] { nvd }); var package = Assert.Single(result.Packages); Assert.Equal(nvd.Identifier, package.Identifier); Assert.Equal(nvd.VersionRanges.Single().RangeExpression, package.VersionRanges.Single().RangeExpression); Assert.Equal("nvd", package.Provenance.Single().Source); Assert.Empty(result.Overrides); } }