use super::{create_test_client, should_run};
use opencode_rs::types::Event;
use std::time::Duration;
use tokio::time::timeout;
#[tokio::test]
#[ignore] async fn test_sse_server_connected() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let event = timeout(Duration::from_secs(5), subscription.recv())
.await
.expect("Timeout waiting for event")
.expect("Failed to get event");
assert!(
event.is_connected(),
"First event should be server.connected, got: {:?}",
event
);
}
#[tokio::test]
#[ignore] async fn test_sse_session_created_event() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let _ = timeout(Duration::from_secs(5), subscription.recv()).await;
let session = client
.sessions()
.create(&Default::default())
.await
.expect("Failed to create session");
let deadline = tokio::time::Instant::now() + Duration::from_secs(10);
let mut found_event = false;
while tokio::time::Instant::now() < deadline {
match timeout(Duration::from_secs(1), subscription.recv()).await {
Ok(Some(Event::SessionCreated { properties })) => {
assert!(
!properties.info.id.is_empty(),
"SessionCreated should have info.id"
);
if properties.info.id == session.id {
found_event = true;
break;
}
}
_ => continue,
}
}
if !found_event {
println!(
"Note: Did not catch session.created for {} (may be timing-related)",
session.id
);
}
let _ = client.sessions().delete(&session.id).await;
}
#[tokio::test]
#[ignore] async fn test_sse_session_idle_event() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let session = client
.sessions()
.create(&Default::default())
.await
.expect("Failed to create session");
let deadline = tokio::time::Instant::now() + Duration::from_secs(10);
while tokio::time::Instant::now() < deadline {
match timeout(Duration::from_secs(1), subscription.recv()).await {
Ok(Some(Event::SessionIdle { properties })) => {
assert!(
properties
.session_id
.as_deref()
.map(|session_id| !session_id.is_empty())
.unwrap_or(false),
"SessionIdle should have session_id"
);
break;
}
_ => continue,
}
}
let _ = client.sessions().delete(&session.id).await;
}
#[tokio::test]
#[ignore] async fn test_sse_message_events() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let session = client
.sessions()
.create(&Default::default())
.await
.expect("Failed to create session");
let deadline = tokio::time::Instant::now() + Duration::from_secs(30);
let mut saw_message_event = false;
while tokio::time::Instant::now() < deadline && !saw_message_event {
if let Ok(Some(event)) = timeout(Duration::from_secs(1), subscription.recv()).await {
match &event {
Event::MessageUpdated { properties } => {
assert!(
!properties.info.id.is_empty(),
"MessageUpdated should have info.id"
);
if let Some(sid) = &properties.info.session_id {
assert!(
!sid.is_empty(),
"MessageUpdated session_id should not be empty if present"
);
}
saw_message_event = true;
}
Event::MessagePartUpdated { properties } => {
if properties.part.is_some() {
saw_message_event = true;
}
}
_ => {}
}
}
}
let _ = client.sessions().delete(&session.id).await;
}
#[tokio::test]
#[ignore] async fn test_sse_permission_events() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let _ = timeout(Duration::from_secs(2), subscription.recv()).await;
}
#[tokio::test]
#[ignore] async fn test_sse_heartbeat() {
if !should_run() {
return;
}
let client = create_test_client().await;
let mut subscription = client
.subscribe()
.await
.expect("Failed to subscribe to SSE");
let deadline = tokio::time::Instant::now() + Duration::from_secs(120);
let mut saw_heartbeat = false;
while tokio::time::Instant::now() < deadline && !saw_heartbeat {
match timeout(Duration::from_secs(10), subscription.recv()).await {
Ok(Some(event)) if event.is_heartbeat() => {
saw_heartbeat = true;
}
_ => {}
}
}
}