using System.IO; using ClaudeDo.Releases; namespace ClaudeDo.Releases.Tests; public sealed class ChecksumVerifierTests : IDisposable { private readonly string _tempDir; public ChecksumVerifierTests() { _tempDir = Path.Combine(Path.GetTempPath(), "ClaudeDoChecksum-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_tempDir); } public void Dispose() { try { Directory.Delete(_tempDir, recursive: true); } catch { } } [Fact] public void ComputeSha256_KnownVector_EmptyFile() { var path = Path.Combine(_tempDir, "empty.bin"); File.WriteAllBytes(path, Array.Empty()); var hash = ChecksumVerifier.ComputeSha256(path); Assert.Equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", hash); } [Fact] public void ComputeSha256_KnownVector_Hello() { var path = Path.Combine(_tempDir, "hello.bin"); File.WriteAllText(path, "hello"); var hash = ChecksumVerifier.ComputeSha256(path); Assert.Equal("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash); } [Fact] public void Verify_ReturnsTrue_WhenHashMatches() { var path = Path.Combine(_tempDir, "x.bin"); File.WriteAllText(path, "hello"); Assert.True(ChecksumVerifier.Verify(path, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824")); } [Fact] public void Verify_IsCaseInsensitive() { var path = Path.Combine(_tempDir, "x.bin"); File.WriteAllText(path, "hello"); Assert.True(ChecksumVerifier.Verify(path, "2CF24DBA5FB0A30E26E83B2AC5B9E29E1B161E5C1FA7425E73043362938B9824")); } [Fact] public void Verify_ReturnsFalse_OnMismatch() { var path = Path.Combine(_tempDir, "x.bin"); File.WriteAllText(path, "hello"); Assert.False(ChecksumVerifier.Verify(path, new string('0', 64))); } [Fact] public void ParseChecksumsFile_ReadsTwoLines() { var content = """ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ClaudeDo-0.2.0-win-x64.zip 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 ClaudeDo.Installer-0.2.0.exe """; var map = ChecksumVerifier.ParseChecksumsFile(content); Assert.Equal(2, map.Count); Assert.Equal( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", map["ClaudeDo-0.2.0-win-x64.zip"]); Assert.Equal( "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", map["ClaudeDo.Installer-0.2.0.exe"]); } [Fact] public void ParseChecksumsFile_SkipsBlankAndMalformedLines() { var content = """ not a line e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 file.zip """; var map = ChecksumVerifier.ParseChecksumsFile(content); Assert.Single(map); Assert.True(map.ContainsKey("file.zip")); } }