//! L1 tests for [`PtyBridge`] — the PTY↔Channel registry — exercised with a //! real [`tauri::ipc::Channel`] built from a capturing closure (no Tauri runtime //! and no real PTY needed). use std::sync::{Arc, Mutex}; use tauri::ipc::{Channel, InvokeResponseBody}; use app_tauri_lib::pty::PtyBridge; use domain::ids::SessionId; use uuid::Uuid; /// Builds a `Channel>` whose sent chunks are recorded into `sink`. /// /// `Vec` is `Serialize`, so chunks arrive as a JSON array string in an /// `InvokeResponseBody::Json`; we parse them back to bytes for assertions. fn capturing_channel(sink: Arc>>>) -> Channel> { Channel::new(move |body: InvokeResponseBody| { let bytes: Vec = match body { InvokeResponseBody::Json(s) => serde_json::from_str(&s).unwrap(), InvokeResponseBody::Raw(b) => b, }; sink.lock().unwrap().push(bytes); Ok(()) }) } fn sid() -> SessionId { SessionId::from_uuid(Uuid::new_v4()) } #[test] fn register_increases_active_sessions() { let bridge = PtyBridge::new(); assert_eq!(bridge.active_sessions(), 0); let sink = Arc::new(Mutex::new(Vec::new())); bridge.register(sid(), capturing_channel(sink)); assert_eq!(bridge.active_sessions(), 1); } #[test] fn send_output_delivers_bytes_to_registered_channel() { let bridge = PtyBridge::new(); let session = sid(); let sink = Arc::new(Mutex::new(Vec::new())); bridge.register(session, capturing_channel(Arc::clone(&sink))); let delivered = bridge.send_output(&session, vec![104, 105]); assert!(delivered, "send_output should return true for a live session"); let captured = sink.lock().unwrap(); assert_eq!(captured.as_slice(), &[vec![104, 105]]); } #[test] fn send_output_to_unknown_session_returns_false() { let bridge = PtyBridge::new(); assert!(!bridge.send_output(&sid(), vec![0])); } #[test] fn unregister_removes_session_and_stops_delivery() { let bridge = PtyBridge::new(); let session = sid(); let sink = Arc::new(Mutex::new(Vec::new())); bridge.register(session, capturing_channel(Arc::clone(&sink))); assert_eq!(bridge.active_sessions(), 1); bridge.unregister(&session); assert_eq!(bridge.active_sessions(), 0); assert!(!bridge.send_output(&session, vec![1])); assert!(sink.lock().unwrap().is_empty()); } #[test] fn register_same_session_twice_replaces_channel() { let bridge = PtyBridge::new(); let session = sid(); let first = Arc::new(Mutex::new(Vec::new())); let second = Arc::new(Mutex::new(Vec::new())); bridge.register(session, capturing_channel(Arc::clone(&first))); bridge.register(session, capturing_channel(Arc::clone(&second))); assert_eq!(bridge.active_sessions(), 1, "same id is replaced, not added"); bridge.send_output(&session, vec![9]); assert!(first.lock().unwrap().is_empty(), "old channel no longer used"); assert_eq!(second.lock().unwrap().as_slice(), &[vec![9]]); }