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:
@@ -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>();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user