From f89be06a335ec9965026a5b5e6968b71cb036a2e Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 10 Oct 2026 02:35:48 +0200 Subject: [PATCH] Begin tests: reuse the untouched-form intent builder; the untouched-form walk begins instead of creating Does not build the fixture replay test: the bridge fixture still carries the old steps until it is re-captured from the real client. Co-Authored-By: Claude Opus 5.5 --- crates/ghostlight-dungeon/src/eve.rs | 9 +++++- crates/ghostlight-dungeon/src/runtime.rs | 38 +++++++----------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/crates/ghostlight-dungeon/src/eve.rs b/crates/ghostlight-dungeon/src/eve.rs index 8332e2b..56c36f1 100644 --- a/crates/ghostlight-dungeon/src/eve.rs +++ b/crates/ghostlight-dungeon/src/eve.rs @@ -916,7 +916,14 @@ mod tests { } assert_eq!(find(root, "world.begin.brief").unwrap()["props"]["value"], ""); - let commands = surface["commands"].as_array().unwrap(); + // Beside the sign-out every signed-in surface carries, Begin is the + // only command. + let commands: Vec<&Value> = surface["commands"] + .as_array() + .unwrap() + .iter() + .filter(|descriptor| descriptor["command"] != "app.auth.logout") + .collect(); assert_eq!(commands.len(), 1, "{commands:?}"); assert_eq!(commands[0]["command"], "world.begin"); assert_eq!(commands[0]["payloadSchema"], "ghostlight.world_create.v4"); diff --git a/crates/ghostlight-dungeon/src/runtime.rs b/crates/ghostlight-dungeon/src/runtime.rs index 96de692..e69c400 100644 --- a/crates/ghostlight-dungeon/src/runtime.rs +++ b/crates/ghostlight-dungeon/src/runtime.rs @@ -5721,30 +5721,16 @@ mod tests { // ---- World.begin ---------------------------------------------------- - fn find_node<'a>(node: &'a Value, id: &str) -> Option<&'a Value> { - if node["id"] == id { - return Some(node); - } - node["children"] - .as_array()? - .iter() - .find_map(|child| find_node(child, id)) - } - - /// The payload the real client builds from the served Begin button: its - /// own action fields (minus the command name) beside the captured - /// `bindings`. Every authored constant comes from the surface this - /// process served, never from a copy in the test. + /// The payload the real client builds from the served Begin button, with + /// the three fields typed. Every authored constant comes from the surface + /// this process served, never from a copy in the test. fn begin_payload_from(surface: &Value, title: &str, brief: &str, subject: &str) -> Value { - let button = find_node(&surface["surface"]["root"], "world.begin") - .expect("the empty-world surface offers Begin"); - let mut payload = button["props"]["action"].as_object().cloned().unwrap(); - payload.remove("command"); - payload.insert( - "bindings".into(), - json!({"title":title,"brief":brief,"subject_label":subject}), - ); - Value::Object(payload) + untouched_intent( + surface, + "world.begin", + &[("title", json!(title)), ("brief", json!(brief)), ("subject_label", json!(subject))], + )["payload"] + .clone() } fn begin_invocation(payload: Value, key: &str) -> Value { @@ -6859,16 +6845,14 @@ mod tests { async fn every_bound_command_admits_the_payload_an_untouched_form_submits() { let fixture = fixture().await; let mut exercised = Vec::new(); - let steps: [(&str, Vec<(&str, Value)>); 5] = [ + let steps: [(&str, Vec<(&str, Value)>); 3] = [ ( - "world.create", + "world.begin", vec![ ("title", json!("Untouched Form World")), ("subject_label", json!("The Operator")), ], ), - ("world.approve", vec![]), - ("world.activate", vec![]), ("world.advance_time", vec![("minutes", json!(1))]), ("world.play", vec![]), ];