#![allow(
clippy::unwrap_used,
clippy::expect_used,
reason = "test code — panics are acceptable failures"
)]
mod support;
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;
use axum::{
body::Body,
http::{Request, StatusCode},
};
use cognee_graph::{GraphDBTrait, MockGraphDB};
use serde_json::json;
use tower::ServiceExt;
use uuid::Uuid;
#[tokio::test]
async fn ws_subscribe_route_exists() {
use cognee_http_server::{AppState, HttpServerConfig, build_router};
let state = AppState::build(HttpServerConfig::default())
.await
.expect("AppState::build");
let app = build_router(state).await.expect("build_router");
let run_id = Uuid::new_v4();
let path = format!("/api/v1/cognify/subscribe/{run_id}");
let req = Request::builder()
.method("GET")
.uri(&path)
.body(Body::empty())
.unwrap();
let resp = app.oneshot(req).await.expect("oneshot");
assert_ne!(
resp.status(),
StatusCode::NOT_FOUND,
"route must exist at /api/v1/cognify/subscribe/{{run_id}}"
);
assert!(
resp.status().is_client_error(),
"plain GET (no WS headers) must return 4xx, not 404 or 5xx; got {}",
resp.status()
);
}
#[tokio::test]
async fn ws_frame_payload_includes_graph_snapshot() {
let mock_graph = MockGraphDB::new();
mock_graph
.add_node_raw(json!({
"id": "n1",
"type": "Entity",
"name": "Carol",
}))
.await
.expect("add n1");
mock_graph
.add_node_raw(json!({
"id": "n2",
"type": "Entity",
"name": "Dave",
}))
.await
.expect("add n2");
mock_graph
.add_edge(
"n1",
"n2",
"WORKS_WITH",
Some(HashMap::from([(Cow::Borrowed("since"), json!("2024"))])),
)
.await
.expect("add edge");
let graph_db: Arc<dyn GraphDBTrait> = Arc::new(mock_graph);
let db = support::build_search_db().await;
let handles = support::build_component_handles(db, None, None, Some(graph_db));
let dataset_id = Some(Uuid::new_v4());
let user_id = Uuid::new_v4();
let payload = handles
.formatted_graph_data(dataset_id, user_id)
.await
.expect("formatted_graph_data");
let nodes = payload["nodes"].as_array().expect("nodes array");
let edges = payload["edges"].as_array().expect("edges array");
assert_eq!(nodes.len(), 2, "WS payload must surface real nodes");
assert_eq!(edges.len(), 1, "WS payload must surface real edges");
for n in nodes {
let obj = n.as_object().expect("node object");
assert!(obj.contains_key("id"));
assert!(obj.contains_key("label"));
assert!(obj.contains_key("type"));
assert!(obj.contains_key("properties"));
}
for e in edges {
let obj = e.as_object().expect("edge object");
assert!(obj.contains_key("source"));
assert!(obj.contains_key("target"));
assert!(obj.contains_key("label"));
}
}
#[tokio::test]
async fn ws_frame_payload_fallback_when_graph_db_missing() {
let db = support::build_search_db().await;
let handles = support::build_component_handles(db, None, None, None);
let payload = handles
.formatted_graph_data(Some(Uuid::new_v4()), Uuid::new_v4())
.await
.expect("formatted_graph_data fallback");
assert!(payload["nodes"].is_array());
assert!(payload["edges"].is_array());
assert!(payload["nodes"].as_array().unwrap().is_empty());
assert!(payload["edges"].as_array().unwrap().is_empty());
}
#[tokio::test]
async fn ws_cognify_end_to_end_skips_without_openai() {
if std::env::var("OPENAI_URL").is_err() {
eprintln!(
"test_cognify_websocket: skipping — OPENAI_URL not set \
(set OPENAI_URL + OPENAI_TOKEN to run)"
);
return;
}
if std::env::var("COGNEE_E2E_EMBED_MODEL_PATH").is_err() {
eprintln!("test_cognify_websocket: skipping — COGNEE_E2E_EMBED_MODEL_PATH not set");
return;
}
eprintln!(
"test_cognify_websocket: skipping — full live-server test deferred; \
payload assembly is covered by ws_frame_payload_includes_graph_snapshot"
);
}