Files
dirigate/tests/server_integration_test.rs
T
g4borg c62d8daea8 chore: rename packages/ to crates/
Move all 29 workspace members from packages/<name>/ to crates/<name>/.
Updates: workspace Cargo.toml (members + path deps), justfile, root
CLAUDE.md, scripts/build/CARGO_INSTALL.md, docs/architecture/crates.md
(renamed from packages.md), structural references in docs/architecture
and docs/configuration, per-crate CLAUDE.md self-references. Historical
plans, reports, and building/ docs are left untouched.

No behavior change; just check-all stays green and fermata tests pass.
2026-04-30 21:58:57 +02:00

160 lines
5.3 KiB
Rust

//! Integration tests for the ACP JSON-RPC server.
//!
//! These tests verify that the server correctly handles JSON-RPC requests
//! over HTTP and returns proper responses.
use dirigate::acp::model::{JsonRpcError, JsonRpcRequest, JsonRpcResponse};
use dirigate::acp::server::AcpServer;
use dirigate::fixture::types::*;
use dirigate::{MockerConfig, MockerState};
use std::collections::HashMap;
use std::sync::Arc;
/// Helper to create a minimal test fixture with a template session.
fn create_test_fixture_with_template() -> Fixture {
Fixture {
version: "0.1".to_string(),
sessions: vec![Session {
id: "test-template".to_string(),
title: "Test Template Session".to_string(),
created_at: "2025-01-01T00:00:00Z".to_string(),
participants: vec![
Participant {
id: "user-1".to_string(),
kind: ParticipantKind::User,
display_name: Some("Test User".to_string()),
},
Participant {
id: "assistant-1".to_string(),
kind: ParticipantKind::Assistant,
display_name: Some("Test Assistant".to_string()),
},
],
messages: vec![],
behavior: None,
}],
responders: Responders {
keyword_map: HashMap::new(),
default_strategy: ResponderStrategy::Echo,
random: None,
},
streaming: Streaming {
enabled: true,
tokens_per_chunk: 5,
chunk_interval_ms: 100,
jitter_ms: Some(10),
},
}
}
#[tokio::test]
async fn test_server_initialize_request() {
// Create state
let config = MockerConfig::default();
let fixtures = create_test_fixture_with_template();
let state = Arc::new(MockerState::new(config, fixtures));
// Create server on a random port
let server = AcpServer::new(state.clone(), 0);
// Start server in background
tokio::spawn(async move {
let _ = server.serve().await;
});
// Give server time to start
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
// Note: We can't actually test the HTTP endpoint without binding to a known port
// This test verifies the server compiles and runs without panicking
}
#[tokio::test]
async fn test_jsonrpc_initialize_response_format() {
// Create a mock initialize request
let request = JsonRpcRequest::new(
"initialize",
Some(serde_json::json!({
"protocol_version": "0.1",
"client_capabilities": {}
})),
1,
);
// Verify request serialization
let json = serde_json::to_string(&request).unwrap();
assert!(json.contains("\"jsonrpc\":\"2.0\""));
assert!(json.contains("\"method\":\"initialize\""));
assert!(json.contains("\"id\":1"));
// Parse it back
let parsed: JsonRpcRequest = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.method, "initialize");
assert_eq!(parsed.jsonrpc, "2.0");
}
#[tokio::test]
async fn test_jsonrpc_session_new_response_format() {
// Create a mock session/new request
let request = JsonRpcRequest::new(
"session/new",
Some(serde_json::json!({
"template_id": "test-template"
})),
2,
);
// Verify request serialization
let json = serde_json::to_string(&request).unwrap();
assert!(json.contains("\"jsonrpc\":\"2.0\""));
assert!(json.contains("\"method\":\"session/new\""));
assert!(json.contains("\"template_id\":\"test-template\""));
assert!(json.contains("\"id\":2"));
// Parse it back
let parsed: JsonRpcRequest = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.method, "session/new");
assert_eq!(parsed.jsonrpc, "2.0");
}
#[tokio::test]
async fn test_jsonrpc_error_response_format() {
// Create an error response
let error = JsonRpcError::method_not_found("unknown_method");
let response = JsonRpcResponse::error(error, Some(serde_json::json!(1)));
// Verify response serialization
let json = serde_json::to_string(&response).unwrap();
assert!(json.contains("\"jsonrpc\":\"2.0\""));
assert!(json.contains("\"error\""));
assert!(json.contains("-32601")); // Method not found code
assert!(!json.contains("\"result\"")); // Should not have result field
// Parse it back
let parsed: JsonRpcResponse = serde_json::from_str(&json).unwrap();
assert!(parsed.error.is_some());
assert!(parsed.result.is_none());
assert_eq!(parsed.error.unwrap().code, -32601);
}
#[tokio::test]
async fn test_jsonrpc_success_response_format() {
// Create a success response
let result = serde_json::json!({
"session_id": "test-session-123"
});
let response = JsonRpcResponse::success(result, Some(serde_json::json!(1)));
// Verify response serialization
let json = serde_json::to_string(&response).unwrap();
assert!(json.contains("\"jsonrpc\":\"2.0\""));
assert!(json.contains("\"result\""));
assert!(json.contains("\"session_id\":\"test-session-123\""));
assert!(!json.contains("\"error\"")); // Should not have error field
// Parse it back
let parsed: JsonRpcResponse = serde_json::from_str(&json).unwrap();
assert!(parsed.result.is_some());
assert!(parsed.error.is_none());
}