#![allow(clippy::unwrap_used)]
use std::time::Duration;
use fraiseql_error::ConfigError;
use super::*;
use crate::config::{
env::{parse_duration, parse_size, resolve_env_value},
validation::ConfigValidator,
};
#[test]
fn test_parse_minimal_config() {
temp_env::with_vars([("DATABASE_URL", Some("postgres://localhost/test"))], || {
let toml = r#"
[server]
port = 4000
[database]
url_env = "DATABASE_URL"
"#;
let config: RuntimeConfig = toml::from_str(toml).unwrap();
assert_eq!(config.server.port, 4000);
assert_eq!(config.server.host, "127.0.0.1");
assert_eq!(config.database.url_env, "DATABASE_URL");
assert_eq!(config.database.pool_size, 10);
});
}
#[test]
fn test_parse_size() {
assert_eq!(parse_size("10MB").unwrap(), 10 * 1024 * 1024);
assert_eq!(parse_size("1GB").unwrap(), 1024 * 1024 * 1024);
assert_eq!(parse_size("500KB").unwrap(), 500 * 1024);
assert_eq!(parse_size("1000").unwrap(), 1000);
assert_eq!(parse_size("100B").unwrap(), 100);
}
#[test]
fn test_parse_size_invalid() {
assert!(
parse_size("abc").is_err(),
"expected Err for invalid size string, got: {:?}",
parse_size("abc")
);
}
#[test]
fn test_parse_duration() {
assert_eq!(parse_duration("30s").unwrap(), Duration::from_secs(30));
assert_eq!(parse_duration("5m").unwrap(), Duration::from_secs(300));
assert_eq!(parse_duration("1h").unwrap(), Duration::from_secs(3600));
assert_eq!(parse_duration("100ms").unwrap(), Duration::from_millis(100));
assert_eq!(parse_duration("1d").unwrap(), Duration::from_secs(86400));
}
#[test]
fn test_parse_duration_invalid() {
assert!(
parse_duration("30").is_err(),
"expected Err for duration without unit, got: {:?}",
parse_duration("30")
); assert!(
parse_duration("abc").is_err(),
"expected Err for non-numeric duration, got: {:?}",
parse_duration("abc")
);
}
#[test]
fn test_env_resolution_with_default() {
temp_env::with_vars([("NONEXISTENT_VAR", None::<&str>)], || {
let result = resolve_env_value("${NONEXISTENT_VAR:-default_value}").unwrap();
assert_eq!(result, "default_value");
});
}
#[test]
fn test_env_resolution_without_default() {
temp_env::with_vars([("EXISTING_VAR", Some("actual_value"))], || {
let result = resolve_env_value("${EXISTING_VAR:-default}").unwrap();
assert_eq!(result, "actual_value");
});
}
#[test]
fn test_validation_missing_env_var() {
temp_env::with_vars([("NONEXISTENT_DB_URL", None::<&str>)], || {
let toml = r#"
[server]
port = 4000
[database]
url_env = "NONEXISTENT_DB_URL"
"#;
let config: RuntimeConfig = toml::from_str(toml).unwrap();
let result = ConfigValidator::new(&config).validate();
assert!(result.is_err(), "expected Err for missing env var but got no errors");
assert!(result.errors.iter().any(|e| matches!(e, ConfigError::MissingEnvVar { .. })));
});
}
#[test]
fn test_validation_cross_field() {
temp_env::with_vars([("DATABASE_URL", Some("postgres://localhost/test"))], || {
let toml = r#"
[server]
port = 4000
[database]
url_env = "DATABASE_URL"
[observers.test]
entity = "users"
events = ["insert"]
[[observers.test.actions]]
type = "email"
template = "welcome"
"#;
let config: RuntimeConfig = toml::from_str(toml).unwrap();
let result = ConfigValidator::new(&config).validate();
assert!(
result.is_err(),
"expected Err because email action requires notifications config but got no errors"
);
});
}