pacsea 0.8.2

A fast, friendly TUI for browsing and installing Arch and AUR packages with built-in news and security scanning
Documentation
//! Unit tests for scan configuration modal handlers.

use crate::state::AppState;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};

use crate::events::modals::scan::handle_scan_config;

#[test]
/// What: Verify `ScanConfig` modal handles Esc to close.
///
/// Inputs:
/// - `ScanConfig` modal, Esc key event.
///
/// Output:
/// - Modal is closed or previous modal is restored.
///
/// Details:
/// - Tests that Esc closes the `ScanConfig` modal.
fn scan_config_esc_closes_modal() {
    let mut app = AppState {
        modal: crate::state::Modal::ScanConfig {
            do_clamav: false,
            do_trivy: false,
            do_semgrep: false,
            do_shellcheck: false,
            do_virustotal: false,
            do_custom: false,
            do_sleuth: false,
            cursor: 0,
        },
        ..Default::default()
    };

    let mut do_clamav = false;
    let mut do_trivy = false;
    let mut do_semgrep = false;
    let mut do_shellcheck = false;
    let mut do_virustotal = false;
    let mut do_custom = false;
    let mut do_sleuth = false;
    let mut cursor = 0;

    let ke = KeyEvent::new(KeyCode::Esc, KeyModifiers::empty());
    let _ = handle_scan_config(
        ke,
        &mut app,
        &mut do_clamav,
        &mut do_trivy,
        &mut do_semgrep,
        &mut do_shellcheck,
        &mut do_virustotal,
        &mut do_custom,
        &mut do_sleuth,
        &mut cursor,
    );

    // Modal should be closed or previous modal restored
    match app.modal {
        crate::state::Modal::None | crate::state::Modal::Preflight { .. } => {}
        _ => panic!("Expected modal to be closed or previous modal restored"),
    }
}

#[test]
/// What: Verify `ScanConfig` modal handles navigation.
///
/// Inputs:
/// - `ScanConfig` modal, Down key event.
///
/// Output:
/// - Cursor moves down.
///
/// Details:
/// - Tests that navigation keys work in `ScanConfig` modal.
fn scan_config_navigation() {
    let mut app = AppState {
        modal: crate::state::Modal::ScanConfig {
            do_clamav: false,
            do_trivy: false,
            do_semgrep: false,
            do_shellcheck: false,
            do_virustotal: false,
            do_custom: false,
            do_sleuth: false,
            cursor: 0,
        },
        ..Default::default()
    };

    let mut do_clamav = false;
    let mut do_trivy = false;
    let mut do_semgrep = false;
    let mut do_shellcheck = false;
    let mut do_virustotal = false;
    let mut do_custom = false;
    let mut do_sleuth = false;
    let mut cursor = 0;

    let ke = KeyEvent::new(KeyCode::Down, KeyModifiers::empty());
    let _ = handle_scan_config(
        ke,
        &mut app,
        &mut do_clamav,
        &mut do_trivy,
        &mut do_semgrep,
        &mut do_shellcheck,
        &mut do_virustotal,
        &mut do_custom,
        &mut do_sleuth,
        &mut cursor,
    );

    assert_eq!(cursor, 1, "Cursor should move down");
}

#[test]
/// What: Verify `ScanConfig` modal handles toggle with Space.
///
/// Inputs:
/// - `ScanConfig` modal, Space key event on first option.
///
/// Output:
/// - `do_clamav` flag is toggled.
///
/// Details:
/// - Tests that Space toggles scan options in `ScanConfig` modal.
fn scan_config_toggle() {
    let mut app = AppState {
        modal: crate::state::Modal::ScanConfig {
            do_clamav: false,
            do_trivy: false,
            do_semgrep: false,
            do_shellcheck: false,
            do_virustotal: false,
            do_custom: false,
            do_sleuth: false,
            cursor: 0,
        },
        ..Default::default()
    };

    let mut do_clamav = false;
    let mut do_trivy = false;
    let mut do_semgrep = false;
    let mut do_shellcheck = false;
    let mut do_virustotal = false;
    let mut do_custom = false;
    let mut do_sleuth = false;
    let mut cursor = 0;

    let ke = KeyEvent::new(KeyCode::Char(' '), KeyModifiers::empty());
    let _ = handle_scan_config(
        ke,
        &mut app,
        &mut do_clamav,
        &mut do_trivy,
        &mut do_semgrep,
        &mut do_shellcheck,
        &mut do_virustotal,
        &mut do_custom,
        &mut do_sleuth,
        &mut cursor,
    );

    assert!(do_clamav, "do_clamav should be toggled to true");
}

#[test]
/// What: Verify `ScanConfig` modal handles Enter to execute scan.
///
/// Inputs:
/// - `ScanConfig` modal with options selected, Enter key event.
///
/// Output:
/// - Scan is executed (spawns terminal - will fail in test environment).
///
/// Details:
/// - Tests that Enter triggers scan execution.
/// - Note: This will spawn a terminal, so it's expected to fail in test environment.
fn scan_config_enter_executes() {
    let mut app = AppState {
        modal: crate::state::Modal::ScanConfig {
            do_clamav: true,
            do_trivy: false,
            do_semgrep: false,
            do_shellcheck: false,
            do_virustotal: false,
            do_custom: false,
            do_sleuth: false,
            cursor: 0,
        },
        pending_install_names: Some(vec!["test-pkg".to_string()]),
        ..Default::default()
    };

    let mut do_clamav = true;
    let mut do_trivy = false;
    let mut do_semgrep = false;
    let mut do_shellcheck = false;
    let mut do_virustotal = false;
    let mut do_custom = false;
    let mut do_sleuth = false;
    let mut cursor = 0;

    let ke = KeyEvent::new(KeyCode::Enter, KeyModifiers::empty());
    let _ = handle_scan_config(
        ke,
        &mut app,
        &mut do_clamav,
        &mut do_trivy,
        &mut do_semgrep,
        &mut do_shellcheck,
        &mut do_virustotal,
        &mut do_custom,
        &mut do_sleuth,
        &mut cursor,
    );

    // Modal should transition (scan spawns terminal)
    // The exact modal depends on implementation, but it should not be ScanConfig anymore
    if let crate::state::Modal::ScanConfig { .. } = app.modal {
        // If still ScanConfig, that's also acceptable (scan might be async)
    } else {
        // Modal changed - scan was triggered
    }
}