use super::component::{ComponentRef, Quantity};
use super::record::Passport;
use super::reference::PassportRef;
fn reference() -> PassportRef {
PassportRef {
uri: "https://example.test/dpp/cell".into(),
public_jws_hash: "b".repeat(64),
}
}
#[test]
fn component_ref_round_trips_with_both_qualifiers() {
let edge = ComponentRef {
reference: reference(),
quantity: Some(Quantity {
value: 1.4,
unit: Some("kg".into()),
}),
role: Some("outer shell".into()),
};
let json = serde_json::to_value(&edge).expect("edge serialises");
assert_eq!(json["reference"]["publicJwsHash"], "b".repeat(64));
assert_eq!(json["quantity"]["value"], 1.4);
assert_eq!(json["quantity"]["unit"], "kg");
assert_eq!(json["role"], "outer shell");
let back: ComponentRef = serde_json::from_value(json).expect("edge deserialises");
assert_eq!(back, edge);
}
#[test]
fn a_bare_component_ref_omits_its_qualifiers() {
let edge = ComponentRef {
reference: reference(),
quantity: None,
role: None,
};
let json = serde_json::to_value(&edge).expect("edge serialises");
let object = json.as_object().expect("object");
assert!(
!object.contains_key("quantity"),
"an absent quantity must be omitted, not serialised as null"
);
assert!(
!object.contains_key("role"),
"an absent role must be omitted, not serialised as null"
);
let back: ComponentRef = serde_json::from_value(json).expect("edge deserialises");
assert_eq!(back, edge);
}
#[test]
fn a_count_is_a_quantity_without_a_unit() {
let quantity = Quantity {
value: 2.0,
unit: None,
};
let json = serde_json::to_value(&quantity).expect("quantity serialises");
assert_eq!(json["value"], 2.0);
assert!(
!json.as_object().expect("object").contains_key("unit"),
"a dimensionless count omits the unit rather than inventing one"
);
}
#[test]
fn the_element_shape_this_replaced_still_parses() {
let bare = serde_json::json!({
"uri": "https://example.test/dpp/cell",
"publicJwsHash": "b".repeat(64),
});
let edge: ComponentRef =
serde_json::from_value(bare).expect("the pre-Phase-3 element shape must still parse");
assert_eq!(edge.reference, reference());
assert_eq!(
edge.quantity, None,
"an edge written before qualifiers existed declares none"
);
assert_eq!(edge.role, None);
}
#[test]
fn a_passport_carrying_the_old_element_shape_still_reads() {
let passport = crate::test_support::sample_passport();
let mut doc = serde_json::to_value(&passport).expect("serialise");
doc.as_object_mut().expect("object").insert(
"componentRefs".to_owned(),
serde_json::json!([{
"uri": "https://example.test/dpp/cell",
"publicJwsHash": "b".repeat(64),
}]),
);
let back: Passport =
serde_json::from_value(doc).expect("a passport with pre-Phase-3 edges must still read");
assert_eq!(back.component_refs.len(), 1);
assert_eq!(back.component_refs[0].reference, reference());
assert_eq!(back.component_refs[0].quantity, None);
}
#[test]
fn the_old_shape_is_read_but_never_written_back() {
let bare = serde_json::json!({
"uri": "https://example.test/dpp/cell",
"publicJwsHash": "b".repeat(64),
});
let edge: ComponentRef = serde_json::from_value(bare).expect("parses");
let out = serde_json::to_value(&edge).expect("serialises");
assert!(
out.get("reference").is_some(),
"a re-serialised edge must use the current shape"
);
assert!(
out.get("uri").is_none(),
"the old shape must not survive a round trip"
);
}
#[test]
fn an_entry_matching_neither_shape_is_still_refused() {
let nonsense = serde_json::json!({ "uri": "https://example.test/dpp/cell" });
serde_json::from_value::<ComponentRef>(nonsense)
.expect_err("an entry that is neither shape must not parse");
}