feat(review): gate Approve & Merge behind opening the diff
Approve & Merge is disabled until the pending changes have been inspected: DetailsIslandViewModel tracks ReviewDiffViewed (reset on task switch and on every state change), MergeSectionViewModel raises DiffViewed when a diff or combined diff is opened and exposes HasReviewableDiff, and a hint sits next to the button. A review with nothing to inspect (sandbox run, no worktree) approves straight through. ClaudeDo-Task: f9809a93
This commit is contained in:
@@ -98,4 +98,43 @@ public class DetailsIslandReviewActionsTests : IDisposable
|
||||
vm.ReviewFeedback = " ";
|
||||
Assert.False(vm.RejectReviewCommand.CanExecute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Approve_IsEnabled_WhenThereIsNothingToReview()
|
||||
{
|
||||
// A childless sandbox run has no worktree diff to inspect, so the gate must
|
||||
// not block it — it approves straight through.
|
||||
var vm = BuildVm(new RecordingWorkerClient());
|
||||
vm.Bind(new TaskRowViewModel { Id = "task-nodiff-1", Status = TaskStatus.WaitingForReview });
|
||||
vm.Monitor.ApplyState(TaskStatus.WaitingForReview);
|
||||
|
||||
Assert.False(vm.Merge.HasReviewableDiff);
|
||||
Assert.False(vm.ShowReviewDiffHint);
|
||||
Assert.True(vm.ApproveReviewCommand.CanExecute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Approve_IsGatedUntilDiffOpened_AndReLocksOnNewRun()
|
||||
{
|
||||
var vm = BuildVm(new RecordingWorkerClient());
|
||||
vm.Bind(new TaskRowViewModel { Id = "task-diff-1", Status = TaskStatus.WaitingForReview });
|
||||
vm.Merge.SyncWorktree("/tmp/wt", null, null, "Active", null);
|
||||
vm.Monitor.ApplyState(TaskStatus.WaitingForReview);
|
||||
|
||||
// There is a diff to read, but it has not been opened → merge is blocked.
|
||||
Assert.True(vm.Merge.HasReviewableDiff);
|
||||
Assert.True(vm.ShowReviewDiffHint);
|
||||
Assert.False(vm.ApproveReviewCommand.CanExecute(null));
|
||||
|
||||
// Opening the diff records the inspection and unlocks the merge.
|
||||
vm.Merge.DiffViewed?.Invoke();
|
||||
Assert.False(vm.ShowReviewDiffHint);
|
||||
Assert.True(vm.ApproveReviewCommand.CanExecute(null));
|
||||
|
||||
// A new run means a fresh diff — the gate re-engages.
|
||||
vm.Monitor.ApplyState(TaskStatus.Running);
|
||||
vm.Monitor.ApplyState(TaskStatus.WaitingForReview);
|
||||
Assert.True(vm.ShowReviewDiffHint);
|
||||
Assert.False(vm.ApproveReviewCommand.CanExecute(null));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user