using System.IO; using ClaudeDo.Installer.Core; namespace ClaudeDo.Installer.Tests; public sealed class InstallManifestStoreTests : IDisposable { private readonly string _tempDir; public InstallManifestStoreTests() { _tempDir = Path.Combine(Path.GetTempPath(), "ClaudeDoInstallerTests-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_tempDir); } public void Dispose() { try { Directory.Delete(_tempDir, recursive: true); } catch { /* best effort */ } } [Fact] public void TryRead_ReturnsNull_WhenFileMissing() { var result = InstallManifestStore.TryRead(_tempDir); Assert.Null(result); } [Fact] public void Write_Then_Read_RoundTripsAllFields() { var manifest = new InstallManifest( Version: "0.2.0", InstallDir: _tempDir, WorkerDir: Path.Combine(_tempDir, "worker"), InstalledAt: new DateTimeOffset(2026, 4, 15, 12, 34, 56, TimeSpan.Zero)); InstallManifestStore.Write(_tempDir, manifest); var round = InstallManifestStore.TryRead(_tempDir); Assert.NotNull(round); Assert.Equal("0.2.0", round!.Version); Assert.Equal(manifest.InstallDir, round.InstallDir); Assert.Equal(manifest.WorkerDir, round.WorkerDir); Assert.Equal(manifest.InstalledAt, round.InstalledAt); } [Fact] public void Write_CreatesInstallDir_IfMissing() { var nested = Path.Combine(_tempDir, "nested"); Assert.False(Directory.Exists(nested)); InstallManifestStore.Write(nested, new InstallManifest( "0.0.1", nested, Path.Combine(nested, "worker"), DateTimeOffset.UtcNow)); Assert.True(File.Exists(Path.Combine(nested, "install.json"))); } [Fact] public void TryRead_ReturnsNull_WhenJsonMalformed() { File.WriteAllText(Path.Combine(_tempDir, "install.json"), "{ not json"); var result = InstallManifestStore.TryRead(_tempDir); Assert.Null(result); } [Fact] public void TryRead_ReturnsNull_WhenJsonIsValidButShapeIsWrong() { // Valid JSON, but installedAt has a wrong type — causes JsonException, swallowed silently. File.WriteAllText(Path.Combine(_tempDir, "install.json"), """{"version":"1.0","installDir":"x","workerDir":"y","installedAt":12345}"""); var result = InstallManifestStore.TryRead(_tempDir); Assert.Null(result); } }