89 lines
3.0 KiB
C#
89 lines
3.0 KiB
C#
namespace Zcbot.WindowsNode.Tests;
|
|
|
|
public sealed class JobPageViewModelTests
|
|
{
|
|
[Fact]
|
|
public void Refresh_PopulatesJobsFormatsStateAndSelectsTheFirstItem()
|
|
{
|
|
var active = Snapshot("software_running", "正在生成图表", minutesAgo: 2);
|
|
var succeeded = Snapshot("succeeded", "历史任务", minutesAgo: 10);
|
|
var viewModel = new JobPageViewModel(new FakeJobMonitorService(active, succeeded));
|
|
|
|
viewModel.Refresh();
|
|
|
|
Assert.Equal(2, viewModel.Jobs.Count);
|
|
Assert.Same(viewModel.Jobs[0], viewModel.SelectedJob);
|
|
Assert.Equal("软件执行中", viewModel.Jobs[0].StageText);
|
|
Assert.StartsWith("已执行 02:", viewModel.Jobs[0].ProgressText);
|
|
Assert.Equal("活动任务 1 个 · 最近记录 2 条", viewModel.Summary);
|
|
Assert.Contains(active.JobId.ToString(), viewModel.SelectedDetail);
|
|
}
|
|
|
|
[Fact]
|
|
public void Refresh_PreservesSelectionByJobIdAcrossSnapshots()
|
|
{
|
|
var first = Snapshot("accepted", "第一项", minutesAgo: 3);
|
|
var second = Snapshot("failed", "第二项", minutesAgo: 2);
|
|
var service = new FakeJobMonitorService(first, second);
|
|
var viewModel = new JobPageViewModel(service);
|
|
viewModel.Refresh();
|
|
viewModel.SelectedJob = viewModel.Jobs[1];
|
|
|
|
service.Snapshots = [
|
|
second with { Detail = "更新后的错误" },
|
|
first,
|
|
];
|
|
viewModel.Refresh();
|
|
|
|
Assert.Equal(second.JobId, viewModel.SelectedJob?.JobId);
|
|
Assert.Contains("更新后的错误", viewModel.SelectedDetail);
|
|
Assert.Equal("error", viewModel.SelectedJob?.Tone);
|
|
}
|
|
|
|
[Fact]
|
|
public void Refresh_ReportsReadFailuresWithoutDroppingTheCurrentList()
|
|
{
|
|
var service = new FakeJobMonitorService(Snapshot("accepted", "任务", 1));
|
|
var viewModel = new JobPageViewModel(service);
|
|
viewModel.Refresh();
|
|
service.Failure = new IOException("locked");
|
|
|
|
viewModel.Refresh();
|
|
|
|
Assert.Single(viewModel.Jobs);
|
|
Assert.Contains("locked", viewModel.Summary);
|
|
}
|
|
|
|
private static JobDisplaySnapshot Snapshot(
|
|
string stage,
|
|
string title,
|
|
int minutesAgo)
|
|
{
|
|
var updatedAt = DateTimeOffset.UtcNow.AddMinutes(-minutesAgo);
|
|
return new JobDisplaySnapshot(
|
|
Guid.NewGuid(),
|
|
"origin.plot@v2",
|
|
title,
|
|
"input.csv",
|
|
stage,
|
|
stage == "succeeded" ? 100 : 25,
|
|
title,
|
|
updatedAt.AddMinutes(-1),
|
|
updatedAt,
|
|
stage == "succeeded");
|
|
}
|
|
|
|
private sealed class FakeJobMonitorService(params JobDisplaySnapshot[] snapshots)
|
|
: IJobMonitorService
|
|
{
|
|
internal IReadOnlyList<JobDisplaySnapshot> Snapshots { get; set; } = snapshots;
|
|
internal Exception? Failure { get; set; }
|
|
|
|
public IReadOnlyList<JobDisplaySnapshot> ReadSnapshots(int limit = 50)
|
|
{
|
|
if (Failure is not null) throw Failure;
|
|
return Snapshots;
|
|
}
|
|
}
|
|
}
|