Skip to main content
Glama

CodeGraph CLI MCP Server

by Jakedismo
api_resolver_tests.rs6.02 kB
use async_graphql::{Request, Variables}; use serde_json::json; mod helpers; use helpers::*; async fn build_schema() -> codegraph_api::schema::CodeGraphSchema { let _lock = TEST_DB_GUARD.lock(); let _wd = temp_workdir(); let cfg = codegraph_core::ConfigManager::new_watching(None).expect("config"); let state = codegraph_api::state::AppState::new(cfg).await.expect("state"); codegraph_api::schema::create_schema(state) } #[tokio::test] async fn api_health_and_version() { let schema = build_schema().await; let q = "{ health version }"; let res = schema.execute(Request::new(q)).await; assert!(res.errors.is_empty()); let data = res.data.into_json().unwrap(); assert!(data["health"].is_string()); assert!(data["version"].is_string()); } #[tokio::test] async fn mutation_add_update_delete_node() { let schema = build_schema().await; // Add let add = r#" mutation Add($input: AddNodeInput!) { addNode(input: $input) } "#; let vars = Variables::from_json(json!({ "input": { "name": "N", "nodeType": "FUNCTION", "language": "RUST", "filePath": "f.rs", "startLine": 1, "startColumn": 1, "endLine": 1, "endColumn": 10 } })); let res = schema.execute(Request::new(add).variables(vars)).await; assert!(res.errors.is_empty()); // Query one random ID (may return null but should not error) let node_id = uuid::Uuid::new_v4().to_string(); let q = r#"query($id: ID!){ node(id: $id){ id name } }"#; let res = schema .execute(Request::new(q).variables(Variables::from_json(json!({"id": node_id})))) .await; assert!(res.errors.is_empty()); } #[tokio::test] async fn mutation_batch_operations_executes() { let schema = build_schema().await; let m = r#" mutation Batch($ops: [BatchOperationInput!]!) { batchOperations(operations: $ops) } "#; let id = uuid::Uuid::new_v4().to_string(); let vars = Variables::from_json(json!({ "ops": [ {"addNode": {"name":"A","nodeType":"FUNCTION","language":"RUST","filePath":"a.rs","startLine":1,"startColumn":1,"endLine":1,"endColumn":5}}, {"updateNode": {"id": id, "name": "B"}}, {"deleteNode": {"id": id}} ] })); let res = schema.execute(Request::new(m).variables(vars)).await; assert!(res.errors.is_empty()); } #[tokio::test] async fn query_nodes_batch_and_neighbors() { let schema = build_schema().await; let ids = vec![uuid::Uuid::new_v4().to_string(), uuid::Uuid::new_v4().to_string()]; let q = r#" query($a: ID!, $b: ID!){ nodes(ids: [$a,$b]){ id name } getNeighbors(id:$a, limit: 5){ id name } } "#; let vars = Variables::from_json(json!({"a": ids[0], "b": ids[1]})); let res = schema.execute(Request::new(q).variables(vars)).await; assert!(res.errors.is_empty()); let data = res.data.into_json().unwrap(); assert!(data["nodes"].is_array()); assert!(data["getNeighbors"].is_array()); } #[tokio::test] async fn query_find_path_structure() { let schema = build_schema().await; let a = uuid::Uuid::new_v4().to_string(); let b = uuid::Uuid::new_v4().to_string(); let q = r#"query($a:ID!,$b:ID!){ findPath(from:$a,to:$b,maxDepth:3){ id sourceId targetId edgeType } }"#; let res = schema .execute(Request::new(q).variables(Variables::from_json(json!({"a":a,"b":b})))) .await; assert!(res.errors.is_empty()); } #[tokio::test] async fn node_query_invalid_uuid_is_graceful() { let schema = build_schema().await; let q = r#"query($id:ID!){ node(id:$id){ id } }"#; let res = schema .execute(Request::new(q).variables(Variables::from_json(json!({"id":"not-a-uuid"})))) .await; // Accept either error or null result, but no panic if !res.errors.is_empty() { let msg = res.errors[0].message.to_lowercase(); assert!(msg.contains("invalid") || msg.contains("uuid")); } } #[tokio::test] async fn simple_health_only() { let schema = build_schema().await; let res = schema.execute(Request::new("{ health }")).await; assert!(res.errors.is_empty()); } #[tokio::test] async fn simple_version_only() { let schema = build_schema().await; let res = schema.execute(Request::new("{ version }")).await; assert!(res.errors.is_empty()); let data = res.data.into_json().unwrap(); let v = data["version"].as_str().unwrap(); assert!(v.contains('.')); } #[tokio::test] async fn maintenance_mutations() { let schema = build_schema().await; let m1 = "mutation{ triggerReindexing }"; let m2 = r#"mutation($i:UpdateConfigurationInput!){ updateConfiguration(input:$i) }"#; let r1 = schema.execute(Request::new(m1)).await; assert!(r1.errors.is_empty()); let r2 = schema .execute(Request::new(m2).variables(Variables::from_json(json!({"i":{"key":"k","value":"v"}})))) .await; assert!(r2.errors.is_empty()); } #[tokio::test] async fn nodes_three_ids_and_neighbors_limit() { let schema = build_schema().await; let q = r#"query($a:ID!,$b:ID!,$c:ID!){ nodes(ids:[$a,$b,$c]){ id } getNeighbors(id:$a, limit:2){ id } }"#; let vars = Variables::from_json(json!({ "a": uuid::Uuid::new_v4().to_string(), "b": uuid::Uuid::new_v4().to_string(), "c": uuid::Uuid::new_v4().to_string(), })); let res = schema.execute(Request::new(q).variables(vars)).await; assert!(res.errors.is_empty()); } #[tokio::test] async fn find_path_zero_depth() { let schema = build_schema().await; let q = r#"query($a:ID!,$b:ID!){ findPath(from:$a,to:$b,maxDepth:0){ id } }"#; let vars = Variables::from_json(json!({ "a": uuid::Uuid::new_v4().to_string(), "b": uuid::Uuid::new_v4().to_string(), })); let res = schema.execute(Request::new(q).variables(vars)).await; assert!(res.errors.is_empty()); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jakedismo/codegraph-rust'

If you have feedback or need assistance with the MCP directory API, please join our Discord server