Add unit tests and implementations for MongoDB index models and OpenAPI metadata

- Implemented `MongoIndexModelTests` to verify index models for various stores.
- Created `OpenApiMetadataFactory` with methods to generate OpenAPI metadata.
- Added tests for `OpenApiMetadataFactory` to ensure expected defaults and URL overrides.
- Introduced `ObserverSurfaceSecrets` and `WebhookSurfaceSecrets` for managing secrets.
- Developed `RuntimeSurfaceFsClient` and `WebhookSurfaceFsClient` for manifest retrieval.
- Added dependency injection tests for `SurfaceEnvironmentRegistration` in both Observer and Webhook contexts.
- Implemented tests for secret resolution in `ObserverSurfaceSecretsTests` and `WebhookSurfaceSecretsTests`.
- Created `EnsureLinkNotMergeCollectionsMigrationTests` to validate MongoDB migration logic.
- Added project files for MongoDB tests and NuGet package mirroring.
This commit is contained in:
master
2025-11-17 21:21:56 +02:00
parent d3128aec24
commit 9075bad2d9
146 changed files with 152183 additions and 82 deletions

View File

@@ -0,0 +1,7 @@
namespace StellaOps.Scanner.Analyzers.Lang;
public sealed class AnalysisSnapshot
{
public IReadOnlyList<LanguageEntrypointSnapshot> Entrypoints { get; set; } = Array.Empty<LanguageEntrypointSnapshot>();
public IReadOnlyList<LanguageComponentSnapshot> Components { get; set; } = Array.Empty<LanguageComponentSnapshot>();
}

View File

@@ -0,0 +1,15 @@
using System;
namespace StellaOps.Scanner.Analyzers.Lang;
internal static class LanguageComponentEvidenceExtensions
{
/// <summary>
/// Builds a stable key for evidence items to support deterministic dictionaries.
/// </summary>
public static string ToKey(this LanguageComponentEvidence evidence)
{
ArgumentNullException.ThrowIfNull(evidence);
return $"{evidence.Kind}:{evidence.Source}:{evidence.Locator}".ToLowerInvariant();
}
}

View File

@@ -0,0 +1,96 @@
using System.Text.Json.Serialization;
namespace StellaOps.Scanner.Analyzers.Lang;
public sealed class LanguageEntrypointRecord
{
private readonly SortedDictionary<string, string?> _metadata;
private readonly SortedDictionary<string, LanguageComponentEvidence> _evidence;
public LanguageEntrypointRecord(
string id,
string name,
IEnumerable<KeyValuePair<string, string?>>? metadata = null,
IEnumerable<LanguageComponentEvidence>? evidence = null)
{
if (string.IsNullOrWhiteSpace(id))
{
throw new ArgumentException("Entrypoint id is required", nameof(id));
}
Id = id.Trim();
Name = string.IsNullOrWhiteSpace(name) ? Id : name.Trim();
_metadata = new SortedDictionary<string, string?>(StringComparer.Ordinal);
foreach (var pair in metadata ?? Array.Empty<KeyValuePair<string, string?>>())
{
_metadata[pair.Key] = pair.Value;
}
_evidence = new SortedDictionary<string, LanguageComponentEvidence>(StringComparer.Ordinal);
foreach (var item in evidence ?? Array.Empty<LanguageComponentEvidence>())
{
var key = item.ToKey();
_evidence[key] = item;
}
}
public string Id { get; }
public string Name { get; }
public IReadOnlyDictionary<string, string?> Metadata => _metadata;
public IReadOnlyCollection<LanguageComponentEvidence> Evidence => _evidence.Values;
internal LanguageEntrypointSnapshot ToSnapshot()
=> new()
{
Id = Id,
Name = Name,
Metadata = _metadata.ToDictionary(static kvp => kvp.Key, static kvp => kvp.Value, StringComparer.Ordinal),
Evidence = _evidence.Values
.Select(static item => new LanguageComponentEvidenceSnapshot
{
Kind = item.Kind,
Source = item.Source,
Locator = item.Locator,
Value = item.Value,
Sha256 = item.Sha256
})
.ToList()
};
internal static LanguageEntrypointRecord FromSnapshot(LanguageEntrypointSnapshot snapshot)
{
if (snapshot is null)
{
throw new ArgumentNullException(nameof(snapshot));
}
var evidence = snapshot.Evidence?
.Select(static e => new LanguageComponentEvidence(e.Kind, e.Source, e.Locator, e.Value, e.Sha256))
.ToArray();
return new LanguageEntrypointRecord(
snapshot.Id ?? string.Empty,
snapshot.Name ?? snapshot.Id ?? string.Empty,
snapshot.Metadata,
evidence);
}
}
public sealed class LanguageEntrypointSnapshot
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("metadata")]
public Dictionary<string, string?> Metadata { get; set; } = new(StringComparer.Ordinal);
[JsonPropertyName("evidence")]
public List<LanguageComponentEvidenceSnapshot> Evidence { get; set; } = new();
}