#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic
)]
use dsse::pae;
#[test]
fn length_prefix_counts_bytes_not_characters() {
let got = pae("tybé", b"x");
assert_eq!(
got,
b"DSSEv1 5 tyb\xc3\xa9 1 x".to_vec(),
"LEN must be the byte length, 5, not the character count, 4"
);
}
#[test]
fn length_prefix_counts_bytes_for_astral_characters() {
let got = pae("🔒", b"");
assert_eq!(got, b"DSSEv1 4 \xf0\x9f\x94\x92 0 ".to_vec());
assert!(!got.starts_with(b"DSSEv1 1 "));
}
#[test]
fn payload_type_containing_a_space_is_carried_verbatim() {
let got = pae("a b", b"c");
assert_eq!(got, b"DSSEv1 3 a b 1 c".to_vec());
}
#[test]
fn payload_type_shaped_like_a_length_field() {
let got = pae("9 not-a-length", b"body");
assert_eq!(got, b"DSSEv1 14 9 not-a-length 4 body".to_vec());
}
#[test]
fn empty_payload_keeps_its_trailing_space() {
let got = pae("t", b"");
assert_eq!(got, b"DSSEv1 1 t 0 ".to_vec());
assert_eq!(*got.last().unwrap(), b' ', "the trailing space is signed");
}
#[test]
fn empty_payload_type_keeps_both_spaces() {
let got = pae("", b"x");
assert_eq!(got, b"DSSEv1 0 1 x".to_vec());
assert_eq!(
&got[7..10],
b"0 ",
"zero length, then the empty type, then SP"
);
}
#[test]
fn both_members_empty() {
assert_eq!(pae("", b""), b"DSSEv1 0 0 ".to_vec());
}
#[test]
fn length_prefix_has_no_leading_zeros() {
for n in [0usize, 1, 9, 10, 11, 99, 100, 101, 255, 1000] {
let payload = vec![b'z'; n];
let got = pae("t", &payload);
let want = format!("DSSEv1 1 t {n} ");
assert!(
got.starts_with(want.as_bytes()),
"payload of {n} bytes: expected prefix {want:?}, got {:?}",
String::from_utf8_lossy(&got[..want.len().min(got.len())])
);
assert!(
!got.starts_with(format!("DSSEv1 1 t 0{n} ").as_bytes()),
"a zero-padded length is a different pre-image"
);
}
}
#[test]
fn encoding_is_injective_across_the_type_body_boundary() {
assert_ne!(pae("ab", b"c"), pae("a", b"bc"));
assert_ne!(pae("a", b"b"), pae("", b"ab"));
assert_ne!(pae("", b"ab"), pae("ab", b""));
}
#[test]
fn payload_that_is_itself_a_valid_pae_stays_nested() {
let inner = pae("inner-type", b"inner-body");
let outer = pae("outer-type", &inner);
assert_ne!(outer, inner);
assert!(outer.starts_with(format!("DSSEv1 10 outer-type {} ", inner.len()).as_bytes()));
assert!(outer.ends_with(&inner), "the inner PAE is carried verbatim");
let occurrences = outer.windows(6).filter(|w| *w == b"DSSEv1").count();
assert_eq!(occurrences, 2);
}
#[test]
fn payload_need_not_be_valid_utf8() {
let payload = [0xff, 0xfe, 0x00, 0x80];
let got = pae("t", &payload);
assert_eq!(got, b"DSSEv1 1 t 4 \xff\xfe\x00\x80".to_vec());
assert!(String::from_utf8(payload.to_vec()).is_err());
}
#[test]
fn payload_type_is_case_sensitive() {
assert_ne!(pae("Application/JSON", b"x"), pae("application/json", b"x"));
}