pg-api 0.2.0

A high-performance PostgreSQL REST API driver with rate limiting, connection pooling, and observability
//! Testes de integração para rate limiting
//!
//! Estes testes verificam o comportamento do rate limiting.

use std::time::Duration;

/// Testa que rate limit headers estão presentes
#[tokio::test]
async fn test_rate_limit_headers_present() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client
            .get("http://localhost:8580/v1/account")
            .header("X-API-Key", "sk_test_key")
            .send()
    ).await;
    
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    // Se autenticado, verifica headers de rate limit
    if response.status() == 200 {
        let headers = response.headers();
        
        // Verifica se algum header de rate limit está presente
        let has_rate_limit_header = headers.contains_key("x-ratelimit-limit")
            || headers.contains_key("X-RateLimit-Limit")
            || headers.contains_key("x-ratelimit-remaining")
            || headers.contains_key("X-RateLimit-Remaining");
        
        // Nota: Headers podem não estar presentes se rate limiting estiver desabilitado
        println!("Rate limit headers presentes: {}", has_rate_limit_header);
    }
}

/// Testa comportamento sob múltiplas requisições
#[tokio::test]
async fn test_multiple_requests() {
    let client = reqwest::Client::new();
    let mut success_count = 0;
    let mut rate_limited_count = 0;
    
    // Faz 10 requisições rápidas
    for i in 0..10 {
        let result = tokio::time::timeout(
            Duration::from_secs(5),
            client
                .get("http://localhost:8580/health")
                .send()
        ).await;
        
        match result {
            Ok(Ok(resp)) => {
                match resp.status() {
                    status if status.is_success() => success_count += 1,
                    status if status == 429 => rate_limited_count += 1,
                    _ => {}
                }
            }
            _ => {
                println!("⚠️  Servidor não está rodando, pulando teste");
                return;
            }
        }
        
        // Pequeno delay entre requisições
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
    
    println!("Sucessos: {}, Rate limited: {}", success_count, rate_limited_count);
    
    // Todas as requisições para /health devem ter sucesso (não tem rate limit)
    assert_eq!(success_count, 10, "Todas as requisições para /health devem ter sucesso");
}

/// Testa resposta 429 Too Many Requests
#[tokio::test]
async fn test_rate_limit_response() {
    // Este teste é difícil de reproduzir sem controle sobre o rate limiter
    // Em um teste real, você precisaria de uma conta com rate limit muito baixo
    // ou mockar o rate limiter
    
    println!("ℹ️  Este teste requer configuração específica de rate limit");
    println!("   Pulando teste de rate limit 429");
}

/// Testa que health check não é rate limited
#[tokio::test]
async fn test_health_not_rate_limited() {
    let client = reqwest::Client::new();
    
    // Faz várias requisições para /health
    for _ in 0..20 {
        let result = tokio::time::timeout(
            Duration::from_secs(5),
            client.get("http://localhost:8580/health").send()
        ).await;
        
        let response = match result {
            Ok(Ok(resp)) => resp,
            _ => {
                println!("⚠️  Servidor não está rodando, pulando teste");
                return;
            }
        };
        
        // Health check não deve ser rate limited
        assert_ne!(
            response.status(),
            429,
            "Health check não deve ser rate limited"
        );
        assert_eq!(response.status(), 200);
    }
}

/// Testa informações de rate limit no endpoint de uso
#[tokio::test]
async fn test_rate_limit_info_in_usage() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client
            .get("http://localhost:8580/v1/account/usage")
            .header("X-API-Key", "sk_test_key")
            .send()
    ).await;
    
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    if response.status() == 200 {
        let body: serde_json::Value = response.json().await.unwrap();
        
        // Verifica se há informação de rate limit na resposta
        if let Some(data) = body.get("data") {
            let has_rate_limit_info = data.get("rate_limit_remaining").is_some()
                || data.get("rate_limit").is_some();
            
            println!("Info de rate limit presente: {}", has_rate_limit_info);
        }
    }
}