mod common; use std::time::Duration; use common::MockTransport; use sgclaw::pipe::{perform_handshake, AgentMessage, BrowserMessage, ExecutionSurfaceKind}; #[test] fn handshake_reads_init_and_writes_init_ack() { let transport = MockTransport::new(vec![BrowserMessage::Init { version: "1.0".to_string(), hmac_seed: "0123456789abcdef".to_string(), capabilities: vec!["browser_action".to_string()], }]); let result = perform_handshake(&transport, Duration::from_secs(5)).unwrap(); let sent = transport.sent_messages(); assert_eq!(result.capabilities, vec!["browser_action"]); assert_eq!(sent.len(), 1); assert!(matches!( &sent[0], AgentMessage::InitAck { version, agent_id, supported_actions } if version == "1.0" && !agent_id.is_empty() && supported_actions.iter().any(|action| action == &sgclaw::pipe::Action::Click) && supported_actions.iter().any(|action| action.as_str() == "eval") )); } #[test] fn handshake_rejects_version_mismatch() { let transport = MockTransport::new(vec![BrowserMessage::Init { version: "9.9".to_string(), hmac_seed: "0123456789abcdef".to_string(), capabilities: vec![], }]); let err = perform_handshake(&transport, Duration::from_secs(5)).unwrap_err(); assert!(err.to_string().contains("unsupported protocol version")); } #[test] fn handshake_capabilities_report_browser_surface_without_redefining_runtime() { let transport = MockTransport::new(vec![BrowserMessage::Init { version: "1.0".to_string(), hmac_seed: "0123456789abcdef".to_string(), capabilities: vec!["browser_action".to_string()], }]); let result = perform_handshake(&transport, Duration::from_secs(5)).unwrap(); let metadata = result .browser_surface_metadata() .expect("expected browser surface metadata"); assert_eq!(metadata.kind, ExecutionSurfaceKind::PrivilegedBrowserPipe); assert!(metadata.privileged); assert!(!metadata.defines_runtime_identity); }