126 lines
4.2 KiB
C#
126 lines
4.2 KiB
C#
using ClaudeDo.Installer.Core;
|
|
using ClaudeDo.Releases;
|
|
|
|
namespace ClaudeDo.Installer.Tests;
|
|
|
|
public sealed class InstallModeDetectorTests : IDisposable
|
|
{
|
|
private readonly string _tempDir;
|
|
|
|
public InstallModeDetectorTests()
|
|
{
|
|
_tempDir = Path.Combine(Path.GetTempPath(), "ClaudeDoDetector-" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(_tempDir);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
try { Directory.Delete(_tempDir, recursive: true); } catch { }
|
|
}
|
|
|
|
private sealed class FakeReleaseClient : IReleaseClient
|
|
{
|
|
public GiteaRelease? Release { get; set; }
|
|
public Task<GiteaRelease?> GetLatestReleaseAsync(CancellationToken ct) => Task.FromResult(Release);
|
|
public Task DownloadAsync(string url, string destPath, IProgress<long> progress, CancellationToken ct)
|
|
=> throw new NotSupportedException();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_FreshInstall_WhenManifestMissing()
|
|
{
|
|
var detector = new InstallModeDetector(new FakeReleaseClient());
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.FreshInstall, state.Mode);
|
|
Assert.Null(state.Existing);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_Config_WhenManifestPresent_And_Api_Unreachable()
|
|
{
|
|
InstallManifestStore.Write(_tempDir,
|
|
new InstallManifest("0.1.0", _tempDir, _tempDir, DateTimeOffset.UtcNow));
|
|
|
|
var detector = new InstallModeDetector(new FakeReleaseClient { Release = null });
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.Config, state.Mode);
|
|
Assert.Equal("0.1.0", state.Existing!.Version);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_Update_WhenLatest_GreaterThan_Installed()
|
|
{
|
|
InstallManifestStore.Write(_tempDir,
|
|
new InstallManifest("0.1.0", _tempDir, _tempDir, DateTimeOffset.UtcNow));
|
|
|
|
var fake = new FakeReleaseClient
|
|
{
|
|
Release = new GiteaRelease("v0.2.0", "v0.2.0", Array.Empty<ReleaseAsset>())
|
|
};
|
|
var detector = new InstallModeDetector(fake);
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.Update, state.Mode);
|
|
Assert.Equal("0.1.0", state.Existing!.Version);
|
|
Assert.Equal("0.2.0", state.LatestVersion);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_Config_WhenLatest_EqualsOrOlderThan_Installed()
|
|
{
|
|
InstallManifestStore.Write(_tempDir,
|
|
new InstallManifest("0.2.0", _tempDir, _tempDir, DateTimeOffset.UtcNow));
|
|
|
|
var fake = new FakeReleaseClient
|
|
{
|
|
Release = new GiteaRelease("v0.2.0", "v0.2.0", Array.Empty<ReleaseAsset>())
|
|
};
|
|
var detector = new InstallModeDetector(fake);
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.Config, state.Mode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_Config_WhenInstalledIs_Newer_Than_Latest()
|
|
{
|
|
InstallManifestStore.Write(_tempDir,
|
|
new InstallManifest("0.3.0", _tempDir, _tempDir, DateTimeOffset.UtcNow));
|
|
|
|
var fake = new FakeReleaseClient
|
|
{
|
|
Release = new GiteaRelease("v0.2.0", "v0.2.0", Array.Empty<ReleaseAsset>())
|
|
};
|
|
var detector = new InstallModeDetector(fake);
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.Config, state.Mode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Detect_Config_WhenInstalledVersion_IsUnparseable()
|
|
{
|
|
// install.json has been tampered with or written by an older installer with a
|
|
// version string we can't compare. Must not crash; must land on Config (no update).
|
|
InstallManifestStore.Write(_tempDir,
|
|
new InstallManifest("garbage", _tempDir, _tempDir, DateTimeOffset.UtcNow));
|
|
|
|
var fake = new FakeReleaseClient
|
|
{
|
|
Release = new GiteaRelease("v0.2.0", "v0.2.0", Array.Empty<ReleaseAsset>())
|
|
};
|
|
var detector = new InstallModeDetector(fake);
|
|
|
|
var state = await detector.DetectAsync(_tempDir, CancellationToken.None);
|
|
|
|
Assert.Equal(InstallerMode.Config, state.Mode);
|
|
}
|
|
}
|