use std::os::unix::fs::PermissionsExt;
use tempfile::TempDir;
#[test]
fn init_creates_full_layout_and_files() {
let tmp = TempDir::new().unwrap();
let root = tmp.path();
let status = std::process::Command::new(env!("CARGO_BIN_EXE_gradatum-admin"))
.arg("init")
.arg("--preset")
.arg("hierarchical")
.arg("--root")
.arg(root)
.arg("--non-interactive")
.current_dir(std::env::temp_dir()) .status()
.unwrap();
assert!(status.success(), "gradatum-admin init returned non-zero");
for sub in ["md", "db", "config"] {
assert!(root.join(sub).is_dir(), "{sub} directory not created");
}
let bearer = root.join("config/admin.bearer.txt");
assert!(bearer.is_file(), "admin.bearer.txt missing");
let mode = bearer.metadata().unwrap().permissions().mode() & 0o777;
assert_eq!(
mode, 0o600,
"admin.bearer.txt chmod = {mode:o}, expected 0600"
);
let priv_key = root.join("config/jwt.private.pem");
assert!(priv_key.is_file(), "jwt.private.pem missing");
let mode = priv_key.metadata().unwrap().permissions().mode() & 0o777;
assert_eq!(
mode, 0o600,
"jwt.private.pem chmod = {mode:o}, expected 0600"
);
let pub_key = root.join("config/jwt.public.pem");
assert!(pub_key.is_file(), "jwt.public.pem missing");
let mode = pub_key.metadata().unwrap().permissions().mode() & 0o777;
assert_eq!(
mode, 0o644,
"jwt.public.pem chmod = {mode:o}, expected 0644"
);
let bearer_toml = root.join("config/bearer.toml");
assert!(bearer_toml.is_file(), "bearer.toml missing");
let mode = bearer_toml.metadata().unwrap().permissions().mode() & 0o777;
assert_eq!(mode, 0o640, "bearer.toml chmod = {mode:o}, expected 0640");
let server_toml = std::fs::read_to_string(root.join("config/server.toml"))
.expect("server.toml missing or unreadable");
assert!(
server_toml.contains("jwt_ttl_human_secs = 3600"),
"server.toml missing jwt_ttl_human_secs = 3600"
);
assert!(
server_toml.contains("jwt_ttl_service_secs = 86400"),
"server.toml missing jwt_ttl_service_secs = 86400"
);
let mode = root
.join("config/server.toml")
.metadata()
.unwrap()
.permissions()
.mode()
& 0o777;
assert_eq!(mode, 0o640, "server.toml chmod = {mode:o}, expected 0640");
assert!(
root.join("db/queue.sqlite").is_file(),
"db/queue.sqlite missing"
);
assert!(
root.join("db/revocation.sqlite").is_file(),
"db/revocation.sqlite missing"
);
assert!(
root.join("db/api_keys.sqlite").is_file(),
"db/api_keys.sqlite missing (AUTH-T2)"
);
let conn = rusqlite::Connection::open(root.join("db/api_keys.sqlite"))
.expect("ouverture api_keys.sqlite");
let table_exists: bool = conn
.query_row(
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='api_keys'",
[],
|r| r.get::<_, i64>(0),
)
.map(|c| c > 0)
.unwrap_or(false);
assert!(
table_exists,
"table api_keys non créée dans api_keys.sqlite"
);
assert!(
server_toml.contains("api_keys_db_path"),
"server.toml missing api_keys_db_path (AUTH-T2)"
);
assert!(
server_toml.contains("vault_index_path"),
"server.toml doit utiliser vault_index_path (canonique alpha.7) — régression Task 16"
);
assert!(
!server_toml.contains("\ndb_path = "),
"server.toml ne doit pas contenir la clé db_path (alias deprecated — déclenche WARN au boot)"
);
}