use super::*;
fn uses_the_network(modern: bool, websocket: bool) -> Result<(), Box<dyn Error>> {
let persistence_directory = test_persistence::directory()?;
let server = RunningServer::start(persistence_directory.path())?;
let (worker, seen) = answering_worker(server.address, 3)?;
let dir = tempfile::tempdir()?;
let seat = if websocket {
server.websocket_url()
} else {
server.address.to_string()
};
let ticket = Ticket::start(dir.path(), seat, 5_000)?;
let connections_before = server.active_connections()?;
let mut host = Host::open(ticket, modern)?;
assert_eq!(server.active_connections()?, connections_before);
let tools = host.request("tools/list", json!({}))?;
tools_list_matches(modern, &tools);
let listed = host.tool("list", &json!({}))?;
let stations = listed["structuredContent"]["stations"]
.as_array()
.cloned()
.unwrap_or_default();
let worker_station = stations
.iter()
.find(|s| s["subjects"] == json!([SUBJECT]))
.ok_or("the worker is not listed")?;
assert_eq!(worker_station["activities"], json!(["echo"]));
subject_schema_matches(&mut host)?;
assert_eq!(
server.connections_settled_to(connections_before)?,
connections_before
);
let called = host.tool(
"call",
&json!({ "subject": SUBJECT, "input": { "text": "hi" } }),
)?;
assert_eq!(called["isError"], false, "{called}");
assert_eq!(
called["structuredContent"],
json!({ "echoed": { "text": "hi" } })
);
assert_eq!(
seen.recv_timeout(PUSH_RECV_TIMEOUT)?,
json!({ "text": "hi" })
);
let flowed = host.tool(
"flow",
&json!({ "steps": [
{ "subject": SUBJECT, "input": { "text": "a" } },
{ "subject": SUBJECT, "input": { "again": { "$prev": "/echoed/text" } } }
] }),
)?;
assert_eq!(flowed["isError"], false);
assert_eq!(
seen.recv_timeout(PUSH_RECV_TIMEOUT)?,
json!({ "text": "a" })
);
assert_eq!(
seen.recv_timeout(PUSH_RECV_TIMEOUT)?,
json!({ "again": "a" })
);
assert_eq!(
flowed["structuredContent"]["steps"][1]["reply"],
json!({ "echoed": { "again": "a" } })
);
let refused = host.tool("call", &json!({ "subject": "nobody.request", "input": {} }))?;
assert_eq!(refused["isError"], true);
let words = refused["structuredContent"]["error"]
.as_str()
.unwrap_or_default()
.to_owned();
assert!(!words.is_empty(), "{refused}");
assert_eq!(
server.connections_settled_to(connections_before)?,
connections_before
);
let pass = std::fs::read_to_string(dir.path().join("token"))?
.trim()
.to_owned();
let (stderr, code) = host.ticket.close()?;
assert_eq!(code, 0, "{stderr}");
assert!(!stderr.contains(&pass), "the pass reached stderr");
drop(worker);
Ok(())
}
#[test]
fn a_modern_host_uses_the_network_through_stdio() -> Result<(), Box<dyn Error>> {
uses_the_network(true, false)
}
#[test]
fn a_legacy_host_uses_the_network_through_stdio() -> Result<(), Box<dyn Error>> {
uses_the_network(false, false)
}
#[test]
fn a_host_uses_the_network_through_the_websocket_door() -> Result<(), Box<dyn Error>> {
uses_the_network(true, true)
}