commit 27a35becfbfae9977533c6700ac77869d0197f1d
parent ece7b260cf468ed3d77b64b420f72af4c22d73eb
Author: triesap <tyson@radroots.org>
Date: Sun, 21 Jun 2026 21:12:08 +0000
events-codec: cover reaction file decode branches
- Cover reaction decode paths for no-relay event/address targets, invalid optional pubkey values, kind mismatches, and invalid numeric kind tags.
- Cover public file metadata decode wrong-kind and minimal-tag empty-content shapes.
- Validate focused reaction/file-metadata tests, full radroots_events_codec tests, crate check, diff check, and refreshed coverage run.
Diffstat:
2 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/crates/events_codec/tests/file_metadata.rs b/crates/events_codec/tests/file_metadata.rs
@@ -251,6 +251,13 @@ fn file_metadata_codec_requires_kind_required_tags_and_hash_shape() {
to_wire_parts_with_kind(&sample_metadata(), KIND_POST),
Err(EventEncodeError::InvalidKind(KIND_POST))
));
+ assert!(matches!(
+ file_metadata_from_event(KIND_POST, &[], ""),
+ Err(EventParseError::InvalidKind {
+ expected: "1063",
+ got: KIND_POST
+ })
+ ));
let mut tags = file_metadata_build_tags(&sample_metadata()).unwrap();
tags.retain(|tag| tag.first().map(|value| value.as_str()) != Some(TAG_URL));
@@ -286,6 +293,30 @@ fn file_metadata_codec_requires_kind_required_tags_and_hash_shape() {
}
#[test]
+fn file_metadata_decode_handles_minimal_public_tags() {
+ let tags = vec![
+ vec![
+ TAG_URL.to_string(),
+ "https://media.example.test/min.jpg".to_string(),
+ ],
+ vec![TAG_MIME.to_string(), "image/jpeg".to_string()],
+ vec![TAG_SHA256.to_string(), VALID_HASH.to_string()],
+ ];
+ let decoded = file_metadata_from_event(KIND_PUBLIC_FILE_METADATA, &tags, "").unwrap();
+
+ assert_eq!(decoded.url, "https://media.example.test/min.jpg");
+ assert_eq!(decoded.mime_type, "image/jpeg");
+ assert_eq!(decoded.sha256, VALID_HASH);
+ assert_eq!(decoded.original_sha256, None);
+ assert_eq!(decoded.size, None);
+ assert_eq!(decoded.dimensions, None);
+ assert_eq!(decoded.thumbnails, None);
+ assert_eq!(decoded.content_hashes, None);
+ assert_eq!(decoded.services, None);
+ assert_eq!(decoded.content, None);
+}
+
+#[test]
fn file_metadata_wrappers_preserve_event_metadata() {
let metadata = sample_metadata();
let parts = to_wire_parts(&metadata).unwrap();
diff --git a/crates/events_codec/tests/reaction.rs b/crates/events_codec/tests/reaction.rs
@@ -283,6 +283,91 @@ fn reaction_from_tags_rejects_missing_legacy_and_mismatched_targets() {
}
#[test]
+fn reaction_from_tags_covers_optional_decode_branches() {
+ let event = reaction_from_tags(
+ KIND_REACTION,
+ &[vec!["e".to_string(), EVENT_ID.to_string()]],
+ "+",
+ )
+ .unwrap();
+ assert_eq!(event.content, "+");
+ match event.target {
+ RadrootsSocialTarget::Event {
+ id,
+ author,
+ event_kind,
+ relays,
+ } => {
+ assert_eq!(id, EVENT_ID);
+ assert_eq!(author, None);
+ assert_eq!(event_kind, None);
+ assert_eq!(relays, None);
+ }
+ _ => panic!("expected event target"),
+ }
+
+ let address = format!("{}:{AUTHOR}:{D_TAG}", KIND_ARTICLE);
+ let reaction = reaction_from_tags(
+ KIND_REACTION,
+ &[vec!["a".to_string(), address.clone()]],
+ "-",
+ )
+ .unwrap();
+ assert_eq!(reaction.content, "-");
+ match reaction.target {
+ RadrootsSocialTarget::Address {
+ address: parsed,
+ author,
+ event_kind,
+ relays,
+ } => {
+ assert_eq!(parsed, address);
+ assert_eq!(author.as_deref(), Some(AUTHOR));
+ assert_eq!(event_kind, Some(KIND_ARTICLE));
+ assert_eq!(relays, None);
+ }
+ _ => panic!("expected address target"),
+ }
+
+ assert!(matches!(
+ reaction_from_tags(
+ KIND_REACTION,
+ &[
+ vec!["e".to_string(), EVENT_ID.to_string()],
+ vec!["p".to_string(), " ".to_string()]
+ ],
+ "+"
+ ),
+ Err(EventParseError::InvalidTag("p"))
+ ));
+ assert!(matches!(
+ reaction_from_tags(
+ KIND_REACTION,
+ &[
+ vec![
+ "a".to_string(),
+ format!("{}:{AUTHOR}:{D_TAG}", KIND_ARTICLE)
+ ],
+ vec!["k".to_string(), KIND_COMMENT.to_string()]
+ ],
+ "+"
+ ),
+ Err(EventParseError::InvalidTag("k"))
+ ));
+ assert!(matches!(
+ reaction_from_tags(
+ KIND_REACTION,
+ &[
+ vec!["e".to_string(), EVENT_ID.to_string()],
+ vec!["k".to_string(), "not-a-kind".to_string()]
+ ],
+ "+"
+ ),
+ Err(EventParseError::InvalidNumber("k", _))
+ ));
+}
+
+#[test]
fn reaction_from_tags_rejects_invalid_kind() {
let tags = reaction_build_tags(&RadrootsReaction {
target: event_target(),