mirror of
https://github.com/openai/codex.git
synced 2026-05-03 02:46:39 +00:00
feat(tui) Permissions update history item (#11550)
## Summary We should document in the tui when you switch permissions! ## Testing - [x] Added unit tests - [x] Tested locally
This commit is contained in:
@@ -20,6 +20,8 @@ use codex_core::config::Config;
|
||||
use codex_core::config::ConfigBuilder;
|
||||
use codex_core::config::Constrained;
|
||||
use codex_core::config::ConstraintError;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_core::config::types::WindowsSandboxModeToml;
|
||||
use codex_core::config_loader::RequirementSource;
|
||||
use codex_core::features::Feature;
|
||||
use codex_core::models_manager::manager::ModelsManager;
|
||||
@@ -5430,6 +5432,196 @@ async fn approvals_popup_navigation_skips_disabled() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn permissions_selection_emits_history_cell_when_selection_changes() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
chat.config.notices.hide_world_writable_warning = Some(true);
|
||||
chat.set_windows_sandbox_mode(Some(WindowsSandboxModeToml::Unelevated));
|
||||
}
|
||||
chat.config.notices.hide_full_access_warning = Some(true);
|
||||
|
||||
chat.open_permissions_popup();
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Down));
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
|
||||
let cells = drain_insert_history(&mut rx);
|
||||
assert_eq!(
|
||||
cells.len(),
|
||||
1,
|
||||
"expected one permissions selection history cell"
|
||||
);
|
||||
let rendered = lines_to_single_string(&cells[0]);
|
||||
assert!(
|
||||
rendered.contains("Permissions updated to"),
|
||||
"expected permissions selection history message, got: {rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn permissions_selection_history_snapshot_after_mode_switch() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
chat.config.notices.hide_world_writable_warning = Some(true);
|
||||
chat.set_windows_sandbox_mode(Some(WindowsSandboxModeToml::Unelevated));
|
||||
}
|
||||
chat.config.notices.hide_full_access_warning = Some(true);
|
||||
|
||||
chat.open_permissions_popup();
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Down));
|
||||
#[cfg(target_os = "windows")]
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Down));
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
|
||||
let cells = drain_insert_history(&mut rx);
|
||||
assert_eq!(cells.len(), 1, "expected one mode-switch history cell");
|
||||
assert_snapshot!(
|
||||
"permissions_selection_history_after_mode_switch",
|
||||
lines_to_single_string(&cells[0])
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn permissions_selection_history_snapshot_full_access_to_default() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
chat.config.notices.hide_world_writable_warning = Some(true);
|
||||
chat.set_windows_sandbox_mode(Some(WindowsSandboxModeToml::Unelevated));
|
||||
}
|
||||
chat.config.notices.hide_full_access_warning = Some(true);
|
||||
chat.config
|
||||
.permissions
|
||||
.approval_policy
|
||||
.set(AskForApproval::Never)
|
||||
.expect("set approval policy");
|
||||
chat.config
|
||||
.permissions
|
||||
.sandbox_policy
|
||||
.set(SandboxPolicy::DangerFullAccess)
|
||||
.expect("set sandbox policy");
|
||||
|
||||
chat.open_permissions_popup();
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Up));
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
|
||||
let cells = drain_insert_history(&mut rx);
|
||||
assert_eq!(cells.len(), 1, "expected one mode-switch history cell");
|
||||
let rendered = lines_to_single_string(&cells[0]);
|
||||
#[cfg(target_os = "windows")]
|
||||
insta::with_settings!({ snapshot_suffix => "windows" }, {
|
||||
assert_snapshot!("permissions_selection_history_full_access_to_default", rendered);
|
||||
});
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
assert_snapshot!(
|
||||
"permissions_selection_history_full_access_to_default",
|
||||
rendered
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn permissions_selection_emits_history_cell_when_current_is_selected() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
chat.config.notices.hide_world_writable_warning = Some(true);
|
||||
chat.set_windows_sandbox_mode(Some(WindowsSandboxModeToml::Unelevated));
|
||||
}
|
||||
chat.config
|
||||
.permissions
|
||||
.approval_policy
|
||||
.set(AskForApproval::OnRequest)
|
||||
.expect("set approval policy");
|
||||
chat.config
|
||||
.permissions
|
||||
.sandbox_policy
|
||||
.set(SandboxPolicy::new_workspace_write_policy())
|
||||
.expect("set sandbox policy");
|
||||
|
||||
chat.open_permissions_popup();
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
|
||||
let cells = drain_insert_history(&mut rx);
|
||||
assert_eq!(
|
||||
cells.len(),
|
||||
1,
|
||||
"expected history cell even when selecting current permissions"
|
||||
);
|
||||
let rendered = lines_to_single_string(&cells[0]);
|
||||
assert!(
|
||||
rendered.contains("Permissions updated to"),
|
||||
"expected permissions update history message, got: {rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn permissions_full_access_history_cell_emitted_only_after_confirmation() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
chat.config.notices.hide_world_writable_warning = Some(true);
|
||||
chat.set_windows_sandbox_mode(Some(WindowsSandboxModeToml::Unelevated));
|
||||
}
|
||||
chat.config.notices.hide_full_access_warning = None;
|
||||
|
||||
chat.open_permissions_popup();
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Down));
|
||||
#[cfg(target_os = "windows")]
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Down));
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
|
||||
let mut open_confirmation_event = None;
|
||||
let mut cells_before_confirmation = Vec::new();
|
||||
while let Ok(event) = rx.try_recv() {
|
||||
match event {
|
||||
AppEvent::InsertHistoryCell(cell) => {
|
||||
cells_before_confirmation.push(cell.display_lines(80));
|
||||
}
|
||||
AppEvent::OpenFullAccessConfirmation {
|
||||
preset,
|
||||
return_to_permissions,
|
||||
} => {
|
||||
open_confirmation_event = Some((preset, return_to_permissions));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if cfg!(not(target_os = "windows")) {
|
||||
assert!(
|
||||
cells_before_confirmation.is_empty(),
|
||||
"did not expect history cell before confirming full access"
|
||||
);
|
||||
}
|
||||
let (preset, return_to_permissions) =
|
||||
open_confirmation_event.expect("expected full access confirmation event");
|
||||
chat.open_full_access_confirmation(preset, return_to_permissions);
|
||||
|
||||
let popup = render_bottom_popup(&chat, 80);
|
||||
assert!(
|
||||
popup.contains("Enable full access?"),
|
||||
"expected full access confirmation popup, got: {popup}"
|
||||
);
|
||||
|
||||
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
|
||||
let cells_after_confirmation = drain_insert_history(&mut rx);
|
||||
let total_history_cells = cells_before_confirmation.len() + cells_after_confirmation.len();
|
||||
assert_eq!(
|
||||
total_history_cells, 1,
|
||||
"expected one full access history cell total"
|
||||
);
|
||||
let rendered = if !cells_before_confirmation.is_empty() {
|
||||
lines_to_single_string(&cells_before_confirmation[0])
|
||||
} else {
|
||||
lines_to_single_string(&cells_after_confirmation[0])
|
||||
};
|
||||
assert!(
|
||||
rendered.contains("Permissions updated to Full Access"),
|
||||
"expected full access update history message, got: {rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Snapshot test: command approval modal
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user