using MeterVault.Infrastructure.Options;
using MeterVault.Infrastructure.Update;
using Microsoft.Extensions.Logging.Abstractions;
namespace MeterVault.Integration.Tests;
///
/// The gate in front of the in-app update. AllowInAppUpdate is the whole gate by explicit
/// operator choice — no key — so the flag defaulting off is the only thing standing between an
/// upgrade and a network-triggerable rebuild-and-restart as root.
///
///
/// None of these launch anything: they assert the conditions that must hold before a launch
/// is even attempted, which is the part worth pinning. The launch itself needs systemd and a real
/// /usr/bin/update.
///
public sealed class UpdateRunnerTests
{
[Fact]
public void Disabled_by_default()
{
// The single most important assertion in this file: with no key required, an operator who
// upgrades without reading the notes must not silently acquire an open trigger.
Assert.False(new MeterVaultOptions().AllowInAppUpdate);
Assert.Equal(UpdateAvailability.NotEnabled, NewRunner(new MeterVaultOptions()).Availability);
}
[Fact]
public void Configuring_api_keys_alone_does_not_enable_it()
{
// The two settings are independent: having an API key for the REST API is not consent to
// rebuild the host.
var options = new MeterVaultOptions();
options.ApiKeys.Add("some-key");
Assert.Equal(UpdateAvailability.NotEnabled, NewRunner(options).Availability);
}
[Fact]
public async Task Refuses_to_launch_when_not_allowed_even_if_asked_directly()
{
// Defence in depth: LaunchAsync re-checks rather than trusting its caller to have done so.
var launch = await NewRunner(new MeterVaultOptions()).LaunchAsync();
Assert.False(launch.Started);
Assert.Contains("NotEnabled", launch.Message, StringComparison.Ordinal);
}
[Fact]
public void Reports_unsupported_where_there_is_no_in_place_updater()
{
// On a dev box or in a container there is no /usr/bin/update, so an enabled runner still
// declines rather than half-running something.
if (UpdateRunner.IsSupportedHere)
{
return; // running on a provisioned LXC; the negative case cannot be observed here
}
Assert.Equal(UpdateAvailability.NotSupportedHere, NewRunner(Enabled()).Availability);
}
private static MeterVaultOptions Enabled() => new() { AllowInAppUpdate = true };
private static UpdateRunner NewRunner(MeterVaultOptions options) =>
new(Microsoft.Extensions.Options.Options.Create(options), NullLogger.Instance);
}