Restructure solution layout by module
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using StellaOps.Concelier.Merge.Identity;
|
||||
using StellaOps.Concelier.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Concelier.Merge.Tests;
|
||||
|
||||
public sealed class AdvisoryIdentityResolverTests
|
||||
{
|
||||
private readonly AdvisoryIdentityResolver _resolver = new();
|
||||
|
||||
[Fact]
|
||||
public void Resolve_GroupsBySharedCveAlias()
|
||||
{
|
||||
var nvd = CreateAdvisory("CVE-2025-1234", aliases: new[] { "CVE-2025-1234" }, source: "nvd");
|
||||
var vendor = CreateAdvisory("VSA-2025-01", aliases: new[] { "CVE-2025-1234", "VSA-2025-01" }, source: "vendor");
|
||||
|
||||
var clusters = _resolver.Resolve(new[] { nvd, vendor });
|
||||
|
||||
var cluster = Assert.Single(clusters);
|
||||
Assert.Equal("CVE-2025-1234", cluster.AdvisoryKey);
|
||||
Assert.Equal(2, cluster.Advisories.Length);
|
||||
Assert.True(cluster.Aliases.Any(alias => alias.Value == "CVE-2025-1234"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Resolve_PrefersPsirtAliasWhenNoCve()
|
||||
{
|
||||
var vendor = CreateAdvisory("VMSA-2025-0001", aliases: new[] { "VMSA-2025-0001" }, source: "vmware");
|
||||
var osv = CreateAdvisory("OSV-2025-1", aliases: new[] { "OSV-2025-1", "GHSA-xxxx-yyyy-zzzz", "VMSA-2025-0001" }, source: "osv");
|
||||
|
||||
var clusters = _resolver.Resolve(new[] { vendor, osv });
|
||||
|
||||
var cluster = Assert.Single(clusters);
|
||||
Assert.Equal("VMSA-2025-0001", cluster.AdvisoryKey);
|
||||
Assert.Equal(2, cluster.Advisories.Length);
|
||||
Assert.True(cluster.Aliases.Any(alias => alias.Value == "VMSA-2025-0001"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Resolve_FallsBackToGhsaWhenOnlyGhsaPresent()
|
||||
{
|
||||
var ghsa = CreateAdvisory("GHSA-aaaa-bbbb-cccc", aliases: new[] { "GHSA-aaaa-bbbb-cccc" }, source: "ghsa");
|
||||
var osv = CreateAdvisory("OSV-2025-99", aliases: new[] { "OSV-2025-99", "GHSA-aaaa-bbbb-cccc" }, source: "osv");
|
||||
|
||||
var clusters = _resolver.Resolve(new[] { ghsa, osv });
|
||||
|
||||
var cluster = Assert.Single(clusters);
|
||||
Assert.Equal("GHSA-aaaa-bbbb-cccc", cluster.AdvisoryKey);
|
||||
Assert.Equal(2, cluster.Advisories.Length);
|
||||
Assert.True(cluster.Aliases.Any(alias => alias.Value == "GHSA-aaaa-bbbb-cccc"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Resolve_GroupsByKeyWhenNoAliases()
|
||||
{
|
||||
var first = CreateAdvisory("custom-1", aliases: Array.Empty<string>(), source: "source-a");
|
||||
var second = CreateAdvisory("custom-1", aliases: Array.Empty<string>(), source: "source-b");
|
||||
|
||||
var clusters = _resolver.Resolve(new[] { first, second });
|
||||
|
||||
var cluster = Assert.Single(clusters);
|
||||
Assert.Equal("custom-1", cluster.AdvisoryKey);
|
||||
Assert.Equal(2, cluster.Advisories.Length);
|
||||
Assert.Contains(cluster.Aliases, alias => alias.Value == "custom-1");
|
||||
}
|
||||
|
||||
private static Advisory CreateAdvisory(string key, string[] aliases, string source)
|
||||
{
|
||||
var provenance = new[]
|
||||
{
|
||||
new AdvisoryProvenance(source, "mapping", key, DateTimeOffset.UtcNow),
|
||||
};
|
||||
|
||||
return new Advisory(
|
||||
key,
|
||||
$"{key} title",
|
||||
$"{key} summary",
|
||||
"en",
|
||||
DateTimeOffset.UtcNow,
|
||||
DateTimeOffset.UtcNow,
|
||||
null,
|
||||
exploitKnown: false,
|
||||
aliases,
|
||||
Array.Empty<AdvisoryCredit>(),
|
||||
Array.Empty<AdvisoryReference>(),
|
||||
Array.Empty<AffectedPackage>(),
|
||||
Array.Empty<CvssMetric>(),
|
||||
provenance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user