57 lines
2.3 KiB
Python
57 lines
2.3 KiB
Python
"""Vault secret resolver + file IO + rsync command build."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import stat
|
|
from pathlib import Path
|
|
|
|
from claire import vault
|
|
|
|
|
|
def test_write_read_roundtrip_and_0600(tmp_path: Path) -> None:
|
|
p = vault.write_vault_file("s.txt", "hunter2", vault_dir=tmp_path)
|
|
assert vault.read_vault_file("s.txt", vault_dir=tmp_path) == "hunter2"
|
|
assert stat.S_IMODE(p.stat().st_mode) == 0o600
|
|
assert stat.S_IMODE(tmp_path.stat().st_mode) == 0o700
|
|
|
|
|
|
def test_read_missing_returns_none(tmp_path: Path) -> None:
|
|
assert vault.read_vault_file("nope.txt", vault_dir=tmp_path) is None
|
|
|
|
|
|
def test_resolve_prefers_vault_over_fallback(tmp_path: Path) -> None:
|
|
vault.write_vault_file("claire-sync-secret.txt", "VAULTSECRET", vault_dir=tmp_path)
|
|
assert vault.resolve_sync_secrets("CONFIGSECRET", vault_dir=tmp_path) == ["VAULTSECRET"]
|
|
|
|
|
|
def test_resolve_falls_back_to_config_when_no_vault(tmp_path: Path) -> None:
|
|
assert vault.resolve_sync_secrets("CONFIGSECRET", vault_dir=tmp_path) == ["CONFIGSECRET"]
|
|
|
|
|
|
def test_resolve_empty_when_nothing(tmp_path: Path) -> None:
|
|
assert vault.resolve_sync_secrets(None, vault_dir=tmp_path) == []
|
|
|
|
|
|
def test_resolve_includes_prev_during_rotation(tmp_path: Path) -> None:
|
|
vault.write_vault_file("claire-sync-secret.txt", "NEW", vault_dir=tmp_path)
|
|
vault.write_vault_file("claire-sync-secret.prev.txt", "OLD", vault_dir=tmp_path)
|
|
assert vault.resolve_sync_secrets(None, vault_dir=tmp_path) == ["NEW", "OLD"]
|
|
|
|
|
|
def test_resolve_dedupes_prev_equal_current(tmp_path: Path) -> None:
|
|
vault.write_vault_file("claire-sync-secret.txt", "SAME", vault_dir=tmp_path)
|
|
vault.write_vault_file("claire-sync-secret.prev.txt", "SAME", vault_dir=tmp_path)
|
|
assert vault.resolve_sync_secrets(None, vault_dir=tmp_path) == ["SAME"]
|
|
|
|
|
|
def test_rsync_cmd_flags(tmp_path: Path) -> None:
|
|
cmd = vault._rsync_cmd(tmp_path, "apricot:.vault/", delete=False, ts="T")
|
|
assert "--no-inplace" in cmd
|
|
assert "--exclude=*.prev.txt" in cmd # rotation prev stays plum-local
|
|
assert "--backup-dir=../.vault-backups/T/" in cmd
|
|
assert "--delete" not in cmd
|
|
assert cmd[-2:] == [f"{tmp_path}/", "apricot:.vault/"]
|
|
|
|
|
|
def test_rsync_cmd_delete_opt_in(tmp_path: Path) -> None:
|
|
assert "--delete" in vault._rsync_cmd(tmp_path, "h:.vault/", delete=True, ts="T")
|