feat(cli/org): org rm/restore/purge trash lifecycle (collection-scoped)

This commit is contained in:
adlee-was-taken
2026-06-20 14:39:18 -04:00
parent 057a7defe5
commit 6123d8b033
4 changed files with 350 additions and 4 deletions

View File

@@ -177,3 +177,41 @@ fn org_edit_updates_fields_and_commits_update_trailer() {
assert!(body.contains("Relicario-Action: item-update"), "missing update trailer: {body}");
assert!(body.contains("Relicario-Collection: prod"), "missing collection trailer: {body}");
}
#[test]
fn org_rm_restore_purge_cycle() {
let f = OrgFixture::new();
let owner = f.owner_member_id();
assert!(f.run(&["org", "create-collection", "prod", "--name", "Production"]).status.success());
assert!(f.run(&["org", "grant", &owner, "prod"]).status.success());
assert!(f.run(&[
"org", "add", "secure-note", "--collection", "prod",
"--title", "Recovery", "--body", "codes-here",
]).status.success());
// rm → appears only with --trashed.
assert!(f.run(&["org", "rm", "Recovery"]).status.success());
let listed = String::from_utf8_lossy(&f.run(&["org", "list"]).stdout).to_string();
assert!(!listed.contains("Recovery"), "trashed item still in default list: {listed}");
let trashed = String::from_utf8_lossy(&f.run(&["org", "list", "--trashed"]).stdout).to_string();
assert!(trashed.contains("Recovery"), "trashed item not in --trashed list: {trashed}");
// restore → back in default list.
assert!(f.run(&["org", "restore", "Recovery"]).status.success());
let listed = String::from_utf8_lossy(&f.run(&["org", "list"]).stdout).to_string();
assert!(listed.contains("Recovery"), "restore did not bring it back: {listed}");
// purge → blob gone, entry gone, item-purge trailer.
assert!(f.run(&["org", "purge", "Recovery"]).status.success());
let prod_dir = f.vault_path().join("items").join("prod");
let count = std::fs::read_dir(&prod_dir).map(|d| d.count()).unwrap_or(0);
assert_eq!(count, 0, "blob not purged from items/prod/");
let listed = String::from_utf8_lossy(&f.run(&["org", "list", "--trashed"]).stdout).to_string();
assert!(!listed.contains("Recovery"), "purged item still listed: {listed}");
let log = Command::new("git")
.args(["-C", f.vault_str(), "log", "-1", "--format=%B"])
.output().unwrap();
let body = String::from_utf8_lossy(&log.stdout).to_string();
assert!(body.contains("Relicario-Action: item-purge"), "missing purge trailer: {body}");
}