#[path = "helpers/mod.rs"]
mod helpers;
use nerve_protocol::types::{FrameFlags, MessageType};
const TOKEN: &str = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
#[test]
fn ping_echoes_request_id() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
helpers::send_nerve(
&mut ws,
MessageType::Ping,
FrameFlags::FINAL,
0xdeadbeef,
&[],
);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(reply.header.request_id, 0xdeadbeef);
}
#[test]
fn ping_reply_flags_and_type() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
helpers::send_nerve(&mut ws, MessageType::Ping, FrameFlags::FINAL, 1, &[]);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(
reply.header.msg_type,
MessageType::Ping as u8,
"reply message type must be Ping"
);
assert_eq!(
reply.header.flags & FrameFlags::FINAL.bits(),
FrameFlags::FINAL.bits(),
"Ping reply must have the FINAL flag set"
);
assert_eq!(
reply.header.flags & FrameFlags::STREAM.bits(),
0,
"Ping reply must not have the STREAM flag set"
);
}
#[test]
fn search_query_handled_connection_stays_open() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
helpers::send_nerve(
&mut ws,
MessageType::SearchQuery,
FrameFlags::empty(),
42,
b"{}",
);
helpers::send_nerve(&mut ws, MessageType::Ping, FrameFlags::FINAL, 43, &[]);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(
reply.header.request_id, 43,
"connection must remain open after SearchQuery"
);
}
#[test]
fn cancel_handled_connection_stays_open() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
helpers::send_nerve(
&mut ws,
MessageType::SearchQuery,
FrameFlags::empty(),
99,
b"{}",
);
helpers::send_nerve(&mut ws, MessageType::Cancel, FrameFlags::FINAL, 99, &[]);
helpers::send_nerve(&mut ws, MessageType::Ping, FrameFlags::FINAL, 100, &[]);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(
reply.header.request_id, 100,
"connection must remain open after Cancel"
);
}
#[test]
fn agent_task_lifecycle() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
helpers::send_nerve(
&mut ws,
MessageType::AgentTaskStart,
FrameFlags::empty(),
200,
b"{}",
);
helpers::send_nerve(
&mut ws,
MessageType::AgentTaskEvent,
FrameFlags::STREAM,
200,
b"{}",
);
helpers::send_nerve(
&mut ws,
MessageType::AgentTaskDone,
FrameFlags::FINAL,
200,
&[],
);
helpers::send_nerve(&mut ws, MessageType::Ping, FrameFlags::FINAL, 201, &[]);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(reply.header.request_id, 201);
}
#[test]
fn multiple_pings_distinct_ids() {
let port = helpers::start_server(TOKEN, "");
let mut ws = helpers::connect_ws(port, TOKEN, None);
let ids = [0u64, 1, u64::MAX, 42, 0xabcd];
for &id in &ids {
helpers::send_nerve(&mut ws, MessageType::Ping, FrameFlags::FINAL, id, &[]);
let reply = helpers::recv_nerve(&mut ws);
assert_eq!(
reply.header.request_id, id,
"request_id mismatch for id={id}"
);
}
}