test(tui): cover approval input after message drain

This commit is contained in:
Hunter B
2026-05-30 21:43:24 -07:00
parent bfb0ccc9b4
commit b135373bf5
2 changed files with 62 additions and 8 deletions
+19 -8
View File
@@ -1940,12 +1940,8 @@ async fn run_event_loop(
} else {
let tool_input = input;
if tool_name == "apply_patch" {
maybe_add_patch_preview(app, &tool_input);
}
// Create approval request and show overlay
let request = ApprovalRequest::new(
push_approval_request_view(
app,
&id,
&tool_name,
&description,
@@ -1961,8 +1957,6 @@ async fn run_event_loop(
"mode": app.mode.label(),
}),
);
app.view_stack
.push(ApprovalView::new_for_locale(request, app.ui_locale));
app.status_message = Some(format!(
"Approval required for '{tool_name}': {description}"
));
@@ -6399,6 +6393,23 @@ async fn handle_view_events(
Ok(false)
}
fn push_approval_request_view(
app: &mut App,
id: &str,
tool_name: &str,
description: &str,
tool_input: &serde_json::Value,
approval_key: &str,
) {
if tool_name == "apply_patch" {
maybe_add_patch_preview(app, tool_input);
}
let request = ApprovalRequest::new(id, tool_name, description, tool_input, approval_key);
app.view_stack
.push(ApprovalView::new_for_locale(request, app.ui_locale));
}
struct ApprovalDecisionEvent {
tool_id: String,
tool_name: String,
+43
View File
@@ -5202,6 +5202,49 @@ fn message_complete_drain_preserves_thinking_when_thinking_complete_lost() {
);
}
#[test]
fn approval_prompt_uses_event_input_after_message_complete_drain() {
let mut app = create_test_app();
app.pending_tool_uses.push((
"tool-1".to_string(),
"exec_shell".to_string(),
serde_json::json!({"command": "stale value from drained list"}),
));
// Mirror the old race: MessageComplete drains pending tool uses before
// ApprovalRequired is handled. The approval modal must still show the
// non-empty input carried directly on the ApprovalRequired event.
app.pending_tool_uses.clear();
let event_input = serde_json::json!({
"command": "cargo test -p codewhale-tui approval",
"workdir": "/repo",
});
push_approval_request_view(
&mut app,
"tool-1",
"exec_shell",
"Run cargo tests",
&event_input,
"approval-key",
);
let mut view = app.view_stack.pop().expect("approval view");
let approval = view
.as_any_mut()
.downcast_mut::<ApprovalView>()
.expect("approval view");
let action = approval.handle_key(KeyEvent::new(KeyCode::Char('v'), KeyModifiers::NONE));
let ViewAction::Emit(ViewEvent::OpenTextPager { content, .. }) = action else {
panic!("expected approval params pager");
};
assert!(content.contains("cargo test -p codewhale-tui approval"));
assert!(content.contains("/repo"));
assert!(!content.contains("stale value from drained list"));
assert_ne!(content.trim(), "{}");
}
#[test]
fn second_thinking_block_appends_new_entry_in_same_active_cell() {
// Real V4 turns can emit Thinking → Tool → Thinking → Tool before any