apollo-errors 0.7.0

Structured error handling with automatic format conversion
Documentation
//! Tests for struct error support
use apollo_errors::FormatConfig;

mod common;

use apollo_errors::Error as ErrorTrait;
use common::{ConfigStructError, SimpleStructError};
use http::StatusCode;
use insta::assert_json_snapshot;

// ============================================================================
// Display tests
// ============================================================================

#[test]
fn test_simple_struct_display() {
    let error = SimpleStructError;
    assert_eq!(error.to_string(), "Simple struct error occurred");
}

#[test]
fn test_struct_with_fields_display() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    assert_eq!(error.to_string(), "Configuration error: invalid port 8080");
}

// ============================================================================
// JSON format tests
// ============================================================================

#[test]
fn test_simple_struct_json() {
    let error = SimpleStructError;
    let json = error.to_json(FormatConfig::default()).unwrap();
    assert_json_snapshot!(json, @r#"
    {
      "error": "structs::simple",
      "message": "Simple struct error occurred"
    }
    "#);
}

#[test]
fn test_struct_with_fields_json() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    let json = error.to_json(FormatConfig::default()).unwrap();
    assert_json_snapshot!(json, @r#"
    {
      "config_path": "/etc/config.toml",
      "error": "structs::config_error",
      "message": "Configuration error: invalid port 8080",
      "port": 8080
    }
    "#);
}

// ============================================================================
// GraphQL format tests
// ============================================================================

#[test]
fn test_simple_struct_graphql() {
    let error = SimpleStructError;
    let graphql = error.to_graphql(FormatConfig::default()).unwrap();
    assert_json_snapshot!(graphql, @r#"
    {
      "extensions": {
        "code": "structs::simple"
      },
      "message": "Simple struct error occurred"
    }
    "#);
}

#[test]
fn test_struct_with_fields_graphql() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    let graphql = error.to_graphql(FormatConfig::default()).unwrap();
    assert_json_snapshot!(graphql, @r#"
    {
      "extensions": {
        "code": "structs::config_error",
        "config_path": "/etc/config.toml",
        "port": 8080
      },
      "message": "Configuration error: invalid port 8080"
    }
    "#);
}

// ============================================================================
// HTTP status tests
// ============================================================================

#[test]
fn test_simple_struct_default_http_status() {
    let error = SimpleStructError;
    assert_eq!(error.http_status(), StatusCode::INTERNAL_SERVER_ERROR);
}

#[test]
fn test_struct_custom_http_status() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    assert_eq!(error.http_status(), StatusCode::BAD_REQUEST);
}

// ============================================================================
// Text format tests
// ============================================================================

#[test]
fn test_simple_struct_text() {
    let error = SimpleStructError;
    assert_eq!(
        error.to_text(FormatConfig::default()),
        "[structs::simple] Simple struct error occurred"
    );
}

#[test]
fn test_struct_with_fields_text() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    assert_eq!(
        error.to_text(FormatConfig::default()),
        "[structs::config_error] Configuration error: invalid port 8080"
    );
}

// ============================================================================
// Diagnostic trait tests
// ============================================================================

#[test]
fn test_struct_diagnostic_code() {
    use miette::Diagnostic;

    let error = SimpleStructError;
    let code = error.code().map(|c| c.to_string());
    assert_eq!(code, Some("structs::simple".to_string()));
}

#[test]
fn test_struct_diagnostic_help() {
    use miette::Diagnostic;

    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    let help = error.help().map(|h| h.to_string());
    assert_eq!(help, Some("Check your configuration file".to_string()));
}

// ============================================================================
// Debug trait tests
// ============================================================================

#[test]
fn test_simple_struct_debug() {
    let error = SimpleStructError;
    let debug = format!("{:?}", error);
    assert_eq!(debug, "SimpleStructError");
}

#[test]
fn test_struct_with_fields_debug() {
    let error = ConfigStructError {
        port: 8080,
        config_path: "/etc/config.toml".to_string(),
    };
    let debug = format!("{:?}", error);
    assert!(debug.contains("ConfigStructError"));
    assert!(debug.contains("port"));
    assert!(debug.contains("8080"));
}