use serde_json::{Map, Value, json};
use super::{Enrolled, MARKER, VERSION, enrolled};
use crate::reply::{Read, Reply, read};
fn frame() -> Value {
json!({
"ok": true,
"kind": "enrolled",
"grade": "foot",
"name": "phone-1",
"address": "engine.invalid:7737",
"ca": "-----BEGIN CERTIFICATE-----\nnotreal-ca\n-----END CERTIFICATE-----\n",
"cert": "-----BEGIN CERTIFICATE-----\nnotreal-leaf\n-----END CERTIFICATE-----\n",
"key": "-----BEGIN notreal KEY-----\nnotreal-key\n-----END notreal KEY-----\n",
})
}
fn obj() -> Map<String, Value> {
frame().as_object().cloned().expect("an object")
}
fn material() -> Enrolled {
enrolled(&obj()).expect("the whole frame reads")
}
#[test]
fn the_six_fields_land_where_they_belong() {
let held = material();
assert_eq!(held.grade, "foot");
assert_eq!(held.name, "phone-1");
assert_eq!(held.address, "engine.invalid:7737");
assert!(held.ca.contains("notreal-ca"));
assert!(held.cert.contains("notreal-leaf"));
assert!(held.key.contains("notreal-key"));
}
#[test]
fn every_missing_field_refuses_and_says_which() {
for field in ["grade", "name", "address", "ca", "cert", "key"] {
let mut without = obj();
without.remove(field);
let said = enrolled(&without).expect_err("a field short of an enrollment");
assert!(said.contains(field), "{field} went unnamed: {said}");
}
}
#[test]
fn a_field_of_the_wrong_type_refuses() {
let mut wrong = obj();
wrong.insert("key".to_owned(), Value::Null);
assert!(enrolled(&wrong).is_err());
}
#[test]
fn the_kind_reads_as_an_answer_of_its_own() {
assert_eq!(read(&frame()), Read::Answer(Reply::Enrolled(material())));
}
#[test]
fn the_envelope_carries_the_marker_the_six_fields_and_no_wire_words() {
let text = material().envelope();
let parsed: Value = serde_json::from_str(&text).expect("the envelope is JSON");
let map = parsed.as_object().expect("an object");
assert_eq!(map.get(MARKER), Some(&Value::from(VERSION)));
assert_eq!(map.len(), 7, "the marker and six fields: {text}");
for absent in ["ok", "kind"] {
assert!(map.get(absent).is_none(), "{absent} rode along: {text}");
}
}
#[test]
fn the_envelope_carries_the_pem_exactly_as_it_arrived() {
let held = material();
let parsed: Value = serde_json::from_str(&held.envelope()).expect("JSON");
for (field, want) in [
("grade", &held.grade),
("name", &held.name),
("address", &held.address),
("ca", &held.ca),
("cert", &held.cert),
("key", &held.key),
] {
assert_eq!(
parsed.get(field).and_then(Value::as_str),
Some(want.as_str())
);
}
}
#[test]
fn the_envelope_is_compact() {
let text = material().envelope();
assert!(!text.contains('\n'), "a literal newline: {text}");
assert!(!text.contains(": "), "whitespace after a colon: {text}");
assert!(!text.contains(", "), "whitespace after a comma: {text}");
}
#[test]
fn the_caption_names_the_box_and_never_the_material() {
let held = material();
let said = held.caption();
for named in [&held.name, &held.grade, &held.address] {
assert!(said.contains(named.as_str()), "{named} is missing: {said}");
}
for secret in ["notreal-key", "notreal-leaf", "notreal-ca", "BEGIN"] {
assert!(!said.contains(secret), "{secret} is in the caption: {said}");
}
}