commit c0b700cbf5d3ec4f14bd1330cd9c1c33797620ac
parent f52866fac56e3ce5754655405322d6430c5a5a53
Author: triesap <tyson@radroots.org>
Date: Mon, 27 Apr 2026 23:09:45 +0000
cli: reconcile seller relay publish docs
- describe direct relay seller publish behavior in CLI docs
- add fast coverage for configured-relay publish attempts
- keep order submit and listing update documented as deferred paths
- update legacy write-plane provider wording for the active path
Diffstat:
2 files changed, 100 insertions(+), 8 deletions(-)
diff --git a/src/runtime/provider.rs b/src/runtime/provider.rs
@@ -8,7 +8,7 @@ use crate::runtime::config::{
#[cfg(test)]
use crate::runtime::hyf;
-const WRITE_PLANE_UNAVAILABLE_DETAIL: &str = "actor-authored relay writes are unavailable until direct Nostr relay publishing is implemented";
+const WRITE_PLANE_UNAVAILABLE_DETAIL: &str = "legacy write-plane provider is unavailable; use seller publish commands with configured direct relays";
#[cfg(test)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -160,7 +160,7 @@ fn unavailable_write_plane_view() -> WritePlaneProviderView {
binding_model: "direct_relay_publish".to_owned(),
state: "unavailable".to_owned(),
provenance: ProviderProvenance::Unavailable.as_str().to_owned(),
- source: "direct relay publishing is not implemented".to_owned(),
+ source: "legacy write-plane provider is not active".to_owned(),
target_kind: None,
target: None,
detail: WRITE_PLANE_UNAVAILABLE_DETAIL.to_owned(),
@@ -344,17 +344,14 @@ mod tests {
}
#[test]
- fn write_plane_is_unavailable_until_direct_relay_publish_lands() {
+ fn write_plane_provider_is_not_active_for_direct_relay_publish() {
let view = resolve_write_plane_provider(&sample_config(Vec::new(), false));
assert_eq!(view.provider_runtime_id, "nostr_relay");
assert_eq!(view.binding_model, "direct_relay_publish");
assert_eq!(view.state, "unavailable");
assert_eq!(view.provenance, ProviderProvenance::Unavailable.as_str());
assert!(view.target.is_none());
- assert!(
- view.detail
- .contains("direct Nostr relay publishing is implemented")
- );
+ assert!(view.detail.contains("seller publish commands"));
}
#[test]
@@ -363,7 +360,7 @@ mod tests {
.expect_err("write plane target");
assert_eq!(
error,
- "actor-authored relay writes are unavailable until direct Nostr relay publishing is implemented"
+ "legacy write-plane provider is unavailable; use seller publish commands with configured direct relays"
);
}
diff --git a/tests/signer_runtime_modes.rs b/tests/signer_runtime_modes.rs
@@ -641,6 +641,83 @@ fn local_farm_publish_fails_without_configured_relay() {
}
#[test]
+fn local_seller_publish_commands_attempt_configured_direct_relay() {
+ let sandbox = RadrootsCliSandbox::new();
+ sandbox.json_success(&["--format", "json", "account", "create"]);
+ let farm = sandbox.json_success(&[
+ "--format",
+ "json",
+ "farm",
+ "create",
+ "--name",
+ "Green Farm",
+ "--location",
+ "farmstand",
+ "--country",
+ "US",
+ "--delivery-method",
+ "pickup",
+ ]);
+ let farm_d_tag = farm["result"]["config"]["farm_d_tag"]
+ .as_str()
+ .expect("farm d tag");
+ let relay = "ws://127.0.0.1:9";
+
+ let (farm_output, farm_value) = sandbox.json_output(&[
+ "--format",
+ "json",
+ "--relay",
+ relay,
+ "--approval-token",
+ "approve",
+ "farm",
+ "publish",
+ ]);
+ assert!(!farm_output.status.success());
+ assert_direct_relay_connection_failure(&farm_value, "farm.publish", &["farm", "publish"]);
+
+ let listing_file = create_listing_draft(&sandbox, "direct-relay-attempt");
+ make_listing_publishable(&listing_file, farm_d_tag);
+ let listing_file_arg = listing_file.to_string_lossy();
+
+ let (publish_output, publish_value) = sandbox.json_output(&[
+ "--format",
+ "json",
+ "--relay",
+ relay,
+ "--approval-token",
+ "approve",
+ "listing",
+ "publish",
+ listing_file_arg.as_ref(),
+ ]);
+ assert!(!publish_output.status.success());
+ assert_direct_relay_connection_failure(
+ &publish_value,
+ "listing.publish",
+ &["listing", "publish"],
+ );
+
+ let (archive_output, archive_value) = sandbox.json_output(&[
+ "--format",
+ "json",
+ "--relay",
+ relay,
+ "--approval-token",
+ "approve",
+ "listing",
+ "archive",
+ listing_file_arg.as_ref(),
+ ]);
+ assert!(!archive_output.status.success());
+ assert_direct_relay_connection_failure(
+ &archive_value,
+ "listing.archive",
+ &["listing", "archive"],
+ );
+}
+
+#[test]
fn watch_only_farm_publish_dry_run_fails_as_account_watch_only() {
let sandbox = RadrootsCliSandbox::new();
let public_identity = identity_public(13);
@@ -764,3 +841,21 @@ fn configure_myc_mode(sandbox: &RadrootsCliSandbox, executable: &Path) {
toml_string(executable.display().to_string().as_str())
));
}
+
+fn assert_direct_relay_connection_failure(
+ value: &serde_json::Value,
+ operation_id: &str,
+ args: &[&str],
+) {
+ assert_eq!(value["operation_id"], operation_id);
+ assert_eq!(value["result"], serde_json::Value::Null);
+ assert_eq!(value["errors"][0]["code"], "network_unavailable");
+ assert_ne!(value["errors"][0]["code"], "operation_unavailable");
+ assert_eq!(value["errors"][0]["detail"]["class"], "network");
+ assert_contains(
+ &value["errors"][0]["message"],
+ "direct relay connection failed",
+ );
+ assert_no_removed_command_reference(value, args);
+ assert_no_daemon_runtime_reference(value, args);
+}