pg-api 0.2.0

A high-performance PostgreSQL REST API driver with rate limiting, connection pooling, and observability
//! Testes de integração para health check
//!
//! Estes testes verificam se o servidor está respondendo corretamente
//! nos endpoints de health e status.

use std::time::Duration;

/// Testa o endpoint /health
#[tokio::test]
async fn test_health_endpoint() {
    // Este teste assume que o servidor está rodando em localhost:8580
    // Em um ambiente de CI, você usaria testcontainers ou um mock server
    let client = reqwest::Client::new();
    
    // Tenta conectar com timeout
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client.get("http://localhost:8580/health").send()
    ).await;
    
    // Se o servidor não estiver rodando, o teste é ignorado
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    assert_eq!(response.status(), 200);
    
    let body: serde_json::Value = response.json().await.unwrap();
    assert_eq!(body["status"], "healthy");
    assert!(body["service"].as_str().is_some());
    assert!(body["version"].as_str().is_some());
}

/// Testa que /health não requer autenticação
#[tokio::test]
async fn test_health_no_auth_required() {
    let client = reqwest::Client::new();
    
    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;
        }
    };
    
    // Não deve retornar 401 (unauthorized)
    assert_ne!(response.status(), 401);
    assert_eq!(response.status(), 200);
}

/// Testa o endpoint /v1/status (requer autenticação)
#[tokio::test]
async fn test_status_endpoint_with_auth() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client
            .get("http://localhost:8580/v1/status")
            .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;
        }
    };
    
    // Pode retornar 200 (se auth válida) ou 401 (se auth inválida)
    // Mas não deve retornar 404
    assert_ne!(response.status(), 404);
}

/// Testa que /v1/status requer autenticação
#[tokio::test]
async fn test_status_requires_auth() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client.get("http://localhost:8580/v1/status").send()
    ).await;
    
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    // Sem autenticação deve retornar 401
    assert_eq!(response.status(), 401);
}

/// Testa o endpoint /docs (Swagger UI)
#[tokio::test]
async fn test_docs_endpoint() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client.get("http://localhost:8580/docs").send()
    ).await;
    
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    // Deve retornar 200 (HTML da documentação)
    assert_eq!(response.status(), 200);
    
    let content_type = response.headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("");
    
    assert!(content_type.contains("text/html"));
}

/// Testa o endpoint /openapi.json
#[tokio::test]
async fn test_openapi_endpoint() {
    let client = reqwest::Client::new();
    
    let result = tokio::time::timeout(
        Duration::from_secs(5),
        client.get("http://localhost:8580/openapi.json").send()
    ).await;
    
    let response = match result {
        Ok(Ok(resp)) => resp,
        _ => {
            println!("⚠️  Servidor não está rodando, pulando teste");
            return;
        }
    };
    
    assert_eq!(response.status(), 200);
    
    let body: serde_json::Value = response.json().await.unwrap();
    assert!(body.get("openapi").is_some() || body.get("swagger").is_some());
}