diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-13 03:26:03 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-13 03:30:13 +0300 |
| commit | 5cfe5e5e730246948b0c9428ad876b6938590aad (patch) | |
| tree | 53d4bbe1aff6887f63f279eed1b5e4e11e7331b7 /tests | |
| parent | 7f3364a468f7dcfd8c9c84e5737fe5699f0e3a93 (diff) | |
feat: add configurable sidebar metadata tokens
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/api_ping.rs | 54 | ||||
| -rw-r--r-- | tests/cli_wrapper.rs | 75 | ||||
| -rw-r--r-- | tests/cross_area.rs | 22 |
3 files changed, 116 insertions, 35 deletions
diff --git a/tests/api_ping.rs b/tests/api_ping.rs index aea8188a..651a3aa5 100644 --- a/tests/api_ping.rs +++ b/tests/api_ping.rs @@ -425,6 +425,26 @@ fn workspace_list_and_create_round_trip() { ); assert_eq!(fetched["result"]["workspace"]["workspace_id"], workspace_id); + let metadata = send_request( + &socket_path, + &format!( + r#"{{"id":"req_workspace_metadata","method":"workspace.report_metadata","params":{{"workspace_id":"{}","source":"user:test","tokens":{{"jj_status":"2 changes"}}}}}}"#, + workspace_id + ), + ); + assert_eq!(metadata["result"]["type"], "ok"); + let fetched = send_request( + &socket_path, + &format!( + r#"{{"id":"req_workspace_metadata_get","method":"workspace.get","params":{{"workspace_id":"{}"}}}}"#, + workspace_id + ), + ); + assert_eq!( + fetched["result"]["workspace"]["tokens"]["jj_status"], + "2 changes" + ); + let panes = send_request( &socket_path, r#"{"id":"req_6","method":"pane.list","params":{}}"#, @@ -1545,7 +1565,7 @@ fn pane_report_agent_updates_effective_state() { let metadata = send_request( &socket_path, &format!( - r#"{{"id":"req_hook_metadata","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","title":"Refactor auth","display_agent":"Pi auth","custom_status":"middleware","state_labels":{{"working":"deep in the mines"}}}}}}"#, + r#"{{"id":"req_hook_metadata","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","title":"Refactor auth","display_agent":"Pi auth","state_labels":{{"working":"deep in the mines"}},"tokens":{{"summary":"reviewing auth","model":"opus"}}}}}}"#, pane_id ), ); @@ -1562,11 +1582,15 @@ fn pane_report_agent_updates_effective_state() { assert_eq!(pane["result"]["pane"]["agent_status"], "working"); assert_eq!(pane["result"]["pane"]["title"], "Refactor auth"); assert_eq!(pane["result"]["pane"]["display_agent"], "Pi auth"); - assert_eq!(pane["result"]["pane"]["custom_status"], "middleware"); assert_eq!( pane["result"]["pane"]["state_labels"]["working"], "deep in the mines" ); + assert_eq!( + pane["result"]["pane"]["tokens"]["summary"], + "reviewing auth" + ); + assert_eq!(pane["result"]["pane"]["tokens"]["model"], "opus"); let agent = send_request( &socket_path, @@ -1585,28 +1609,20 @@ fn pane_report_agent_updates_effective_state() { ); assert_eq!(agent["result"]["agent"]["title"], "Refactor auth"); assert_eq!(agent["result"]["agent"]["display_agent"], "Pi auth"); - assert_eq!(agent["result"]["agent"]["custom_status"], "middleware"); assert_eq!( agent["result"]["agent"]["state_labels"]["working"], "deep in the mines" ); - - let invalid_metadata = send_request( - &socket_path, - &format!( - r#"{{"id":"req_hook_metadata_invalid","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","custom_status":"x","clear_custom_status":true}}}}"#, - pane_id - ), - ); assert_eq!( - invalid_metadata["error"]["code"], - "invalid_metadata_request" + agent["result"]["agent"]["tokens"]["summary"], + "reviewing auth" ); + assert_eq!(agent["result"]["agent"]["tokens"]["model"], "opus"); let blank_source_metadata = send_request( &socket_path, &format!( - r#"{{"id":"req_hook_metadata_blank_source","method":"pane.report_metadata","params":{{"pane_id":"{}","source":" ","custom_status":"x"}}}}"#, + r#"{{"id":"req_hook_metadata_blank_source","method":"pane.report_metadata","params":{{"pane_id":"{}","source":" ","title":"x"}}}}"#, pane_id ), ); @@ -1630,7 +1646,7 @@ fn pane_report_agent_updates_effective_state() { let blank_authority_source_metadata = send_request( &socket_path, &format!( - r#"{{"id":"req_hook_metadata_blank_authority_source","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","applies_to_source":" ","custom_status":"x"}}}}"#, + r#"{{"id":"req_hook_metadata_blank_authority_source","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","applies_to_source":" ","title":"x"}}}}"#, pane_id ), ); @@ -2277,7 +2293,7 @@ fn metadata_status_subscription_filter_and_ttl_expiry_are_observable() { let metadata = send_request( &socket_path, &format!( - r#"{{"id":"req_meta_sub_3","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","custom_status":"filtered out"}}}}"#, + r#"{{"id":"req_meta_sub_3","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","title":"filtered out"}}}}"#, pane_id ), ); @@ -2303,7 +2319,7 @@ fn metadata_status_subscription_filter_and_ttl_expiry_are_observable() { let metadata = send_request( &socket_path, &format!( - r#"{{"id":"req_meta_sub_4","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","custom_status":"short lived","ttl_ms":100}}}}"#, + r#"{{"id":"req_meta_sub_4","method":"pane.report_metadata","params":{{"pane_id":"{}","source":"user:pi-display","agent":"pi","applies_to_source":"herdr:pi","title":"short lived","ttl_ms":100}}}}"#, pane_id ), ); @@ -2314,14 +2330,14 @@ fn metadata_status_subscription_filter_and_ttl_expiry_are_observable() { assert_eq!(set_event["data"]["pane_id"], pane_id); assert_eq!(set_event["data"]["agent_status"], "working"); assert_eq!(set_event["data"]["agent"], "pi"); - assert_eq!(set_event["data"]["custom_status"], "short lived"); + assert_eq!(set_event["data"]["title"], "short lived"); let expiry_event = reader.read_json_line(Duration::from_secs(3)); assert_eq!(expiry_event["event"], "pane.agent_status_changed"); assert_eq!(expiry_event["data"]["pane_id"], pane_id); assert_eq!(expiry_event["data"]["agent_status"], "working"); assert_eq!(expiry_event["data"]["agent"], "pi"); - assert!(expiry_event["data"]["custom_status"].is_null()); + assert!(expiry_event["data"]["title"].is_null()); cleanup_spawned_herdr(child, base); } diff --git a/tests/cli_wrapper.rs b/tests/cli_wrapper.rs index 10a00c41..78d4c123 100644 --- a/tests/cli_wrapper.rs +++ b/tests/cli_wrapper.rs @@ -898,6 +898,61 @@ fn pane_run_sends_one_send_input_request_with_enter_key() { } #[test] +fn workspace_report_metadata_sends_token_patch() { + let base = unique_test_dir(); + fs::create_dir_all(&base).unwrap(); + let socket_path = base.join("herdr.sock"); + let listener = UnixListener::bind(&socket_path).unwrap(); + + let server = thread::spawn(move || { + let (mut stream, _) = listener.accept().unwrap(); + let mut line = String::new(); + let mut reader = BufReader::new(stream.try_clone().unwrap()); + reader.read_line(&mut line).unwrap(); + stream + .write_all(br#"{"id":"cli:request","result":{"type":"ok"}}"#) + .unwrap(); + stream.write_all(b"\n").unwrap(); + stream.flush().unwrap(); + line + }); + + let run = run_cli( + &socket_path, + &[ + "workspace", + "report-metadata", + "2", + "--source", + "user:jj", + "--token", + "jj_status=2 changes", + "--token", + "summary=clean", + "--clear-token", + "old", + "--ttl-ms", + "5000", + ], + ); + assert!( + run.status.success(), + "stderr: {}", + String::from_utf8_lossy(&run.stderr) + ); + + let request: serde_json::Value = serde_json::from_str(&server.join().unwrap()).unwrap(); + assert_eq!(request["method"], "workspace.report_metadata"); + assert_eq!(request["params"]["workspace_id"], "2"); + assert_eq!(request["params"]["tokens"]["jj_status"], "2 changes"); + assert_eq!(request["params"]["tokens"]["summary"], "clean"); + assert!(request["params"]["tokens"]["old"].is_null()); + assert_eq!(request["params"]["ttl_ms"], 5000); + + cleanup_test_base(&base); +} + +#[test] fn pane_report_metadata_sends_presentation_request() { let base = unique_test_dir(); fs::create_dir_all(&base).unwrap(); @@ -931,10 +986,14 @@ fn pane_report_metadata_sends_presentation_request() { "Refactor auth", "--display-agent", "Claude auth", - "--custom-status", - "middleware", "--state-label", "working=deep in the mines", + "--token", + "summary=reviewing auth", + "--token", + "model=opus", + "--clear-token", + "old", "--ttl-ms", "3600000", ], @@ -954,11 +1013,13 @@ fn pane_report_metadata_sends_presentation_request() { assert!(request["params"]["applies_to_source"].is_null()); assert_eq!(request["params"]["title"], "Refactor auth"); assert_eq!(request["params"]["display_agent"], "Claude auth"); - assert_eq!(request["params"]["custom_status"], "middleware"); assert_eq!( request["params"]["state_labels"]["working"], "deep in the mines" ); + assert_eq!(request["params"]["tokens"]["summary"], "reviewing auth"); + assert_eq!(request["params"]["tokens"]["model"], "opus"); + assert!(request["params"]["tokens"]["old"].is_null()); assert_eq!(request["params"]["ttl_ms"], 3_600_000); cleanup_test_base(&base); @@ -978,8 +1039,8 @@ fn pane_report_metadata_rejects_blank_source_before_socket_request() { "1-1", "--source", " ", - "--custom-status", - "middleware", + "--token", + "summary=middleware", ], ); @@ -1009,8 +1070,8 @@ fn pane_report_metadata_rejects_blank_applies_to_source_before_socket_request() "user:claude-title", "--applies-to-source", " ", - "--custom-status", - "middleware", + "--token", + "summary=middleware", ], ); diff --git a/tests/cross_area.rs b/tests/cross_area.rs index 9fe71790..0ee9aa2b 100644 --- a/tests/cross_area.rs +++ b/tests/cross_area.rs @@ -836,7 +836,9 @@ fn cross_area_agent_process_survives_detach_and_reattach() { client_handshake(&mut client_b, CURRENT_PROTOCOL, 80, 24); let saw_working_on_client = wait_for_frame_matching(&mut client_b, Duration::from_secs(5), |frame| { - frame_contains_text(frame, "working") + ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] + .iter() + .any(|symbol| frame_contains_text(frame, symbol)) }) .expect("frame decoding should succeed"); assert!( @@ -844,21 +846,23 @@ fn cross_area_agent_process_survives_detach_and_reattach() { "reattached client frame should expose persisted agent working status" ); - // Transition to idle and verify API + client surfaces both observe it. - pane_report_agent(&api_socket, &pane_id, "pi", "idle", "cross-area-test"); + // Transition to blocked and verify API + client surfaces both observe it. + // The fake process remains visibly working, so blocked is the deterministic + // higher-priority semantic transition for this cross-area projection test. + pane_report_agent(&api_socket, &pane_id, "pi", "blocked", "cross-area-test"); assert!( - wait_for_agent_status(&api_socket, &pane_id, "idle", Duration::from_secs(3)), - "pane agent status should transition to idle" + wait_for_agent_status(&api_socket, &pane_id, "blocked", Duration::from_secs(3)), + "pane agent status should transition to blocked" ); - let saw_idle_on_client = + let saw_blocked_on_client = wait_for_frame_matching(&mut client_b, Duration::from_secs(5), |frame| { - frame_contains_text(frame, "idle") + frame_contains_text(frame, "◉") }) .expect("frame decoding should succeed"); assert!( - saw_idle_on_client, - "reattached client frame should show idle status after transition" + saw_blocked_on_client, + "reattached client frame should show blocked status after transition" ); cleanup_spawned_herdr(server, base); |
