#![allow(clippy::unwrap_used)]
use super::SecurityConfig;
#[test]
fn misspelled_subsystem_key_is_a_load_error() {
for typo in [
"rate_limitting",
"token_revokation",
"api_key",
"trusted_document",
"service_account",
"error_sanitisation",
"pkce_config",
] {
let json = format!(r#"{{"{typo}": {{"enabled": true}}}}"#);
let parsed = serde_json::from_str::<SecurityConfig>(&json);
assert!(
parsed.is_err(),
"security key '{typo}' is not a subsystem; accepting it silently disables the \
subsystem it was meant to configure"
);
}
}
#[test]
fn garbage_keys_from_the_fuzz_reproducer_are_rejected() {
let json = r#"{"0es":[5555550000000000000000014385656476851910884],":::::iows":[]}"#;
assert!(
serde_json::from_str::<SecurityConfig>(json).is_err(),
"unknown security keys must be a load error, not preserved untyped"
);
}
#[test]
fn typed_subsystem_sections_round_trip() {
let json = r#"{
"multi_tenant": false,
"rate_limiting": {"enabled": true, "requests_per_second": 50},
"error_sanitization": {"enabled": true},
"trusted_documents": {"enabled": true, "mode": "strict", "manifest_path": "m.json"},
"pkce": {"enabled": true, "state_ttl_secs": 300},
"token_revocation": {"enabled": true, "backend": "memory"},
"api_keys": {"enabled": true, "static": [
{"key_hash": "sha256:ab", "name": "ci", "scopes": ["read:*"]}
]},
"service_accounts": {"reporter": {"secret_env": "SA_REPORTER", "roles": ["viewer"]}},
"persisted_queries_only": true
}"#;
let parsed: SecurityConfig = serde_json::from_str(json).unwrap();
assert!(parsed.rate_limiting.as_ref().unwrap().enabled);
assert_eq!(parsed.rate_limiting.as_ref().unwrap().requests_per_second, 50);
assert!(parsed.error_sanitization.as_ref().unwrap().enabled);
assert!(parsed.trusted_documents.as_ref().unwrap().enabled);
assert_eq!(parsed.pkce.as_ref().unwrap().state_ttl_secs, 300);
assert!(parsed.token_revocation.as_ref().unwrap().enabled);
assert_eq!(parsed.api_keys.as_ref().unwrap().static_keys.len(), 1);
assert_eq!(parsed.service_accounts.as_ref().unwrap()["reporter"].secret_env, "SA_REPORTER");
assert!(parsed.persisted_queries_only);
let round_tripped: SecurityConfig =
serde_json::from_str(&serde_json::to_string(&parsed).unwrap()).unwrap();
assert_eq!(parsed, round_tripped, "SecurityConfig must be stable across a save/load cycle");
}
#[test]
fn misspelled_field_inside_a_subsystem_is_a_load_error() {
let json = r#"{"rate_limiting": {"enabled": true, "requests_per_secound": 9}}"#;
assert!(
serde_json::from_str::<SecurityConfig>(json).is_err(),
"a typo'd field inside [security.rate_limiting] must fail the load"
);
}
#[test]
fn explicit_null_sections_mean_not_configured() {
let json = r#"{"rate_limiting": null, "pkce": null, "token_revocation": null}"#;
let parsed: SecurityConfig = serde_json::from_str(json).unwrap();
assert!(parsed.rate_limiting.is_none());
assert!(parsed.pkce.is_none());
assert!(parsed.token_revocation.is_none());
}