//! Tests for storage layers that already exist. These must PASS. use std::path::PathBuf; use zagan_bet::client::database as client_database; use zagan_bet::server::database as server_database; fn tmp_db(name: &str) -> (String, rusqlite::Connection) { let path = PathBuf::from(env!("CARGO_TARGET_TMPDIR")) .join(format!("storage-{name}.db")) .to_string_lossy() .into_owned(); let _ = std::fs::remove_file(&path); let conn = rusqlite::Connection::open(&path).unwrap(); (path, conn) } #[test] fn client_credentials_roundtrip() { let (_, conn) = tmp_db("creds"); client_database::init_db(&conn); let identity = "5a15c712230831cb"; assert_eq!(client_database::get_credentials(&conn, identity), None); client_database::save_credentials(&conn, identity, "alice", "pw").unwrap(); assert_eq!( client_database::get_credentials(&conn, identity), Some(("alice".to_string(), "pw".to_string())) ); // Overwrite works. client_database::save_credentials(&conn, identity, "alice", "pw2").unwrap(); assert_eq!( client_database::get_credentials(&conn, identity), Some(("alice".to_string(), "pw2".to_string())) ); } #[test] fn credentials_belong_to_the_certificate_not_the_address() { let (_, conn) = tmp_db("creds-identity"); client_database::init_db(&conn); // Two addresses for one server, one address for another. client_database::save_host(&conn, "10.0.0.100:11525"); client_database::save_host(&conn, "127.0.0.1:11525"); client_database::save_host(&conn, "other.example:11525"); client_database::save_fingerprint(&conn, "10.0.0.100:11525", "server-a").unwrap(); client_database::save_fingerprint(&conn, "127.0.0.1:11525", "server-a").unwrap(); client_database::save_fingerprint(&conn, "other.example:11525", "server-b").unwrap(); client_database::save_credentials(&conn, "server-a", "alice", "pw").unwrap(); assert_eq!( client_database::get_credentials(&conn, "server-a"), Some(("alice".to_string(), "pw".to_string())), "one login covers every address with the same key" ); assert_eq!( client_database::get_credentials(&conn, "server-b"), None, "a different key must not inherit the credentials" ); } #[test] fn forgetting_one_address_keeps_the_shared_credentials() { let (_, conn) = tmp_db("creds-forget"); client_database::init_db(&conn); client_database::save_host(&conn, "10.0.0.100:11525"); client_database::save_host(&conn, "127.0.0.1:11525"); client_database::save_fingerprint(&conn, "10.0.0.100:11525", "server-a").unwrap(); client_database::save_fingerprint(&conn, "127.0.0.1:11525", "server-a").unwrap(); client_database::save_credentials(&conn, "server-a", "alice", "pw").unwrap(); let outcome = client_database::forget_host(&conn, "10.0.0.100:11525").unwrap(); assert!(!outcome.credentials_removed); assert_eq!(outcome.siblings, vec!["127.0.0.1:11525".to_string()]); assert_eq!( client_database::get_credentials(&conn, "server-a"), Some(("alice".to_string(), "pw".to_string())), "the server is still reachable, so the login is still useful" ); let outcome = client_database::forget_host(&conn, "127.0.0.1:11525").unwrap(); assert!(outcome.credentials_removed); assert!(outcome.siblings.is_empty()); assert_eq!(client_database::get_credentials(&conn, "server-a"), None); } #[test] fn client_last_host_tracking() { let (_, conn) = tmp_db("hosts"); client_database::init_db(&conn); assert_eq!(client_database::get_last_host(&conn), None); client_database::save_host(&conn, "example.com:9000"); assert_eq!( client_database::get_last_host(&conn), Some("example.com:9000".to_string()) ); } #[test] fn server_user_registration_and_auth_lookup() { let (_, conn) = tmp_db("users"); server_database::init_db(&conn); server_database::add_user(&conn, "bob", "cafebabe").unwrap(); assert_eq!( server_database::get_hashed_password(&conn, "bob"), Some("cafebabe".to_string()) ); assert_eq!(server_database::get_hashed_password(&conn, "nobody"), None); }