using StellaOps.AirGap.Importer.Contracts; using StellaOps.AirGap.Importer.Validation; namespace StellaOps.AirGap.Importer.Tests; public class ReplayVerifierTests { private readonly ReplayVerifier _verifier = new(); [Fact] public void FullRecompute_succeeds_when_hashes_match_and_fresh() { var now = DateTimeOffset.Parse("2025-12-02T01:00:00Z"); var request = new ReplayVerificationRequest( "aa".PadRight(64, 'a'), "bb".PadRight(64, 'b'), "aa".PadRight(64, 'a'), "bb".PadRight(64, 'b'), now.AddHours(-4), 24, "cc".PadRight(64, 'c'), "cc".PadRight(64, 'c'), ReplayDepth.FullRecompute); var result = _verifier.Verify(request, now); Assert.True(result.IsValid); Assert.Equal("full-recompute-passed", result.Reason); } [Fact] public void Detects_hash_drift() { var now = DateTimeOffset.UtcNow; var request = new ReplayVerificationRequest( "aa".PadRight(64, 'a'), "bb".PadRight(64, 'b'), "00".PadRight(64, '0'), "bb".PadRight(64, 'b'), now, 1, null, null, ReplayDepth.HashOnly); var result = _verifier.Verify(request, now); Assert.False(result.IsValid); Assert.Equal("manifest-hash-drift", result.Reason); } [Fact] public void PolicyFreeze_requires_matching_policy_hash() { var now = DateTimeOffset.UtcNow; var request = new ReplayVerificationRequest( "aa".PadRight(64, 'a'), "bb".PadRight(64, 'b'), "aa".PadRight(64, 'a'), "bb".PadRight(64, 'b'), now, 12, "bundle-policy", "sealed-policy-other", ReplayDepth.PolicyFreeze); var result = _verifier.Verify(request, now); Assert.False(result.IsValid); Assert.Equal("policy-hash-drift", result.Reason); } }