mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
Introduce HostShutdownGate to serialize and record the first host shutdown request (Restart preferred over later Exit). Add tests (HostShutdownGateTests) and a tray-menu spec describing shutdown requirements. Integrate the gate into App: expose IsShutdownInProgress, ignore tray/settings/component-library actions during shutdown, reuse/track the fused component library window, ensure edit-mode exit on failures, and close the library during shutdown. Add TrySubmitShutdown to commit shutdown intent, schedule forced termination, perform exit cleanup, and invoke desktop lifetime shutdown. Update HostApplicationLifecycleService to use the new TrySubmitShutdown flow for Exit/Restart. Harden DesktopTrayService.Dispose to clear icons and dispose the tray icon safely. These changes ensure irreversible shutdown commits, prevent UI reopening during shutdown, preserve restart intent, and avoid duplicate or conflicting shutdown actions.
49 lines
1.5 KiB
C#
49 lines
1.5 KiB
C#
using LanMountainDesktop.Services;
|
|
using Xunit;
|
|
|
|
namespace LanMountainDesktop.Tests;
|
|
|
|
public sealed class HostShutdownGateTests
|
|
{
|
|
[Fact]
|
|
public void Submit_WhenFirstExitRequest_AcceptsAndRecordsExit()
|
|
{
|
|
var gate = new HostShutdownGate();
|
|
|
|
var submission = gate.Submit(HostShutdownMode.Exit);
|
|
|
|
Assert.True(submission.Accepted);
|
|
Assert.True(submission.IsFirstSubmission);
|
|
Assert.Equal(HostShutdownMode.Exit, submission.EffectiveMode);
|
|
Assert.True(gate.IsShutdownRequested);
|
|
Assert.Equal(HostShutdownMode.Exit, gate.EffectiveMode);
|
|
}
|
|
|
|
[Fact]
|
|
public void Submit_WhenDuplicateSameMode_AcceptsButDoesNotExecuteAgain()
|
|
{
|
|
var gate = new HostShutdownGate();
|
|
gate.Submit(HostShutdownMode.Exit);
|
|
|
|
var duplicate = gate.Submit(HostShutdownMode.Exit);
|
|
|
|
Assert.True(duplicate.Accepted);
|
|
Assert.False(duplicate.IsFirstSubmission);
|
|
Assert.Equal(HostShutdownMode.Exit, duplicate.EffectiveMode);
|
|
}
|
|
|
|
[Fact]
|
|
public void Submit_WhenExitArrivesAfterRestart_DoesNotOverwriteRestart()
|
|
{
|
|
var gate = new HostShutdownGate();
|
|
gate.Submit(HostShutdownMode.Restart);
|
|
|
|
var conflictingExit = gate.Submit(HostShutdownMode.Exit);
|
|
|
|
Assert.False(conflictingExit.Accepted);
|
|
Assert.False(conflictingExit.IsFirstSubmission);
|
|
Assert.Equal(HostShutdownMode.Restart, conflictingExit.EffectiveMode);
|
|
Assert.Equal(HostShutdownMode.Restart, gate.EffectiveMode);
|
|
}
|
|
}
|