#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::tests_outside_test_module,
unused_crate_dependencies,
reason = "integration tests inherit the crate's full dev-dep set; \
dev-deps this file does not consume would otherwise trip \
`unused_crate_dependencies`. Test code may also panic for brevity."
)]
use bech32::{Bech32, Hrp};
use nula_core::Coordinate;
use nula_core::FromBech32;
use nula_core::nips::nip19::{FromBech32Error, Nip19Event};
const SPECIAL: u8 = 0;
const AUTHOR: u8 = 2;
const KIND: u8 = 3;
fn push_tlv(buf: &mut Vec<u8>, tag: u8, value: &[u8]) {
buf.push(tag);
buf.push(u8::try_from(value.len()).expect("test TLV value fits in one byte"));
buf.extend_from_slice(value);
}
fn bech32_nip19(hrp: &str, payload: &[u8]) -> String {
bech32::encode::<Bech32>(Hrp::parse(hrp).expect("valid hrp"), payload).expect("bech32 encode")
}
#[test]
fn nevent_kind_out_of_range_is_rejected() {
let mut tlv = Vec::new();
push_tlv(&mut tlv, SPECIAL, &[0xab; 32]);
push_tlv(&mut tlv, KIND, &65_537_u32.to_be_bytes());
let wire = bech32_nip19("nevent", &tlv);
let err = Nip19Event::from_bech32(&wire).expect_err("kind 65537 exceeds nula's 16-bit Kind");
assert!(
matches!(err, FromBech32Error::KindOutOfRange { raw: 65_537 }),
"expected KindOutOfRange, got {err:?}",
);
}
#[test]
fn nevent_invalid_author_is_rejected() {
let mut tlv = Vec::new();
push_tlv(&mut tlv, SPECIAL, &[0xab; 32]);
push_tlv(&mut tlv, AUTHOR, &[0x01; 31]); let wire = bech32_nip19("nevent", &tlv);
assert!(
Nip19Event::from_bech32(&wire).is_err(),
"a 31-byte author TLV must be rejected, not silently dropped",
);
}
#[test]
fn coordinate_preserves_colons_in_identifier() {
let pubkey = "aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4";
let coord = Coordinate::parse(format!("30023:{pubkey}:weird:id:with:colons"))
.expect("valid kind:pubkey:identifier triple");
assert_eq!(
coord.identifier, "weird:id:with:colons",
"nula must preserve colons in the identifier (upstream truncates to `weird`)",
);
}