feat: add Reachability Center and Why Drawer components with tests
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled

- Implemented ReachabilityCenterComponent for displaying asset reachability status with summary and filtering options.
- Added ReachabilityWhyDrawerComponent to show detailed reachability evidence and call paths.
- Created unit tests for both components to ensure functionality and correctness.
- Updated accessibility test results for the new components.
This commit is contained in:
master
2025-12-12 18:50:35 +02:00
parent efaf3cb789
commit 3f3473ee3a
320 changed files with 10635 additions and 3677 deletions

View File

@@ -8,9 +8,9 @@ using StellaOps.Concelier.Core;
using StellaOps.Concelier.Core.Events;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Storage.Mongo.Advisories;
using StellaOps.Concelier.Storage.Mongo.Aliases;
using StellaOps.Concelier.Storage.Mongo.MergeEvents;
using StellaOps.Concelier.Storage.Advisories;
using StellaOps.Concelier.Storage.Aliases;
using StellaOps.Concelier.Storage.MergeEvents;
using StellaOps.Provenance.Mongo;
namespace StellaOps.Concelier.Merge.Tests;

View File

@@ -1,34 +1,20 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using MongoDB.Driver;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Storage.Mongo;
using StellaOps.Concelier.Storage.Mongo.Aliases;
using StellaOps.Concelier.Testing;
namespace StellaOps.Concelier.Merge.Tests;
[Collection("mongo-fixture")]
public sealed class AliasGraphResolverTests : IClassFixture<MongoIntegrationFixture>
{
private readonly MongoIntegrationFixture _fixture;
public AliasGraphResolverTests(MongoIntegrationFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task ResolveAsync_ReturnsCollisions_WhenAliasesOverlap()
{
await DropAliasCollectionAsync();
var aliasStore = new AliasStore(_fixture.Database, NullLogger<AliasStore>.Instance);
var resolver = new AliasGraphResolver(aliasStore);
var timestamp = DateTimeOffset.UtcNow;
using System;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Storage.Aliases;
namespace StellaOps.Concelier.Merge.Tests;
public sealed class AliasGraphResolverTests
{
[Fact]
public async Task ResolveAsync_ReturnsCollisions_WhenAliasesOverlap()
{
var aliasStore = new AliasStore();
var resolver = new AliasGraphResolver(aliasStore);
var timestamp = DateTimeOffset.UtcNow;
await aliasStore.ReplaceAsync(
"ADV-1",
new[] { new AliasEntry("CVE", "CVE-2025-2000"), new AliasEntry(AliasStoreConstants.PrimaryScheme, "ADV-1") },
@@ -50,13 +36,12 @@ public sealed class AliasGraphResolverTests : IClassFixture<MongoIntegrationFixt
Assert.Contains("ADV-1", collision.AdvisoryKeys);
Assert.Contains("ADV-2", collision.AdvisoryKeys);
}
[Fact]
public async Task BuildComponentAsync_TracesConnectedAdvisories()
{
await DropAliasCollectionAsync();
var aliasStore = new AliasStore(_fixture.Database, NullLogger<AliasStore>.Instance);
var resolver = new AliasGraphResolver(aliasStore);
[Fact]
public async Task BuildComponentAsync_TracesConnectedAdvisories()
{
var aliasStore = new AliasStore();
var resolver = new AliasGraphResolver(aliasStore);
var timestamp = DateTimeOffset.UtcNow;
await aliasStore.ReplaceAsync(
@@ -83,28 +68,15 @@ public sealed class AliasGraphResolverTests : IClassFixture<MongoIntegrationFixt
Assert.Contains("ADV-C", component.AdvisoryKeys, StringComparer.OrdinalIgnoreCase);
Assert.NotEmpty(component.Collisions);
Assert.True(component.AliasMap.ContainsKey("ADV-A"));
Assert.Contains(component.AliasMap["ADV-B"], record => record.Scheme == "OSV" && record.Value == "OSV-2025-1");
}
private async Task DropAliasCollectionAsync()
{
try
{
await _fixture.Database.DropCollectionAsync(MongoStorageDefaults.Collections.Alias);
}
catch (MongoDB.Driver.MongoCommandException ex) when (ex.CodeName == "NamespaceNotFound" || ex.Message.Contains("ns not found", StringComparison.OrdinalIgnoreCase))
{
}
}
[Fact]
public async Task BuildComponentAsync_LinksOsvAndGhsaAliases()
{
await DropAliasCollectionAsync();
var aliasStore = new AliasStore(_fixture.Database, NullLogger<AliasStore>.Instance);
var resolver = new AliasGraphResolver(aliasStore);
var timestamp = DateTimeOffset.UtcNow;
Assert.Contains(component.AliasMap["ADV-B"], record => record.Scheme == "OSV" && record.Value == "OSV-2025-1");
}
[Fact]
public async Task BuildComponentAsync_LinksOsvAndGhsaAliases()
{
var aliasStore = new AliasStore();
var resolver = new AliasGraphResolver(aliasStore);
var timestamp = DateTimeOffset.UtcNow;
await aliasStore.ReplaceAsync(
"ADV-OSV",

View File

@@ -2,7 +2,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Storage.Mongo.MergeEvents;
using StellaOps.Concelier.Storage.MergeEvents;
namespace StellaOps.Concelier.Merge.Tests;

View File

@@ -1,30 +1,20 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Time.Testing;
using MongoDB.Driver;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Storage.Mongo;
using StellaOps.Concelier.Storage.Mongo.MergeEvents;
using StellaOps.Concelier.Testing;
namespace StellaOps.Concelier.Merge.Tests;
[Collection("mongo-fixture")]
public sealed class MergePrecedenceIntegrationTests : IAsyncLifetime
{
private readonly MongoIntegrationFixture _fixture;
private MergeEventStore? _mergeEventStore;
private MergeEventWriter? _mergeEventWriter;
private AdvisoryPrecedenceMerger? _merger;
private FakeTimeProvider? _timeProvider;
public MergePrecedenceIntegrationTests(MongoIntegrationFixture fixture)
{
_fixture = fixture;
}
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Concelier.Merge.Services;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Storage.MergeEvents;
namespace StellaOps.Concelier.Merge.Tests;
public sealed class MergePrecedenceIntegrationTests : IAsyncLifetime
{
private MergeEventStore? _mergeEventStore;
private MergeEventWriter? _mergeEventWriter;
private AdvisoryPrecedenceMerger? _merger;
private FakeTimeProvider? _timeProvider;
[Fact]
public async Task MergePipeline_PsirtOverridesNvd_AndKevOnlyTogglesExploitKnown()
@@ -82,29 +72,28 @@ public sealed class MergePrecedenceIntegrationTests : IAsyncLifetime
AutoAdvanceAmount = TimeSpan.Zero,
};
_merger = new AdvisoryPrecedenceMerger(new AffectedPackagePrecedenceResolver(), _timeProvider);
_mergeEventStore = new MergeEventStore(_fixture.Database, NullLogger<MergeEventStore>.Instance);
_mergeEventWriter = new MergeEventWriter(_mergeEventStore, new CanonicalHashCalculator(), _timeProvider, NullLogger<MergeEventWriter>.Instance);
await DropMergeCollectionAsync();
}
_mergeEventStore = new MergeEventStore();
_mergeEventWriter = new MergeEventWriter(_mergeEventStore, new CanonicalHashCalculator(), _timeProvider, NullLogger<MergeEventWriter>.Instance);
}
public Task DisposeAsync() => Task.CompletedTask;
private async Task EnsureInitializedAsync()
{
if (_mergeEventWriter is null)
{
await InitializeAsync();
}
}
private async Task EnsureInitializedAsync()
{
if (_mergeEventWriter is null)
{
await InitializeAsync();
}
}
private async Task DropMergeCollectionAsync()
private Task DropMergeCollectionAsync()
{
try
{
await _fixture.Database.DropCollectionAsync(MongoStorageDefaults.Collections.MergeEvent);
}
catch (MongoCommandException ex) when (ex.CodeName == "NamespaceNotFound" || ex.Message.Contains("ns not found", StringComparison.OrdinalIgnoreCase))
{
return Task.CompletedTask;
// {
// await _fixture.Database.DropCollectionAsync(MongoStorageDefaults.Collections.MergeEvent);
// }
// catch (MongoCommandException ex) when (ex.CodeName == "NamespaceNotFound" || ex.Message.Contains("ns not found", StringComparison.OrdinalIgnoreCase))
// {
// Collection has not been created yet safe to ignore.
}
}