guardy 0.2.4

Fast, secure git hooks in Rust with secret scanning and protected file synchronization
Documentation
use anyhow::Result;

#[tokio::test]
async fn test_validate_hooks_config_success() -> Result<()> {
    // Test validation with valid default configuration
    let result = guardy::hooks::validate::validate_hooks_config().await;

    // Default config should be valid (even if empty)
    assert!(
        result.is_ok(),
        "Default hooks config should validate successfully: {result:?}"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_empty_config() -> Result<()> {
    // Test validation when no hooks are configured
    // This should pass with warnings but not errors
    let result = guardy::hooks::validate::validate_hooks_config().await;

    assert!(
        result.is_ok(),
        "Empty hooks config should validate with warnings: {result:?}"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_hook_definition_structure() -> Result<()> {
    // Test the internal validation logic by checking that it handles
    // basic structure validation correctly
    let result = guardy::hooks::validate::validate_hooks_config().await;

    // Should not panic or crash
    assert!(
        result.is_ok() || result.is_err(),
        "Validation should complete without panicking"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_with_configuration_loaded() -> Result<()> {
    // Test validation when we have actual configuration loaded
    // This tests that the validation works with the global CONFIG
    let hooks_config = &guardy::config::CONFIG.hooks;

    // Verify configuration is accessible
    let _pre_commit_len = hooks_config.pre_commit.commands.len();
    let _commit_msg_len = hooks_config.commit_msg.commands.len();
    // Just verify we can access the configuration without panicking

    // Now test validation
    let result = guardy::hooks::validate::validate_hooks_config().await;

    assert!(
        result.is_ok(),
        "Loaded hooks config should validate: {result:?}"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_glob_pattern_handling() -> Result<()> {
    // Test that validation handles glob patterns correctly
    // This is an indirect test since we can't easily mock the config
    let result = guardy::hooks::validate::validate_hooks_config().await;

    // Should handle any glob patterns in the configuration without crashing
    assert!(
        result.is_ok() || result.is_err(),
        "Should handle glob patterns gracefully"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_all_hook_types() -> Result<()> {
    // Test that validation checks all supported hook types
    let result = guardy::hooks::validate::validate_hooks_config().await;

    // Should validate all hook types: pre-commit, commit-msg, post-checkout, post-commit,
    // post-merge
    assert!(result.is_ok(), "Should validate all hook types: {result:?}");

    Ok(())
}

#[tokio::test]
async fn test_validate_returns_appropriate_result() -> Result<()> {
    // Test that validation returns appropriate success/failure
    let result = guardy::hooks::validate::validate_hooks_config().await;

    match result {
        Ok(()) => {
            // Configuration is valid - this is expected for default config
            // Configuration validated successfully
        }
        Err(e) => {
            // Configuration has errors - ensure error message is meaningful
            let error_msg = e.to_string();
            assert!(!error_msg.is_empty(), "Error message should not be empty");
            assert!(
                error_msg.contains("error") || error_msg.contains("Error"),
                "Error message should indicate validation failure: {error_msg}"
            );
        }
    }

    Ok(())
}

#[tokio::test]
async fn test_validate_performance() -> Result<()> {
    // Test that validation completes in reasonable time
    use std::time::Instant;

    let start = Instant::now();
    let result = guardy::hooks::validate::validate_hooks_config().await;
    let duration = start.elapsed();

    // Validation should complete quickly (< 1 second)
    assert!(
        duration.as_secs() < 1,
        "Validation should complete quickly, took: {duration:?}"
    );

    // And should not fail due to performance issues
    assert!(
        result.is_ok() || result.is_err(),
        "Should complete without timeout"
    );

    Ok(())
}

#[tokio::test]
async fn test_validate_handles_empty_strings() -> Result<()> {
    // Test that validation handles edge cases like empty strings gracefully
    let result = guardy::hooks::validate::validate_hooks_config().await;

    // Should not crash on empty strings or null values
    assert!(
        result.is_ok() || result.is_err(),
        "Should handle empty strings gracefully"
    );

    Ok(())
}