commit b191be105621e95818b890cfda12f5e96f1f721b
parent d27ff693775d5c52e6c3c5c90480869d417e8b1d
Author: triesap <tyson@radroots.org>
Date: Sat, 23 May 2026 08:37:27 +0000
cli: normalize app listing export units
- preserves app-authored package labels during listing export
- normalizes unsupported app unit fields to canonical CLI draft units
- keeps exported drafts on the existing listing validation path
- covers the app-style dozen label in target CLI export tests
Diffstat:
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/runtime/listing.rs b/src/runtime/listing.rs
@@ -1217,6 +1217,7 @@ fn app_listing_draft_from_record(
draft.listing.farm_d_tag = farm_id.clone();
}
normalize_app_listing_availability(&mut draft)?;
+ normalize_app_listing_units(&mut draft);
Ok(draft)
}
@@ -1246,6 +1247,30 @@ fn normalize_app_listing_availability(draft: &mut ListingDraftDocument) -> Resul
Ok(())
}
+fn normalize_app_listing_units(draft: &mut ListingDraftDocument) {
+ let quantity_unit = draft.primary_bin.quantity_unit.trim().to_owned();
+ let price_per_unit = draft.primary_bin.price_per_unit.trim().to_owned();
+ let quantity_unit_supported = quantity_unit.parse::<RadrootsCoreUnit>().is_ok();
+ let price_per_unit_supported = price_per_unit.parse::<RadrootsCoreUnit>().is_ok();
+ if quantity_unit_supported && price_per_unit_supported {
+ return;
+ }
+
+ if draft.primary_bin.label.trim().is_empty() {
+ draft.primary_bin.label = if !quantity_unit_supported && !quantity_unit.is_empty() {
+ quantity_unit.clone()
+ } else {
+ price_per_unit.clone()
+ };
+ }
+ if !quantity_unit_supported {
+ draft.primary_bin.quantity_unit = "each".to_owned();
+ }
+ if !price_per_unit_supported {
+ draft.primary_bin.price_per_unit = "each".to_owned();
+ }
+}
+
fn app_listing_export_issues(
config: &RuntimeConfig,
draft: &ListingDraftDocument,
diff --git a/tests/target_cli.rs b/tests/target_cli.rs
@@ -324,11 +324,11 @@ fn seed_app_listing_record(
"primary_bin": {
"bin_id": "bin-1",
"quantity_amount": "1",
- "quantity_unit": "each",
+ "quantity_unit": "dozen",
"price_amount": "7.50",
"price_currency": "USD",
"price_per_amount": "1",
- "price_per_unit": "each",
+ "price_per_unit": "dozen",
},
"inventory": {
"available": "12",
@@ -3601,6 +3601,10 @@ fn listing_app_records_list_and_export_to_valid_cli_draft() {
assert_eq!(export["result"]["listing_id"], listing_d_tag);
assert_eq!(export["result"]["seller_account_id"], account_id);
assert!(export_path.exists());
+ let exported_contents = fs::read_to_string(&export_path).expect("exported listing draft");
+ assert!(exported_contents.contains("quantity_unit = \"each\""));
+ assert!(exported_contents.contains("price_per_unit = \"each\""));
+ assert!(exported_contents.contains("label = \"dozen\""));
let validate = sandbox.json_success(&[
"--format",