mod adopt;
mod envelope;
mod refusals;
use super::*;
use crate::boundary::dispatch::Deps;
use crate::boundary::tests::snapshot;
use crate::boundary::{Action, Gesture};
use crate::cli_outbound::Cli;
use crate::registry::Grade;
use rustls::pki_types::CertificateDer;
use rustls::pki_types::pem::PemObject;
use std::path::PathBuf;
use std::sync::Arc;
use tempfile::{TempDir, tempdir};
pub(super) const STATED: &str = "engine.invalid:7737";
pub(super) fn provisioned(tmp: &TempDir) -> (Deps, PathBuf) {
let world = crate::test_support::world_under(tmp.path());
let dir = material::dir(&world);
provision::mint(&dir, STATED, &[], false).expect("the operator's own mint");
let state_root = tmp.path().join("state-root");
(deps(&world, &state_root), dir)
}
pub(super) fn deps(world: &crate::xdg::Env, state_root: &Path) -> Deps {
Deps {
litany: Cli::new("/no/such/litany"),
bl: Cli::new("/no/such/bl"),
state_root: state_root.to_path_buf(),
home: PathBuf::from("/home/x"),
yog_data_root: PathBuf::from("/data"),
yog_binary: PathBuf::from("/no/such/yog"),
world: world.clone(),
snapshot: Arc::new(snapshot(
Path::new("/names/alba"),
"alba",
Vec::new(),
Vec::new(),
)),
caller: crate::boundary::dispatch::Caller::default(),
}
}
pub(super) fn request(name: &str, grade: Grade) -> Request {
Request {
workspace: "alba".to_owned(),
name: name.to_owned(),
grade,
address: None,
}
}
pub(super) fn enrolled(reply: Reply) -> Enrolled {
match reply {
Reply::Enrolled(enrolled) => enrolled,
other => panic!("not an enrollment: {other:?}"),
}
}
#[test]
fn an_enrollment_mints_registers_and_answers() {
let tmp = tempdir().expect("tmp");
let (deps, dir) = provisioned(&tmp);
let answer = enrolled(enroll(&deps, "7", &request("phone-1", Grade::Operator)).expect("act"));
assert_eq!(answer.name, "phone-1");
assert_eq!(answer.grade, Grade::Operator);
assert_eq!(answer.address, STATED);
assert_eq!(answer.ca, read(&dir.join(material::ANCHORS)).expect("ca"));
assert_eq!(answer.cert, read(&dir.join("phone-1.pem")).expect("leaf"));
assert!(answer.key.contains("PRIVATE KEY"), "a key, in PEM");
let client = Client::parse("phone-1").expect("identity");
assert!(
crate::registry::registered(&deps.state_root, &client).contains("alba"),
"seated in the workspace the gesture named"
);
let trail = crate::opslog::tail(&deps.state_root, 8);
let row = trail.first().expect("one row");
assert_eq!(
row.argv,
vec![crate::opslog::YOG_STEP.to_owned(), STEP.into()]
);
assert_eq!(row.exit, 0);
assert!(row.stdout.is_empty() && row.stderr.is_empty());
}
#[test]
fn the_key_is_absent_server_side_and_the_certificate_is_not() {
let tmp = tempdir().expect("tmp");
let (deps, dir) = provisioned(&tmp);
enroll(&deps, "7", &request("phone-1", Grade::Operator)).expect("act");
assert!(!dir.join("phone-1.key").exists(), "shredded");
assert!(dir.join("phone-1.pem").is_file(), "kept, and public");
let again =
enrolled(enroll(&deps, "8", &request("phone-1", Grade::Operator)).expect("re-mint"));
assert!(!again.key.is_empty(), "material a device can use");
assert!(!dir.join("phone-1.key").exists(), "and shredded again");
}
#[test]
fn the_address_field_matches_what_a_client_dials() {
let tmp = tempdir().expect("tmp");
let (deps, dir) = provisioned(&tmp);
let answer = enrolled(enroll(&deps, "7", &request("phone-1", Grade::Operator)).expect("act"));
let dialled = material::read_dir(&dir, material::Role::Client)
.expect("readable")
.expect("provisioned")
.address;
assert_eq!(answer.address, dialled);
}
#[test]
fn a_foot_is_minted_as_a_foot_and_reads_back_as_one() {
let tmp = tempdir().expect("tmp");
let (deps, _) = provisioned(&tmp);
for (name, grade) in [("laptop", Grade::Operator), ("builder", Grade::Foot)] {
let answer = enrolled(enroll(&deps, "7", &request(name, grade)).expect("act"));
assert_eq!(answer.grade, grade);
let der = CertificateDer::from_pem_slice(answer.cert.as_bytes()).expect("pem");
assert_eq!(crate::registry::leaf::grade(&der), grade, "{name}");
assert_eq!(
crate::registry::leaf::common_name(&der).as_deref(),
Some(name)
);
}
}
#[test]
fn a_foot_grade_caller_is_refused_structurally() {
let gesture = Gesture::Act(Action::Enroll(request("phone-1", Grade::Operator)));
assert!(
!Grade::Foot.admits(&gesture),
"an act is outside the foot set: advertise, invocations, complete"
);
assert!(Grade::Operator.admits(&gesture));
}
#[test]
fn the_chokepoint_routes_it_and_refuses_an_unknown_workspace() {
let tmp = tempdir().expect("tmp");
let (deps, _) = provisioned(&tmp);
let act = |name: &str, ws: &str| {
crate::boundary::dispatch::dispatch(
&deps,
&mut crate::ui_state::UiState::open(tmp.path().join("ui.json")),
"7",
&Action::Enroll(Request {
workspace: ws.to_owned(),
name: name.to_owned(),
grade: Grade::Operator,
address: None,
}),
)
};
let answer = enrolled(act("phone-1", "alba").expect("routed"));
assert_eq!(answer.name, "phone-1");
let refusal = act("phone-2", "elsewhere").expect_err("unresolvable");
assert!(refusal.contains("elsewhere"), "{refusal}");
}