use super::{ENTRIES, WIRE, dir, read_dir};
use crate::channel::material::{ADDRESS, ANCHORS, CHAIN, KEY};
use crate::test_support::{Scratch, mint};
use std::path::Path;
fn provision(entries: &Path, leaf: &str, address: &str) {
let dir = entries.join(leaf);
std::fs::create_dir_all(&dir).expect("the entry");
for file in [ANCHORS, CHAIN, KEY] {
std::fs::write(dir.join(file), b"pem bytes stand in here").expect("write");
}
std::fs::write(dir.join(ADDRESS), address).expect("write");
}
#[test]
fn entries_live_where_the_protocol_says_they_do() {
let root = Path::new("/somewhere/thrall");
assert_eq!(dir(root), root.join(WIRE).join(ENTRIES));
}
#[test]
fn an_unprovisioned_box_holds_no_channel() {
let scratch = Scratch::new();
assert_eq!(read_dir(&scratch.join("never-made")), Vec::new());
assert_eq!(read_dir(scratch.path()), Vec::new());
}
#[test]
fn entries_are_answered_in_one_order() {
let scratch = Scratch::new();
provision(scratch.path(), "second", "b.example:9000");
provision(scratch.path(), "first", "a.example:9000");
let held = read_dir(scratch.path());
let names: Vec<&str> = held.iter().map(|e| e.leaf.as_str()).collect();
assert_eq!(names, ["first", "second"]);
assert_eq!(
held[0].channel.as_ref().expect("provisioned").address,
"a.example:9000"
);
}
#[test]
fn a_file_beside_the_entries_is_not_an_entry() {
let scratch = Scratch::new();
provision(scratch.path(), "one", "a.example:9000");
std::fs::write(scratch.join("notes.txt"), b"left here by hand").expect("write");
assert_eq!(read_dir(scratch.path()).len(), 1);
}
#[test]
fn one_broken_entry_does_not_cost_the_others() {
let scratch = Scratch::new();
provision(scratch.path(), "good", "a.example:9000");
provision(scratch.path(), "half", "b.example:9000");
std::fs::remove_file(scratch.join("half").join(KEY)).expect("rm");
std::fs::create_dir_all(scratch.join("empty")).expect("mkdir");
let held = read_dir(scratch.path());
let by_name: Vec<(&str, bool)> = held
.iter()
.map(|e| (e.leaf.as_str(), e.channel.is_ok()))
.collect();
assert_eq!(by_name, [("empty", false), ("good", true), ("half", false)]);
let half = held[2].channel.as_ref().expect_err("refused");
assert!(half.contains("half-provisioned"), "{half}");
let empty = held[0].channel.as_ref().expect_err("refused");
assert!(empty.contains("is an empty entry"), "{empty}");
assert!(empty.contains("thrall mints nothing"), "{empty}");
}
#[test]
fn opening_an_entry_is_opening_its_channel() {
let scratch = Scratch::new();
let entry = scratch.join("engine");
mint::provisioned(&entry, "engine.example:9000");
let held = read_dir(scratch.path());
assert_eq!(held.len(), 1);
let channel = held[0].open().expect("opened");
assert_eq!(channel.client(), mint::FOOT_NAME);
assert_eq!(channel.address(), "engine.example:9000");
std::fs::remove_file(entry.join(ANCHORS)).expect("rm");
let broken = read_dir(scratch.path());
let refusal = broken[0].open().expect_err("refused");
assert!(refusal.contains("half-provisioned"), "{refusal}");
}