F4: DetailsIslandView/TasksIslandView hatten je eine view-lokale Confirm/Error-Dialog-Kopie, teils mit hartkodiertem "Delete"-Knopf fuer jede Aktion (inkl. der Stash+Merge-Bestaetigung, die nichts loescht). Beide Kopien entfernt; DetailsIslandViewModel/TasksIslandViewModel routen Confirm/Error jetzt durch den geteilten Dialogs-Seam (IDialogService, propagiert vom Shell wie schon bei Lists/Tasks) statt ueber eine vom Code-behind gesetzte Func-Property. IDialogService.ConfirmAsync bekommt einen optionalen confirmLabel-Parameter (Default: lokalisiertes "Confirm"); nur die echten Delete-Aktionen (Task loeschen, abgeschlossene Tasks leeren) uebergeben das lokalisierte "Delete"-Label. F5: "Cancel"/"Confirm"/"Delete"/"OK" und die Titel "Confirm"/"Error" durch Loc.T mit neuen Keys unter "dialog.*" ersetzt (en.json + de.json). Mission Controls eigene Dialog-Kopie bleibt bestehen (eigenes Fenster, WindowDialogService ist an den Haupt-Owner gebunden) — nur ihre Labels wurden lokalisiert. Out of scope (siehe Task-Beschreibung): die Nachrichtentexte der Dialoge bleiben unlokalisiert.
65 lines
3.0 KiB
C#
65 lines
3.0 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using ClaudeDo.Ui.Services;
|
|
using ClaudeDo.Ui.ViewModels;
|
|
using ClaudeDo.Ui.ViewModels.Conflicts;
|
|
using ClaudeDo.Ui.ViewModels.Modals;
|
|
|
|
namespace ClaudeDo.Ui.Tests;
|
|
|
|
// Covers the worker-menu "Shutdown" command: a confirm dialog gates the actual kill-worker +
|
|
// close-app action. ShutdownOperation is a test seam standing in for the real body, so these
|
|
// tests only assert the confirm gate, never a real process kill.
|
|
public class IslandsShellViewModelShutdownTests
|
|
{
|
|
[Fact]
|
|
public async Task Declined_DoesNotInvokeShutdownOperation()
|
|
{
|
|
var invoked = false;
|
|
var vm = new IslandsShellViewModel
|
|
{
|
|
Dialogs = new FakeDialogService(confirmResult: false),
|
|
ShutdownOperation = () => invoked = true,
|
|
};
|
|
|
|
await vm.ShutdownCommand.ExecuteAsync(null);
|
|
|
|
Assert.False(invoked);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Confirmed_InvokesShutdownOperation()
|
|
{
|
|
var invoked = false;
|
|
var vm = new IslandsShellViewModel
|
|
{
|
|
Dialogs = new FakeDialogService(confirmResult: true),
|
|
ShutdownOperation = () => invoked = true,
|
|
};
|
|
|
|
await vm.ShutdownCommand.ExecuteAsync(null);
|
|
|
|
Assert.True(invoked);
|
|
}
|
|
|
|
private sealed class FakeDialogService(bool confirmResult) : IDialogService
|
|
{
|
|
public Task<bool> ConfirmAsync(string message, string? confirmLabel = null) => Task.FromResult(confirmResult);
|
|
|
|
public Task ShowAboutAsync(AboutModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowWeeklyReportAsync(WeeklyReportModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowUsageMonitorAsync(UsageMonitorModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowSettingsAsync(SettingsModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowListSettingsAsync(ListSettingsModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowRepoImportAsync(RepoImportModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowWorktreesOverviewAsync(WorktreesOverviewModalViewModel vm) => throw new NotImplementedException();
|
|
public Task<IReadOnlyList<string>?> ShowMergeHelperSelectionAsync(MergeHelperSelectionModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowWorkerConnectionAsync(WorkerConnectionModalViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowConflictResolverAsync(ConflictResolverViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowLogVisualizerAsync(LogVisualizerViewModel vm) => throw new NotImplementedException();
|
|
public Task ShowErrorAsync(string message) => Task.CompletedTask;
|
|
public void ShowMissionControl(MissionControlViewModel vm) => throw new NotImplementedException();
|
|
public void ShowCheatSheets(CheatSheetsViewModel vm) => throw new NotImplementedException();
|
|
}
|
|
}
|