use super::RealtimeHandoffState; use super::RealtimeSessionKind; use super::realtime_delegation_from_handoff; use super::realtime_text_from_handoff_request; use super::wrap_realtime_delegation_input; use async_channel::bounded; use codex_protocol::protocol::RealtimeHandoffRequested; use codex_protocol::protocol::RealtimeTranscriptEntry; use pretty_assertions::assert_eq; #[test] fn prefers_handoff_input_transcript_over_active_transcript() { let handoff = RealtimeHandoffRequested { handoff_id: "handoff_1".to_string(), item_id: "item_1".to_string(), input_transcript: "ignored".to_string(), active_transcript: vec![ RealtimeTranscriptEntry { role: "user".to_string(), text: "hello".to_string(), }, RealtimeTranscriptEntry { role: "assistant".to_string(), text: "hi there".to_string(), }, ], }; assert_eq!( realtime_text_from_handoff_request(&handoff), Some("ignored".to_string()) ); } #[test] fn extracts_text_from_handoff_request_active_transcript_if_input_missing() { let handoff = RealtimeHandoffRequested { handoff_id: "handoff_1".to_string(), item_id: "item_1".to_string(), input_transcript: String::new(), active_transcript: vec![RealtimeTranscriptEntry { role: "user".to_string(), text: "hello".to_string(), }], }; assert_eq!( realtime_text_from_handoff_request(&handoff), Some("user: hello".to_string()) ); } #[test] fn wraps_handoff_with_transcript_delta() { let handoff = RealtimeHandoffRequested { handoff_id: "handoff_1".to_string(), item_id: "item_1".to_string(), input_transcript: "delegate this".to_string(), active_transcript: vec![ RealtimeTranscriptEntry { role: "user".to_string(), text: "hello".to_string(), }, RealtimeTranscriptEntry { role: "assistant".to_string(), text: "hi there".to_string(), }, ], }; assert_eq!( realtime_delegation_from_handoff(&handoff), Some( "\n delegate this\n user: hello\nassistant: hi there\n" .to_string() ) ); } #[test] fn extracts_text_from_handoff_request_input_transcript_if_messages_missing() { let handoff = RealtimeHandoffRequested { handoff_id: "handoff_1".to_string(), item_id: "item_1".to_string(), input_transcript: "ignored".to_string(), active_transcript: vec![], }; assert_eq!( realtime_text_from_handoff_request(&handoff), Some("ignored".to_string()) ); } #[test] fn ignores_empty_handoff_request_input_transcript() { let handoff = RealtimeHandoffRequested { handoff_id: "handoff_1".to_string(), item_id: "item_1".to_string(), input_transcript: String::new(), active_transcript: vec![], }; assert_eq!(realtime_text_from_handoff_request(&handoff), None); } #[test] fn wraps_realtime_delegation_input() { assert_eq!( wrap_realtime_delegation_input("hello", /*transcript_delta*/ None), "\n hello\n" ); } #[test] fn wraps_realtime_delegation_input_with_xml_escaping() { assert_eq!( wrap_realtime_delegation_input("use a < b && c > d", Some("saw ")), "\n use a < b && c > d\n saw <that>\n" ); } #[test] fn wraps_realtime_delegation_input_with_xml_escaping_without_transcript() { assert_eq!( wrap_realtime_delegation_input("use a < b && c > d", /*transcript_delta*/ None), "\n use a < b && c > d\n" ); } #[tokio::test] async fn clears_active_handoff_explicitly() { let (tx, _rx) = bounded(1); let state = RealtimeHandoffState::new(tx, RealtimeSessionKind::V1); *state.active_handoff.lock().await = Some("handoff_1".to_string()); assert_eq!( state.active_handoff.lock().await.clone(), Some("handoff_1".to_string()) ); *state.active_handoff.lock().await = None; assert_eq!(state.active_handoff.lock().await.clone(), None); }