using System; using System.Collections.Generic; using StellaOps.Signals.Models; using StellaOps.Signals.Services; using Xunit; public class ReachabilityFactDigestCalculatorTests { [Fact] public void Compute_ReturnsDeterministicDigest_ForEquivalentFacts() { var factA = new ReachabilityFactDocument { CallgraphId = "cg-1", Subject = new ReachabilitySubject { Component = "demo", Version = "1.0.0" }, SubjectKey = "demo|1.0.0", EntryPoints = new List { "svc.main", "app.main" }, States = new List { new() { Target = "a", Reachable = true, Confidence = 0.9, Bucket = "runtime", Weight = 0.45, Path = new List { "app.main", "a" }, Evidence = new ReachabilityEvidenceDocument { RuntimeHits = new List { "a" } } }, new() { Target = "b", Reachable = false, Confidence = 0.3, Bucket = "unreachable", Weight = 0.1, Path = new List { "app.main", "b" } } }, RuntimeFacts = new List { new() { SymbolId = "a", HitCount = 2 } }, Metadata = new Dictionary(StringComparer.Ordinal) { { "tenant", "tenant-default" } }, ComputedAt = DateTimeOffset.Parse("2025-12-09T00:00:00Z") }; var factB = new ReachabilityFactDocument { CallgraphId = "cg-1", Subject = new ReachabilitySubject { Component = "demo", Version = "1.0.0" }, SubjectKey = "demo|1.0.0", EntryPoints = new List { "app.main", "svc.main" }, // reversed States = new List { new() { Target = "b", Reachable = false, Confidence = 0.3, Bucket = "unreachable", Weight = 0.1, Path = new List { "app.main", "b" } }, new() { Target = "a", Reachable = true, Confidence = 0.9, Bucket = "runtime", Weight = 0.45, Path = new List { "app.main", "a" }, Evidence = new ReachabilityEvidenceDocument { RuntimeHits = new List { "a" } } } }, RuntimeFacts = new List { new() { SymbolId = "a", HitCount = 2 } }, Metadata = new Dictionary(StringComparer.Ordinal) { { "tenant", "tenant-default" } }, ComputedAt = DateTimeOffset.Parse("2025-12-09T00:00:00Z") }; var digestA = ReachabilityFactDigestCalculator.Compute(factA); var digestB = ReachabilityFactDigestCalculator.Compute(factB); Assert.StartsWith("sha256:", digestA, StringComparison.Ordinal); Assert.Equal(digestA, digestB); } }