// SPDX-License-Identifier: AGPL-3.0-or-later // Copyright (c) StellaOps Contributors using System.Collections.Immutable; using StellaOps.Attestor.ProofChain.Predicates; using StellaOps.Scanner.SmartDiff.Attestation; using StellaOps.Scanner.SmartDiff.Detection; using Xunit; namespace StellaOps.Scanner.SmartDiffTests; public sealed class DeltaVerdictBuilderTests { [Fact] public void BuildStatement_BuildsPredicateAndSubjects() { var changes = new[] { new MaterialRiskChangeResult( FindingKey: new FindingKey("CVE-2025-0001", "pkg:npm/a@1.0.0"), HasMaterialChange: true, Changes: ImmutableArray.Create(new DetectedChange( Rule: DetectionRule.R1_ReachabilityFlip, ChangeType: MaterialChangeType.ReachabilityFlip, Direction: RiskDirection.Increased, Reason: "reachability_flip", PreviousValue: "false", CurrentValue: "true", Weight: 1.0)), PriorityScore: 100, PreviousStateHash: "sha256:prev", CurrentStateHash: "sha256:curr"), new MaterialRiskChangeResult( FindingKey: new FindingKey("CVE-2025-0002", "pkg:npm/b@2.0.0"), HasMaterialChange: true, Changes: ImmutableArray.Create(new DetectedChange( Rule: DetectionRule.R2_VexFlip, ChangeType: MaterialChangeType.VexFlip, Direction: RiskDirection.Decreased, Reason: "vex_flip", PreviousValue: "affected", CurrentValue: "not_affected", Weight: 0.7)), PriorityScore: 50, PreviousStateHash: "sha256:prev2", CurrentStateHash: "sha256:curr2") }; var request = new DeltaVerdictBuildRequest { BeforeRevisionId = "rev-before", AfterRevisionId = "rev-after", BeforeImageDigest = "sha256:before", AfterImageDigest = "sha256:after", Changes = changes, ComparedAt = new DateTimeOffset(2025, 12, 22, 0, 0, 0, TimeSpan.Zero), BeforeProofSpine = new AttestationReference { Digest = "sha256:spine-before" }, AfterProofSpine = new AttestationReference { Digest = "sha256:spine-after" } }; var builder = new DeltaVerdictBuilder(); var statement = builder.BuildStatement(request); Assert.Equal(2, statement.Subject.Count); Assert.Equal("delta-verdict.stella/v1", statement.PredicateType); Assert.True(statement.Predicate.HasMaterialChange); Assert.Equal(150, statement.Predicate.PriorityScore); Assert.Equal("rev-before", statement.Predicate.BeforeRevisionId); Assert.Equal("rev-after", statement.Predicate.AfterRevisionId); Assert.Equal(2, statement.Predicate.Changes.Length); Assert.Equal("R1", statement.Predicate.Changes[0].Rule); Assert.Equal("increased", statement.Predicate.Changes[0].Direction); } }