commit 693e8e0d23442b57467736c0610f6f700df30ff5
parent ba0ce9d3cb1ed6a768540f16016040fd78f4c041
Author: triesap <tyson@radroots.org>
Date: Mon, 27 Apr 2026 06:35:28 +0000
cli: make seller flow executable
- document seller setup through local account and farm defaults
- wire farm create target inputs used by seller examples
- replace weak seller example data with valid listing values
- assert validate dry-run and signed publish in seller flow tests
Diffstat:
3 files changed, 103 insertions(+), 9 deletions(-)
diff --git a/src/operation_adapter.rs b/src/operation_adapter.rs
@@ -775,7 +775,7 @@ fn value_to_data(value: Value) -> OperationData {
fn target_operation_input(command: &crate::target_cli::TargetCommand) -> OperationData {
use crate::target_cli::{
AccountCommand, AccountSelectionCommand, BasketCommand, BasketItemCommand,
- BasketQuoteCommand, ListingCommand, MarketCommand, MarketListingCommand,
+ BasketQuoteCommand, FarmCommand, ListingCommand, MarketCommand, MarketListingCommand,
MarketProductCommand, OrderCommand, OrderEventCommand, TargetCommand,
};
@@ -798,6 +798,28 @@ fn target_operation_input(command: &crate::target_cli::TargetCommand) -> Operati
},
AccountCommand::Create | AccountCommand::List => {}
},
+ TargetCommand::Farm(args) => match &args.command {
+ FarmCommand::Create(args) => {
+ insert_string(&mut input, "farm_d_tag", &args.farm_d_tag);
+ insert_string(&mut input, "name", &args.name);
+ insert_string(&mut input, "display_name", &args.display_name);
+ insert_string(&mut input, "about", &args.about);
+ insert_string(&mut input, "website", &args.website);
+ insert_string(&mut input, "picture", &args.picture);
+ insert_string(&mut input, "banner", &args.banner);
+ insert_string(&mut input, "location", &args.location);
+ insert_string(&mut input, "city", &args.city);
+ insert_string(&mut input, "region", &args.region);
+ insert_string(&mut input, "country", &args.country);
+ insert_string(&mut input, "delivery_method", &args.delivery_method);
+ }
+ FarmCommand::Get
+ | FarmCommand::Profile(_)
+ | FarmCommand::Location(_)
+ | FarmCommand::Fulfillment(_)
+ | FarmCommand::Readiness(_)
+ | FarmCommand::Publish => {}
+ },
TargetCommand::Listing(args) => match &args.command {
ListingCommand::Create(args) => {
insert_path(&mut input, "output", &args.output);
diff --git a/src/target_cli.rs b/src/target_cli.rs
@@ -141,7 +141,7 @@ impl TargetCommand {
JobCommand::Watch => "job.watch",
},
Self::Farm(args) => match &args.command {
- FarmCommand::Create => "farm.create",
+ FarmCommand::Create(_) => "farm.create",
FarmCommand::Get => "farm.get",
FarmCommand::Profile(profile) => match profile.command {
FarmProfileCommand::Update => "farm.profile.update",
@@ -469,7 +469,7 @@ pub struct FarmArgs {
#[derive(Debug, Clone, Subcommand)]
pub enum FarmCommand {
- Create,
+ Create(FarmCreateArgs),
Get,
Profile(FarmProfileArgs),
Location(FarmLocationArgs),
@@ -479,6 +479,34 @@ pub enum FarmCommand {
}
#[derive(Debug, Clone, Args)]
+pub struct FarmCreateArgs {
+ #[arg(long = "farm-d-tag")]
+ pub farm_d_tag: Option<String>,
+ #[arg(long)]
+ pub name: Option<String>,
+ #[arg(long = "display-name")]
+ pub display_name: Option<String>,
+ #[arg(long)]
+ pub about: Option<String>,
+ #[arg(long)]
+ pub website: Option<String>,
+ #[arg(long)]
+ pub picture: Option<String>,
+ #[arg(long)]
+ pub banner: Option<String>,
+ #[arg(long)]
+ pub location: Option<String>,
+ #[arg(long)]
+ pub city: Option<String>,
+ #[arg(long)]
+ pub region: Option<String>,
+ #[arg(long)]
+ pub country: Option<String>,
+ #[arg(long = "delivery-method")]
+ pub delivery_method: Option<String>,
+}
+
+#[derive(Debug, Clone, Args)]
pub struct FarmProfileArgs {
#[command(subcommand)]
pub command: FarmProfileCommand,
diff --git a/tests/target_cli.rs b/tests/target_cli.rs
@@ -302,6 +302,28 @@ fn seller_mvp_flow_acceptance_uses_target_operations() {
let listing_file = sandbox.root().join("listing.toml");
let listing_file = listing_file.to_string_lossy().into_owned();
+ let account = json_success(&sandbox, &["--format", "json", "account", "create"]);
+ assert_eq!(account["operation_id"], "account.create");
+ assert_eq!(account["result"]["account"]["signer"], "local");
+
+ let farm = json_success(
+ &sandbox,
+ &[
+ "--format",
+ "json",
+ "farm",
+ "create",
+ "--name",
+ "Green Farm",
+ "--location",
+ "farmstand",
+ "--delivery-method",
+ "pickup",
+ ],
+ );
+ assert_eq!(farm["operation_id"], "farm.create");
+ assert_eq!(farm["result"]["state"], "saved");
+
let create = json_success(
&sandbox,
&[
@@ -315,12 +337,16 @@ fn seller_mvp_flow_acceptance_uses_target_operations() {
"eggs",
"--title",
"Eggs",
+ "--category",
+ "eggs",
+ "--summary",
+ "Fresh eggs",
"--bin-id",
"bin-1",
"--quantity-amount",
"1",
"--quantity-unit",
- "dozen",
+ "each",
"--price-amount",
"6",
"--price-currency",
@@ -328,7 +354,7 @@ fn seller_mvp_flow_acceptance_uses_target_operations() {
"--price-per-amount",
"1",
"--price-per-unit",
- "dozen",
+ "each",
"--available",
"10",
],
@@ -347,7 +373,8 @@ fn seller_mvp_flow_acceptance_uses_target_operations() {
],
);
assert_eq!(validate["operation_id"], "listing.validate");
- assert!(validate["result"]["valid"].is_boolean());
+ assert_eq!(validate["result"]["valid"], true);
+ assert_eq!(validate["result"]["issues"], Value::Null);
let publish = json_success(
&sandbox,
@@ -363,7 +390,24 @@ fn seller_mvp_flow_acceptance_uses_target_operations() {
assert_eq!(publish["operation_id"], "listing.publish");
assert_eq!(publish["result"]["state"], "dry_run");
- let orders = json_success(&sandbox, &["--format", "json", "order", "list"]);
- assert_eq!(orders["operation_id"], "order.list");
- assert_eq!(orders["errors"].as_array().expect("errors").len(), 0);
+ let signed = json_success(
+ &sandbox,
+ &[
+ "--format",
+ "json",
+ "--approval-token",
+ "approve",
+ "listing",
+ "publish",
+ listing_file.as_str(),
+ ],
+ );
+ assert_eq!(signed["operation_id"], "listing.publish");
+ assert_eq!(signed["result"]["state"], "signed");
+ assert_eq!(signed["result"]["signer_mode"], "local");
+ assert_eq!(
+ signed["result"]["event"]["author"],
+ signed["result"]["seller_pubkey"]
+ );
+ assert!(signed["result"]["event"]["signature"].is_string());
}