use serde_json::{Value, json};
use super::{KEPT, enroll};
use crate::cli::Stream;
use crate::test_support::{Scratch, wire};
const CA: &str = "-----BEGIN CERTIFICATE-----\nnotreal-ca\n-----END CERTIFICATE-----\n";
const CERT: &str = "-----BEGIN CERTIFICATE-----\nnotreal-leaf\n-----END CERTIFICATE-----\n";
const KEY: &str = "-----BEGIN notreal KEY-----\nnotreal-key\n-----END notreal KEY-----\n";
fn minted() -> Value {
json!({
"ok": true,
"kind": "enrolled",
"grade": "foot",
"name": "phone-1",
"address": "engine.invalid:7737",
"ca": CA,
"cert": CERT,
"key": KEY,
})
}
fn tree(at: &std::path::Path) -> Vec<String> {
let mut found = Vec::new();
walk(at, at, &mut found);
found.sort();
found
}
fn walk(root: &std::path::Path, at: &std::path::Path, out: &mut Vec<String>) {
let Ok(entries) = std::fs::read_dir(at) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
walk(root, &path, out);
} else {
let len = std::fs::metadata(&path).map_or(0, |held| held.len());
let shown = path.strip_prefix(root).unwrap_or(&path).display();
out.push(format!("{shown} ({len})"));
}
}
}
fn spent(answer: Vec<Value>) -> (crate::cli::Verdict, Vec<String>, Vec<String>) {
let scratch = Scratch::new();
let _engine = wire::wired(&scratch, &wire::flat(), vec![answer]);
let before = tree(scratch.path());
let verdict = enroll(scratch.path(), "home", "phone-1", "foot");
let after = tree(scratch.path());
(verdict, before, after)
}
#[test]
fn the_act_writes_no_file_at_all() {
let (verdict, before, after) = spent(vec![minted()]);
assert_eq!(verdict.code, 0, "{}", verdict.text);
assert_eq!(before, after, "the enrollment left something on the disk");
}
#[test]
fn the_answer_is_drawn_and_never_spelled_out() {
let (verdict, ..) = spent(vec![minted()]);
assert_eq!(verdict.stream, Stream::Out);
for secret in ["notreal-key", "notreal-leaf", "notreal-ca", "BEGIN"] {
assert!(
!verdict.text.contains(secret),
"{secret} reached stdout:\n{}",
verdict.text
);
}
assert!(verdict.text.contains("phone-1"), "{}", verdict.text);
assert!(
verdict.text.contains("engine.invalid:7737"),
"{}",
verdict.text
);
assert!(verdict.text.contains(KEPT), "{}", verdict.text);
assert!(
verdict.text.contains('\u{2588}') || verdict.text.contains('\u{2580}'),
"no symbol was drawn:\n{}",
verdict.text
);
}
#[test]
fn the_gesture_that_crossed_is_the_verb_table_s_own() {
let scratch = Scratch::new();
let engine = wire::wired(&scratch, &wire::flat(), vec![vec![minted()]]);
let _ = enroll(scratch.path(), "home", "phone-1", "foot");
let heard = engine.heard();
let request = heard.last().expect("the engine was handed a request");
assert_eq!(
request,
&crate::verbs::enroll("home".to_owned(), "phone-1".to_owned(), "foot".to_owned())
);
}
#[test]
fn a_refusal_is_answered_rather_than_drawn() {
let (verdict, ..) = spent(vec![json!({"ok": false, "error": "not operator-grade"})]);
assert_eq!(verdict.stream, Stream::Out);
assert_eq!(verdict.code, 1);
assert!(
verdict.text.contains("not operator-grade"),
"{}",
verdict.text
);
}
#[test]
fn an_unreadable_frame_fails_in_this_seat_s_own_words() {
let (verdict, ..) = spent(vec![json!({"ok": true, "kind": "enrolled"})]);
assert_eq!(verdict.stream, Stream::Err);
assert!(verdict.text.contains("grade"), "{}", verdict.text);
}
#[test]
fn an_answer_of_another_kind_says_nothing_was_minted() {
let (verdict, ..) = spent(vec![json!({"ok": true, "kind": "nudged"})]);
assert_eq!(verdict.stream, Stream::Err);
assert!(verdict.text.contains("did not mint"), "{}", verdict.text);
}
#[test]
fn a_root_with_no_channel_fails_before_anything_is_asked() {
let scratch = Scratch::new();
let verdict = enroll(scratch.path(), "home", "phone-1", "foot");
assert_eq!(verdict.stream, Stream::Err);
assert_eq!(verdict.code, 1);
assert_eq!(tree(scratch.path()), Vec::<String>::new());
}
#[test]
fn material_too_big_for_a_symbol_says_so_and_draws_nothing() {
let mut oversized = minted();
oversized["ca"] = Value::String("notreal".repeat(400));
let (verdict, before, after) = spent(vec![oversized]);
assert_eq!(verdict.stream, Stream::Err);
assert!(verdict.text.contains("will not fit"), "{}", verdict.text);
assert!(
verdict.text.contains("2331"),
"the ceiling: {}",
verdict.text
);
assert!(!verdict.text.contains("notreal"), "it printed the material");
assert_eq!(before, after, "a refusal still wrote something");
}
#[test]
fn an_empty_stream_says_the_engine_answered_nothing() {
let (verdict, ..) = spent(Vec::new());
assert!(verdict.text.contains("nothing at all"), "{}", verdict.text);
}