Files
Axi_Omron/tests/AxiOmron.PcbCheck.Tests/WorkflowHostedServiceTests.cs
yunxiao.zhu 8f74e07c66 feat(*): 添加管理员解锁与 SFTP 探活能力
* 新增管理员解锁弹窗、手动操作权限控制与倒计时状态
* 支持系统设置页测试 SFTP 连接,并在启动时执行探活
* 补充设计时服务、全局异常兜底与相关单元测试
2026-04-17 14:12:10 +08:00

87 lines
3.7 KiB
C#

using AxiOmron.PcbCheck.Models;
using AxiOmron.PcbCheck.Options;
using AxiOmron.PcbCheck.Services.Implementations;
using AxiOmron.PcbCheck.Services.Interfaces;
namespace AxiOmron.PcbCheck.Tests;
/// <summary>
/// 验证流程后台服务的 SFTP 启动探活行为。
/// </summary>
public sealed class WorkflowHostedServiceTests
{
/// <summary>
/// 启动探活失败时,不应抛出异常,且应写入运行态状态。
/// </summary>
/// <returns>异步测试任务。</returns>
[Fact]
public async Task ProbeSftpOnStartupAsync_ShouldUpdateSnapshot_WhenConnectionFails()
{
var stateStore = new AppStateStore();
var service = new WorkflowHostedService(
new FakePlcService(),
new FakeScannerService(),
new FakeSftpLookupService
{
TestOutcome = new SftpConnectionTestOutcome
{
IsSuccess = false,
IsSystemError = true,
StatusMessage = "启动探活失败"
}
},
new FakeAndonService(),
stateStore,
new AppConfig(),
new FakeAppLogger<WorkflowHostedService>());
await service.ProbeSftpOnStartupAsync(CancellationToken.None);
Assert.Equal("异常", stateStore.GetSnapshot().SftpStatus);
}
private sealed class FakePlcService : IPlcService
{
public Task ForceReconnectAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task<PlcSignalSnapshot> ReadSignalsAsync(CancellationToken cancellationToken) => Task.FromResult(new PlcSignalSnapshot());
public Task WriteStateAsync(PlcProcessState state, CancellationToken cancellationToken) => Task.CompletedTask;
}
private sealed class FakeScannerService : IScannerService
{
public Task ForceReconnectAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task<bool> TestConnectionAsync(CancellationToken cancellationToken) => Task.FromResult(true);
public Task<ScanOperationResult> TriggerScanAsync(CancellationToken cancellationToken) => Task.FromResult(new ScanOperationResult());
}
private sealed class FakeSftpLookupService : ISftpLookupService
{
public SftpConnectionTestOutcome TestOutcome { get; set; } = new();
public Task<SftpCheckOutcome> CheckFileAsync(string barcode, CancellationToken cancellationToken) => Task.FromResult(new SftpCheckOutcome());
public Task<SftpConnectionTestOutcome> TestConnectionAsync(SftpOptions? options, CancellationToken cancellationToken)
{
return Task.FromResult(TestOutcome);
}
}
private sealed class FakeAndonService : IAndonService
{
public Task<AndonOperationResult> RaiseAlarmAsync(AndonAlarmRequest request, CancellationToken cancellationToken)
=> Task.FromResult(new AndonOperationResult());
public Task<AndonOperationResult> TestAsync(CancellationToken cancellationToken)
=> Task.FromResult(new AndonOperationResult());
}
private sealed class FakeAppLogger<TCategoryName> : IAppLogger<TCategoryName>
{
public void LogError(string message, bool showInUi = false, params object?[] args) { }
public void LogError(Exception exception, string message, bool showInUi = false, params object?[] args) { }
public void LogInformation(string message, bool showInUi = false, params object?[] args) { }
public void LogWarning(string message, bool showInUi = false, params object?[] args) { }
public void LogWarning(Exception exception, string message, bool showInUi = false, params object?[] args) { }
}
}