use crate::tui::onboarding::{AuthField, OnboardingStep, OnboardingWizard, WizardAction};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
fn key(code: KeyCode) -> KeyEvent {
KeyEvent::new(code, KeyModifiers::NONE)
}
#[allow(clippy::field_reassign_with_default)]
fn quick_jump_wizard_on_model_step() -> OnboardingWizard {
let mut w = OnboardingWizard::default();
w.quick_jump = true;
w.step = OnboardingStep::ProviderAuth;
w.auth_field = AuthField::Model;
w.ps.models = vec!["foo".to_string(), "bar".to_string()];
w.ps.selected_model = 0;
w
}
#[allow(clippy::field_reassign_with_default)]
fn quick_jump_wizard_on_custom_context_window() -> OnboardingWizard {
let mut w = OnboardingWizard::default();
w.quick_jump = true;
w.step = OnboardingStep::ProviderAuth;
w.auth_field = AuthField::CustomContextWindow;
w.ps.custom_name = "dialagram".to_string();
w.ps.custom_model = "qwen-3.7-max-thinking".to_string();
w.ps.context_window = "200000".to_string();
w
}
#[test]
fn enter_on_model_field_commits_quick_jump() {
let mut w = quick_jump_wizard_on_model_step();
let action = w.handle_key(key(KeyCode::Enter));
assert_eq!(
action,
WizardAction::QuickJumpDone,
"Enter on Model is the user's explicit confirmation — must commit"
);
}
#[test]
fn tab_on_model_field_does_not_commit() {
let mut w = quick_jump_wizard_on_model_step();
let action = w.handle_key(key(KeyCode::Tab));
assert!(
!matches!(action, WizardAction::QuickJumpDone),
"Tab on Model must NOT trigger commit — only Enter is the confirmation. \
Pre-fix: Tab called next_step() which auto-saved (2026-05-28 bug)"
);
assert!(
!w.quick_jump_done,
"quick_jump_done must stay false after Tab"
);
}
#[test]
fn down_on_model_field_does_not_commit() {
let mut w = quick_jump_wizard_on_model_step();
let action = w.handle_key(key(KeyCode::Down));
assert!(
!matches!(action, WizardAction::QuickJumpDone),
"Down on Model must navigate the model list, never commit"
);
assert!(!w.quick_jump_done);
}
#[test]
fn backtab_on_model_field_does_not_commit() {
let mut w = quick_jump_wizard_on_model_step();
let action = w.handle_key(key(KeyCode::BackTab));
assert!(
!matches!(action, WizardAction::QuickJumpDone),
"BackTab on Model goes back to ApiKey, must not commit"
);
assert!(!w.quick_jump_done);
}
#[test]
fn escape_on_model_field_in_quick_jump_cancels_not_commits() {
let mut w = quick_jump_wizard_on_model_step();
let action = w.handle_key(key(KeyCode::Esc));
assert_eq!(
action,
WizardAction::Cancel,
"Escape in quick_jump must always cancel cleanly, never commit"
);
assert!(!w.quick_jump_done);
}
#[test]
fn enter_on_custom_context_window_commits() {
let mut w = quick_jump_wizard_on_custom_context_window();
let action = w.handle_key(key(KeyCode::Enter));
assert_eq!(
action,
WizardAction::QuickJumpDone,
"Enter on CustomContextWindow (last step of custom flow) is the explicit confirmation"
);
}
#[test]
fn tab_on_custom_context_window_does_not_commit() {
let mut w = quick_jump_wizard_on_custom_context_window();
let action = w.handle_key(key(KeyCode::Tab));
assert!(
!matches!(action, WizardAction::QuickJumpDone),
"Tab on CustomContextWindow must NOT commit (pre-fix it did)"
);
assert!(!w.quick_jump_done);
}
#[test]
fn down_on_custom_context_window_does_not_commit() {
let mut w = quick_jump_wizard_on_custom_context_window();
let action = w.handle_key(key(KeyCode::Down));
assert!(
!matches!(action, WizardAction::QuickJumpDone),
"Down on CustomContextWindow must NOT commit (pre-fix it did)"
);
assert!(!w.quick_jump_done);
}