use actix_web::http::StatusCode;
use athena_rs::error::{ErrorCategory, ProcessedError};
use athena_rs::error::{
sql_sanitizer::{extract_metadata, sanitize_and_extract, sanitize_error_message},
sqlx_parser::process_sqlx_error,
};
use serde_json::json;
#[test]
fn sql_sanitizer_sanitize_select_query() {
let error = "failed to execute select query: SELECT id, name FROM users WHERE email = $1: column 'email' does not exist";
let sanitized = sanitize_error_message(error);
assert!(!sanitized.contains("SELECT"));
assert!(!sanitized.contains("users"));
assert!(sanitized.contains("column"));
}
#[test]
fn sql_sanitizer_sanitize_insert_query() {
let error = "INSERT INTO users (name, email) VALUES ($1, $2): duplicate key value violates unique constraint \"users_email_key\"";
let sanitized = sanitize_error_message(error);
assert!(!sanitized.contains("INSERT INTO"));
assert!(!sanitized.contains("VALUES"));
assert!(sanitized.contains("constraint"));
}
#[test]
fn sql_sanitizer_sanitize_update_query() {
let error = "UPDATE users SET name = $1 WHERE id = $2: permission denied";
let sanitized = sanitize_error_message(error);
assert!(!sanitized.contains("UPDATE"));
assert!(!sanitized.contains("SET"));
assert!(sanitized.contains("permission"));
}
#[test]
fn sql_sanitizer_extract_constraint_name() {
let error = "duplicate key value violates unique constraint \"users_email_key\"";
let info = extract_metadata(error);
assert_eq!(info.constraint_name, Some("users_email_key".to_string()));
}
#[test]
fn sql_sanitizer_extract_column_name() {
let error = "column \"email\" does not exist";
let info = extract_metadata(error);
assert_eq!(info.column_name, Some("email".to_string()));
}
#[test]
fn sql_sanitizer_extract_table_name() {
let error = "relation \"users\" does not exist";
let info = extract_metadata(error);
assert_eq!(info.table_name, Some("users".to_string()));
}
#[test]
fn sql_sanitizer_sanitize_and_extract() {
let error = "SELECT * FROM users WHERE email = $1: column \"email\" does not exist";
let (sanitized, info) = sanitize_and_extract(error);
assert!(!sanitized.contains("SELECT"));
assert_eq!(info.column_name, Some("email".to_string()));
}
#[test]
fn sql_sanitizer_empty_sql_only_message() {
let error = "SELECT * FROM users";
let sanitized = sanitize_error_message(error);
assert_eq!(sanitized, "Database query execution failed");
}
#[test]
fn sql_sanitizer_multiple_sql_statements() {
let error = "failed: SELECT * FROM users; INSERT INTO logs VALUES ($1)";
let sanitized = sanitize_error_message(error);
assert!(!sanitized.contains("SELECT"));
assert!(!sanitized.contains("INSERT"));
assert!(sanitized.contains("failed"));
}
#[test]
fn error_category_serialization() {
let category = ErrorCategory::DatabaseConstraint;
let json = serde_json::to_string(&category).unwrap();
assert_eq!(json, "\"database_constraint\"");
}
#[test]
fn processed_error_builder() {
let error = ProcessedError::new(
ErrorCategory::QuerySyntax,
StatusCode::BAD_REQUEST,
"invalid_query",
"Invalid query syntax",
"trace123",
)
.with_hint("Check your column names")
.with_metadata("table", json!("users"));
assert_eq!(error.category, ErrorCategory::QuerySyntax);
assert_eq!(error.status_code, StatusCode::BAD_REQUEST);
assert_eq!(error.error_code, "invalid_query");
assert_eq!(error.hint, Some("Check your column names".to_string()));
assert_eq!(error.metadata.get("table").unwrap(), "users");
}
#[test]
fn processed_error_to_json() {
let error = ProcessedError::new(
ErrorCategory::DatabaseConstraint,
StatusCode::CONFLICT,
"unique_violation",
"A record with this value already exists",
"abc123",
)
.with_hint("Try a different value")
.with_metadata("constraint", json!("users_email_key"));
let json = error.to_json();
assert_eq!(json["status"], "error");
assert_eq!(json["code"], "unique_violation");
assert_eq!(json["hint"], "Try a different value");
assert_eq!(json["trace_id"], "abc123");
assert_eq!(json["details"]["category"], "database_constraint");
assert_eq!(json["details"]["constraint"], "users_email_key");
}
#[test]
fn generate_trace_id() {
let trace_id = athena_rs::error::generate_trace_id();
assert!(!trace_id.is_empty());
assert!(trace_id.len() <= 16);
}
#[test]
fn sqlx_parser_row_not_found_error() {
let err = sqlx::Error::RowNotFound;
let processed = process_sqlx_error(&err);
assert_eq!(processed.category, ErrorCategory::NotFound);
assert_eq!(processed.status_code, StatusCode::NOT_FOUND);
assert_eq!(processed.error_code, "row_not_found");
assert!(processed.hint.is_some());
}
#[test]
fn sqlx_parser_pool_timeout_error() {
let err = sqlx::Error::PoolTimedOut;
let processed = process_sqlx_error(&err);
assert_eq!(processed.category, ErrorCategory::DatabaseConnection);
assert_eq!(processed.status_code, StatusCode::SERVICE_UNAVAILABLE);
assert_eq!(processed.error_code, "pool_timeout");
}
#[test]
fn sqlx_parser_column_not_found_error() {
let err = sqlx::Error::ColumnNotFound("email".to_string());
let processed = process_sqlx_error(&err);
assert_eq!(processed.category, ErrorCategory::QuerySyntax);
assert_eq!(processed.error_code, "column_not_found");
assert_eq!(processed.metadata.get("column").unwrap(), "email");
}