claude-sdk-rs 1.0.0

Rust SDK for Claude AI with CLI integration - type-safe async API for Claude Code and direct SDK usage
Documentation
#[cfg(test)]
mod tests {
    use serde_json::Value;

    use crate::clients::helpscout::*;
    use crate::transport::TransportType;
    use crate::core::nodes::external_mcp_client::ExternalMCPClientNode;
    use crate::core::task::TaskContext;

    #[test]
    fn test_helpscout_client_default_config() {
        let client = HelpscoutClientNode::with_defaults();
        let config = client.get_helpscout_config();

        assert_eq!(config.server_url, "http://localhost:8001");
        assert_eq!(client.get_config().service_name, "helpscout");
        assert!(!client.is_connected());
    }

    #[test]
    fn test_helpscout_client_http_config() {
        let server_url = "http://helpscout.example.com:9001".to_string();
        let api_key = "test-api-key-123".to_string();

        let client =
            HelpscoutClientNode::with_http_transport(server_url.clone(), Some(api_key.clone()));

        let config = client.get_helpscout_config();
        assert_eq!(config.server_url, server_url);
        assert_eq!(config.api_key, Some(api_key));

        match &config.transport {
            TransportType::Http { base_url, .. } => {
                assert_eq!(base_url, &server_url);
            }
            _ => panic!("Expected HTTP transport"),
        }
    }

    #[test]
    fn test_helpscout_client_websocket_config() {
        let websocket_url = "ws://helpscout.example.com:9001/ws".to_string();
        let api_key = "test-ws-key-456".to_string();

        let client = HelpscoutClientNode::with_websocket_transport(
            websocket_url.clone(),
            Some(api_key.clone()),
        );

        let config = client.get_helpscout_config();
        assert_eq!(config.server_url, websocket_url);
        assert_eq!(config.api_key, Some(api_key));

        match &config.transport {
            TransportType::WebSocket { url, .. } => {
                assert_eq!(url, &websocket_url);
            }
            _ => panic!("Expected WebSocket transport"),
        }
    }

    #[test]
    fn test_helpscout_client_stdio_config() {
        let command = "python3".to_string();
        let args = vec![
            "-m".to_string(),
            "helpscout_mcp_server".to_string(),
            "--port".to_string(),
            "8001".to_string(),
        ];
        let api_key = "test-stdio-key-789".to_string();

        let client = HelpscoutClientNode::with_stdio_transport(
            command.clone(),
            args.clone(),
            Some(api_key.clone()),
        );

        let config = client.get_helpscout_config();
        assert_eq!(config.server_url, "stdio://python3");
        assert_eq!(config.api_key, Some(api_key));

        match &config.transport {
            TransportType::Stdio {
                command: cmd,
                args: cmd_args,
                ..
            } => {
                assert_eq!(cmd, &command);
                assert_eq!(cmd_args, &args);
            }
            _ => panic!("Expected Stdio transport"),
        }
    }

    #[test]
    fn test_helpscout_client_node_trait() {
        use crate::core::nodes::Node;
        use crate::core::task::TaskContext;

        let client = HelpscoutClientNode::with_defaults();
        let mut task_context = TaskContext::new(
            "test-task".to_string(),
            Value::String("test-workflow".to_string()),
        );

        let result = client.process(task_context);
        assert!(result.is_ok());

        let updated_context = result.unwrap();
        assert!(
            updated_context
                .get_data::<bool>("helpscout_client_processed")
                .unwrap_or(Some(false))
                .unwrap_or(false)
        );
        assert_eq!(
            updated_context
                .get_data::<String>("service_name")
                .unwrap_or(Some("".to_string())),
            Some("helpscout".to_string())
        );
    }

    #[tokio::test]
    async fn test_search_articles_arguments() {
        let mut client = HelpscoutClientNode::with_defaults();

        // This test validates argument preparation for search_articles
        // In a real test environment, you would mock the MCP client connection
        let keywords = "appointment scheduling";
        let page = Some(2);
        let per_page = Some(20);

        // Since we can't connect to a real server in unit tests,
        // we just validate the client creation and configuration
        assert_eq!(client.get_config().service_name, "helpscout");
        assert!(!client.is_connected());

        // The actual tool execution would be tested in integration tests
        // with a real or mocked MCP server
    }

    #[tokio::test]
    async fn test_get_article_arguments() {
        let mut client = HelpscoutClientNode::with_defaults();

        // This test validates argument preparation for get_article
        let article_id = "article-123";

        // Validate client setup
        assert_eq!(client.get_config().service_name, "helpscout");
        assert!(!client.is_connected());

        // The actual tool execution would be tested in integration tests
    }

    #[tokio::test]
    async fn test_create_article_arguments() {
        let mut client = HelpscoutClientNode::with_defaults();

        // This test validates argument preparation for create_article
        let title = "How to schedule appointments";
        let content = "This article explains the appointment scheduling process...";
        let collection_id = "collection-456";
        let tags = Some(vec!["scheduling".to_string(), "appointments".to_string()]);

        // Validate client setup
        assert_eq!(client.get_config().service_name, "helpscout");
        assert!(!client.is_connected());

        // The actual tool execution would be tested in integration tests
    }

    #[tokio::test]
    async fn test_list_tools_when_not_connected() {
        let mut client = HelpscoutClientNode::with_defaults();

        // Should return an error when not connected
        let result = client.list_tools().await;
        assert!(result.is_err());

        if let Err(e) = result {
            match e {
                crate::core::error::WorkflowError::MCPConnectionError { message } => {
                    assert!(message.contains("helpscout client not connected"));
                }
                _ => panic!("Expected MCPConnectionError"),
            }
        }
    }

    #[tokio::test]
    async fn test_execute_tool_when_not_connected() {
        let mut client = HelpscoutClientNode::with_defaults();

        // Should return an error when not connected
        let result = client.execute_tool("search_articles", None).await;
        assert!(result.is_err());

        if let Err(e) = result {
            match e {
                crate::core::error::WorkflowError::MCPConnectionError { message } => {
                    assert!(message.contains("helpscout client not connected"));
                }
                _ => panic!("Expected MCPConnectionError"),
            }
        }
    }

    #[test]
    fn test_helpscout_config_from_env() {
        // This test would require setting environment variables
        // For now, just test the default behavior
        let config = HelpscoutClientConfig::default();

        // Default values when env vars are not set
        assert_eq!(config.server_url, "http://localhost:8001");

        match config.transport {
            TransportType::Http { base_url, .. } => {
                assert_eq!(base_url, "http://localhost:8001");
            }
            _ => panic!("Expected HTTP transport by default"),
        }
    }

    #[test]
    fn test_helpscout_auth_config_generation() {
        let api_key = "test-key-123".to_string();
        let client = HelpscoutClientNode::with_http_transport(
            "http://localhost:8001".to_string(),
            Some(api_key.clone()),
        );

        let external_config = client.get_config();

        // Check that auth config was properly generated
        assert!(external_config.auth.is_some());

        if let Some(ref auth) = external_config.auth {
            assert_eq!(auth.token, Some(api_key.clone()));
            assert!(auth.headers.is_some());

            if let Some(ref headers) = auth.headers {
                assert_eq!(headers.get("X-API-Key"), Some(&api_key));
            }
        }
    }

    #[test]
    fn test_helpscout_client_without_auth() {
        let client = HelpscoutClientNode::with_http_transport(
            "http://localhost:8001".to_string(),
            None, // No API key
        );

        let external_config = client.get_config();

        // Auth should be None when no API key is provided
        assert!(external_config.auth.is_none());
    }
}