commit 09ca67d3d7fa8bb29f7b0b04c3e6da935ea5f348
parent bd57d87d94afbceaf6567da55de5f2ab58bb4563
Author: triesap <tyson@radroots.org>
Date: Fri, 12 Jun 2026 04:12:59 -0700
release: close social preflight gaps
- preserve listing published_at tags in the trade parser
- cover the trade parser published_at round trip and invalid numeric tag path
- run events_codec coverage with the serde_json codec test surface
- record the temporary events_codec branch coverage override for heavy development
Diffstat:
3 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/crates/trade/src/listing/codec.rs b/crates/trade/src/listing/codec.rs
@@ -16,7 +16,7 @@ use radroots_events::listing::{
};
use radroots_events::plot::RadrootsPlotRef;
use radroots_events::resource_area::RadrootsResourceAreaRef;
-use radroots_events::tags::TAG_D;
+use radroots_events::tags::{TAG_D, TAG_PUBLISHED_AT};
pub(crate) use radroots_events::trade::RadrootsTradeListingParseError as TradeListingParseError;
use radroots_events_codec::d_tag::is_d_tag_base64url;
use radroots_events_codec::error::EventEncodeError;
@@ -56,6 +56,13 @@ fn parse_unit(s: &str) -> Result<RadrootsCoreUnit, TradeListingParseError> {
.map_err(|_| TradeListingParseError::InvalidUnit)
}
+fn parse_u64_tag_value(value: Option<&String>, field: &str) -> Result<u64, TradeListingParseError> {
+ value
+ .ok_or_else(|| TradeListingParseError::InvalidTag(field.to_string()))?
+ .parse::<u64>()
+ .map_err(|_| TradeListingParseError::InvalidNumber(field.to_string()))
+}
+
fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, TradeListingParseError> {
let tag = tags
.iter()
@@ -193,6 +200,7 @@ fn listing_from_tags(
let mut delivery_method: Option<RadrootsListingDeliveryMethod> = None;
let mut images: Vec<RadrootsListingImage> = Vec::new();
let mut geohash: Option<String> = None;
+ let mut published_at: Option<u64> = None;
let has_structured_location = tags
.iter()
@@ -208,6 +216,9 @@ fn listing_from_tags(
"title" => set_if_empty(&mut product.title, tag.get(1)),
"category" => set_if_empty(&mut product.category, tag.get(1)),
"summary" => set_optional(&mut product.summary, tag.get(1)),
+ TAG_PUBLISHED_AT => {
+ published_at = Some(parse_u64_tag_value(tag.get(1), TAG_PUBLISHED_AT)?);
+ }
"process" => set_optional(&mut product.process, tag.get(1)),
"lot" => set_optional(&mut product.lot, tag.get(1)),
"location" => {
@@ -462,6 +473,7 @@ fn listing_from_tags(
Ok(RadrootsListing {
d_tag,
+ published_at,
farm: farm_ref,
product,
primary_bin_id,
@@ -738,6 +750,42 @@ mod tests {
}
#[test]
+ fn listing_from_tags_roundtrips_published_at_tag() {
+ let mut tags = base_trade_tags();
+ tags.push(vec![TAG_PUBLISHED_AT.into(), "1781895600".into()]);
+
+ let listing = listing_from_tags(
+ &tags,
+ listing_d_tag(),
+ farm_ref(),
+ "seller".to_string(),
+ None,
+ None,
+ )
+ .expect("listing");
+
+ assert_eq!(listing.published_at, Some(1_781_895_600));
+
+ let published_at = tags
+ .iter_mut()
+ .find(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_PUBLISHED_AT))
+ .expect("published_at tag");
+ published_at[1] = "bad".to_string();
+
+ let err = listing_from_tags(
+ &tags,
+ listing_d_tag(),
+ farm_ref(),
+ "seller".to_string(),
+ None,
+ None,
+ )
+ .unwrap_err();
+
+ assert_eq!(parse_error_tag(err), TAG_PUBLISHED_AT.to_string());
+ }
+
+ #[test]
fn listing_from_tags_rejects_invalid_d_tag() {
let tags = base_trade_tags();
diff --git a/policy/coverage/policy.toml b/policy/coverage/policy.toml
@@ -26,6 +26,14 @@ fail_under_branches = 73.638
temporary = true
reason = "heavy-development branch coverage gap for publish 0.1.0-alpha.2"
+[overrides.radroots_events_codec]
+fail_under_exec_lines = 90.0
+fail_under_functions = 90.0
+fail_under_regions = 90.0
+fail_under_branches = 81.264
+temporary = true
+reason = "heavy-development branch coverage gap for publish 0.1.0-alpha.2"
+
[overrides.radroots_nostr_signer]
fail_under_exec_lines = 89.185
fail_under_functions = 90.0
diff --git a/policy/coverage/profiles.toml b/policy/coverage/profiles.toml
@@ -8,6 +8,11 @@ no_default_features = true
features = []
test_threads = 1
+[profiles.crates."radroots_events_codec"]
+no_default_features = false
+features = ["serde_json"]
+test_threads = 1
+
[profiles.crates."radroots_nostr_runtime"]
no_default_features = true
features = ["std"]