using System; using FluentAssertions; using StellaOps.TestKit.Evidence; using Xunit; namespace StellaOps.TestKit.Tests; public sealed partial class EvidenceChainTests { [Fact] public void ArtifactHashStable_PassesWithCorrectHash() { var content = "test artifact"; var expectedHash = EvidenceChainAssert.ComputeSha256(content); var act = () => EvidenceChainAssert.ArtifactHashStable(content, expectedHash); act.Should().NotThrow(); } [Fact] public void ArtifactHashStable_ThrowsWithIncorrectHash() { var content = "test artifact"; var wrongHash = new string('0', 64); var act = () => EvidenceChainAssert.ArtifactHashStable(content, wrongHash); act.Should().Throw() .WithMessage("*Artifact hash mismatch*"); } [Fact] public void ArtifactHashStable_ThrowsOnNullArtifact() { var act = () => EvidenceChainAssert.ArtifactHashStable((byte[])null!, "hash"); act.Should().Throw(); } [Fact] public void ArtifactImmutable_PassesWithDeterministicGenerator() { var counter = 0; Func generator = () => { counter++; return "immutable content"; }; var act = () => EvidenceChainAssert.ArtifactImmutable(generator, iterations: 5); act.Should().NotThrow(); counter.Should().Be(5); } [Fact] public void ArtifactImmutable_ThrowsWithNonDeterministicGenerator() { var counter = 0; Func generator = () => { counter++; return $"non-deterministic content {counter}"; }; var act = () => EvidenceChainAssert.ArtifactImmutable(generator, iterations: 5); act.Should().Throw() .WithMessage("*Artifact not immutable*"); } [Fact] public void ArtifactImmutable_ThrowsWithLessThanTwoIterations() { var act = () => EvidenceChainAssert.ArtifactImmutable(() => "content", iterations: 1); act.Should().Throw(); } }