use crate::{CliError, Session};
use btctax_store::Passphrase;
use std::path::Path;
pub fn run(vault_path: &Path, pp: &Passphrase, key_backup_path: &Path) -> Result<(), CliError> {
run_with_repair(vault_path, pp, key_backup_path, false)
}
pub fn run_with_repair(
vault_path: &Path,
pp: &Passphrase,
key_backup_path: &Path,
repair: bool,
) -> Result<(), CliError> {
let session = if repair {
Session::repair(vault_path, pp)?
} else {
Session::create(vault_path, pp)?
};
session.vault().backup_key(key_backup_path)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use btctax_store::Passphrase;
#[test]
fn init_creates_vault_key_and_forced_backup() {
let dir = tempfile::tempdir().unwrap();
let vault = dir.path().join("vault.pgp");
let backup = dir.path().join("backup/key.asc");
run(&vault, &Passphrase::new("pw".into()), &backup).unwrap();
assert!(vault.exists(), "vault.pgp written");
assert!(dir.path().join("vault.key").exists(), "sidecar key written");
assert!(backup.exists(), "forced key backup written");
}
#[test]
fn init_refuses_to_clobber_an_existing_vault() {
let dir = tempfile::tempdir().unwrap();
let vault = dir.path().join("vault.pgp");
let backup = dir.path().join("k.asc");
run(&vault, &Passphrase::new("pw".into()), &backup).unwrap();
let err = run(&vault, &Passphrase::new("pw".into()), &backup).unwrap_err();
assert!(matches!(
err,
CliError::Store(btctax_store::StoreError::AlreadyExists)
));
}
#[test]
fn init_repair_recovers_a_half_created_vault() {
let dir = tempfile::tempdir().unwrap();
let vault = dir.path().join("vault.pgp");
let backup = dir.path().join("k.asc");
let pp = Passphrase::new("pw".into());
run(&vault, &pp, &backup).unwrap();
std::fs::remove_file(&vault).unwrap();
let bak = btctax_store::paths::bak_of(&vault);
if bak.exists() {
std::fs::remove_file(&bak).unwrap();
}
let backup2 = dir.path().join("k2.asc");
run_with_repair(&vault, &pp, &backup2, true).unwrap();
crate::Session::open(&vault, &pp).unwrap();
}
#[test]
fn init_without_repair_on_half_created_errors() {
let dir = tempfile::tempdir().unwrap();
let vault = dir.path().join("vault.pgp");
let backup = dir.path().join("k.asc");
let pp = Passphrase::new("pw".into());
run(&vault, &pp, &backup).unwrap();
std::fs::remove_file(&vault).unwrap();
let bak = btctax_store::paths::bak_of(&vault);
if bak.exists() {
std::fs::remove_file(&bak).unwrap();
}
let err = run(&vault, &pp, &backup).unwrap_err();
assert!(
matches!(
err,
CliError::Store(btctax_store::StoreError::HalfCreatedVault(_))
),
"expected HalfCreatedVault, got: {err:?}"
);
}
}