83 lines
3.5 KiB
C#
83 lines
3.5 KiB
C#
using Bunit;
|
|
using Moq;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using SilverOS.Welcome.App.Components;
|
|
using SilverOS.Welcome.App.Components.Steps;
|
|
using SilverOS.Welcome.Core.Apply;
|
|
using SilverOS.Welcome.Core.Apps;
|
|
using SilverOS.Welcome.Core.Flavours;
|
|
using Xunit;
|
|
|
|
public class ApplyStepTests : TestContext
|
|
{
|
|
// The component loads the catalog from AppContext.BaseDirectory/apps; no catalog.json
|
|
// is staged in the test bin, so the real AppCatalog degrades to an empty list — which is
|
|
// exactly what these tests want (no apps selected → empty Apps on the request).
|
|
private static void AddCatalog(IServiceCollection services) =>
|
|
services.AddSingleton<IAppCatalog>(new AppCatalog());
|
|
|
|
[Fact]
|
|
public async Task Calls_apply_with_the_wizard_selections()
|
|
{
|
|
var apply = new Mock<IApplyService>();
|
|
var state = new WizardState
|
|
{
|
|
Flavour = new FlavourManifest { Id = "daily-driver", Hardening = new() { Modules = new[] { "00" } } },
|
|
Username = "alice",
|
|
Password = "pw",
|
|
AdminPassword = "apw",
|
|
BitLockerPin = "123456"
|
|
};
|
|
Services.AddSingleton(state);
|
|
Services.AddSingleton(apply.Object);
|
|
AddCatalog(Services);
|
|
var cut = RenderComponent<ApplyStep>();
|
|
await cut.InvokeAsync(() => cut.Instance.StartAsync());
|
|
apply.Verify(a => a.RunAsync(
|
|
It.Is<ApplyRequest>(r => r.Username == "alice" && r.Flavour.Id == "daily-driver"),
|
|
It.IsAny<IProgress<ApplyProgress>>(),
|
|
It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task OnComplete_invoked_when_apply_succeeds()
|
|
{
|
|
var apply = new Mock<IApplyService>();
|
|
apply.Setup(a => a.RunAsync(It.IsAny<ApplyRequest>(), It.IsAny<IProgress<ApplyProgress>>(), It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
var state = new WizardState
|
|
{
|
|
Flavour = new FlavourManifest { Id = "daily-driver", Hardening = new() { Modules = new[] { "00" } } },
|
|
Username = "alice", Password = "pw", AdminPassword = "apw", BitLockerPin = "123456"
|
|
};
|
|
Services.AddSingleton(state);
|
|
Services.AddSingleton(apply.Object);
|
|
AddCatalog(Services);
|
|
var completed = false;
|
|
var cut = RenderComponent<ApplyStep>(p => p.Add(s => s.OnComplete, EventCallback.Factory.Create(this, () => { completed = true; })));
|
|
await cut.InvokeAsync(() => cut.Instance.StartAsync());
|
|
Assert.True(completed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Shows_error_and_retry_button_when_apply_fails()
|
|
{
|
|
var apply = new Mock<IApplyService>();
|
|
apply.Setup(a => a.RunAsync(It.IsAny<ApplyRequest>(), It.IsAny<IProgress<ApplyProgress>>(), It.IsAny<CancellationToken>()))
|
|
.ThrowsAsync(new InvalidOperationException("Module 03 failed"));
|
|
var state = new WizardState
|
|
{
|
|
Flavour = new FlavourManifest { Id = "daily-driver", Hardening = new() { Modules = new[] { "00" } } },
|
|
Username = "alice", Password = "pw", AdminPassword = "apw", BitLockerPin = "123456"
|
|
};
|
|
Services.AddSingleton(state);
|
|
Services.AddSingleton(apply.Object);
|
|
AddCatalog(Services);
|
|
var cut = RenderComponent<ApplyStep>();
|
|
await cut.InvokeAsync(() => cut.Instance.StartAsync());
|
|
Assert.Contains("Module 03 failed", cut.Markup);
|
|
Assert.NotNull(cut.Find(".btn-retry"));
|
|
}
|
|
}
|