lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit d7ea0fb78b32bd4bb47ce8960307d029f6849e32
parent 60b8e80f98e0cfa86ea86eb6093fd916765243ec
Author: triesap <tyson@radroots.org>
Date:   Sun, 21 Jun 2026 21:05:49 +0000

events-codec: expand calendar file encode coverage

- Cover absent optional calendar encode fields for time events, collection event addresses, RSVP relay echoing, and free/busy tags.

- Cover minimal public file metadata encode shape and invalid dimension validation.

- Validate focused calendar/file metadata tests, full radroots_events_codec tests, crate check, diff check, and refreshed coverage run.

Diffstat:
Mcrates/events_codec/tests/calendar.rs | 42++++++++++++++++++++++++++++++++++++++++++
Mcrates/events_codec/tests/file_metadata.rs | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/crates/events_codec/tests/calendar.rs b/crates/events_codec/tests/calendar.rs @@ -276,6 +276,48 @@ fn calendar_rsvp_to_wire_parts_roundtrips_status_event_id_and_participants() { } #[test] +fn calendar_encode_omits_absent_optional_fields() { + let mut time = sample_time_event(); + time.end = None; + time.location = None; + let tags = calendar_time_event_build_tags(&time).unwrap(); + assert!(!tags.iter().any(|tag| tag[0] == TAG_END)); + assert!(!tags.iter().any(|tag| tag[0] == TAG_LOCATION)); + + let mut collection = sample_calendar_collection(); + collection.events[0] = RadrootsSocialTarget::Address { + address: format!("{KIND_CALENDAR_TIME_EVENT}:{EVENT_AUTHOR}:{EVENT_D_TAG}"), + author: Some(EVENT_AUTHOR.to_string()), + event_kind: None, + relays: None, + }; + let tags = calendar_collection_build_tags(&collection).unwrap(); + assert_eq!( + tags.iter() + .find(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_A)) + .map(Vec::len), + Some(2) + ); + + let mut rsvp = sample_rsvp(); + rsvp.event = RadrootsSocialTarget::Address { + address: format!("{KIND_CALENDAR_TIME_EVENT}:{EVENT_AUTHOR}:{EVENT_D_TAG}"), + author: Some(EVENT_AUTHOR.to_string()), + event_kind: None, + relays: None, + }; + rsvp.free_busy = None; + let tags = rsvp_build_tags(&rsvp).unwrap(); + assert_eq!( + tags.iter() + .find(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_E)) + .map(Vec::len), + Some(2) + ); + assert!(!tags.iter().any(|tag| tag[0] == TAG_FREE_BUSY)); +} + +#[test] fn calendar_codecs_reject_wrong_kind_invalid_dates_and_missing_time_dates() { assert!(matches!( date_to_wire_parts_with_kind(&sample_date_event(), KIND_POST), diff --git a/crates/events_codec/tests/file_metadata.rs b/crates/events_codec/tests/file_metadata.rs @@ -154,6 +154,63 @@ fn file_metadata_to_wire_parts_roundtrips_nip94_tags() { } #[test] +fn file_metadata_encode_handles_minimal_optional_shape_and_invalid_dimensions() { + let mut metadata = sample_metadata(); + metadata.original_sha256 = None; + metadata.size = None; + metadata.dimensions = None; + metadata.thumbnails = None; + metadata.summary = None; + metadata.alt = None; + metadata.fallback = None; + metadata.magnet = None; + metadata.content_hashes = None; + metadata.services = None; + metadata.content = None; + + let parts = to_wire_parts(&metadata).unwrap(); + assert_eq!(parts.content, ""); + assert!( + !parts + .tags + .iter() + .any(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_SIZE)) + ); + assert!( + !parts + .tags + .iter() + .any(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_DIMENSIONS)) + ); + assert!( + !parts + .tags + .iter() + .any(|tag| { tag.first().map(|value| value.as_str()) == Some(TAG_ORIGINAL_SHA256) }) + ); + + let mut metadata = sample_metadata(); + metadata.dimensions = Some(RadrootsSocialMediaDimensions { + width: 0, + height: 800, + }); + assert!(matches!( + file_metadata_build_tags(&metadata), + Err(EventEncodeError::InvalidField("dimensions")) + )); + + let mut metadata = sample_metadata(); + metadata.dimensions = Some(RadrootsSocialMediaDimensions { + width: 1200, + height: 0, + }); + assert!(matches!( + file_metadata_build_tags(&metadata), + Err(EventEncodeError::InvalidField("dimensions")) + )); +} + +#[test] fn file_metadata_public_and_private_kind1063_contracts_do_not_cross_decode() { let public = to_wire_parts(&sample_metadata()).unwrap(); let decoded_public =