use assert_cmd::Command;
use quorum_lippa_client::keyring::{delete_cookie, load_cookie, Storage};
use tempfile::TempDir;
fn init_repo() -> TempDir {
let td = TempDir::new().unwrap();
git2::Repository::init(td.path()).unwrap();
td
}
struct KeyringCleanup(String);
impl Drop for KeyringCleanup {
fn drop(&mut self) {
let _ = delete_cookie(&Storage::OsKeyring, &self.0);
}
}
#[cfg_attr(
target_os = "linux",
ignore = "requires a running Secret Service (gnome-keyring / kwallet); \
enable manually with `cargo test -- --ignored`"
)]
#[test]
fn os_keyring_persists_cookie_across_processes() {
let mut server = mockito::Server::new();
let unique_cookie = format!(
"cross-process-cookie-{pid}-{nanos}",
pid = std::process::id(),
nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0),
);
server
.mock("POST", "/api/v1/auth/login")
.with_status(200)
.with_header(
"set-cookie",
&format!("session={unique_cookie}; Path=/; HttpOnly"),
)
.with_body("{}")
.create();
let url = server.url();
let _cleanup = KeyringCleanup(url.clone());
let _ = delete_cookie(&Storage::OsKeyring, &url);
let td = init_repo();
Command::cargo_bin("quorum")
.expect("quorum binary built")
.current_dir(td.path())
.env_remove("QUORUM_LIPPA_SESSION")
.env_remove("QUORUM_LIPPA_EMAIL")
.env_remove("QUORUM_LIPPA_PASSWORD")
.args(["auth", "login", "--non-interactive", "--url"])
.arg(&url)
.env("QUORUM_LIPPA_EMAIL", "x@example.com")
.env("QUORUM_LIPPA_PASSWORD", "p")
.assert()
.success();
let loaded = load_cookie(&Storage::OsKeyring, &url)
.expect("keyring read must not error on the host platform");
let secret = loaded.expect(
"cookie must persist across processes; if this fails on a fixed build, the OS \
keychain is not reachable for this user — see README build prerequisites \
(BUG 1 regression guard)",
);
assert_eq!(
secret.expose(),
unique_cookie,
"cross-process cookie value mismatch"
);
}