remote-mcp-kernel 0.1.0-alpha.4

A microkernel-based MCP (Model Context Protocol) server with OAuth authentication and multiple transport protocols
Documentation
//! Test cases for microkernel server
//!
//! This module contains comprehensive test cases for the microkernel server
//! to ensure independence and correct composition of handlers.

use crate::handlers::{McpServer, SseHandler, SseHandlerConfig, StreamableHttpHandler};
use oauth_provider_rs::{provider_trait::OAuthProviderConfig, OAuthProvider, http_integration::config::OAuthProviderConfig as HttpOAuthProviderConfig};

use super::core::MicrokernelServer;
use super::factory::*;
use super::types::*;

fn create_test_github_oauth_provider() -> oauth_provider_rs::GitHubOAuthProvider {
    let github_config = OAuthProviderConfig::with_oauth_config(
        "test_client_id".to_string(),
        "test_client_secret".to_string(),
        "http://localhost:8080/oauth/callback".to_string(),
        "read:user".to_string(),
        "github".to_string(),
    );
    oauth_provider_rs::GitHubOAuthProvider::new_github(github_config)
}

fn create_test_cognito_oauth_provider() -> oauth_provider_rs::CognitoOAuthProvider {
    let cognito_config = OAuthProviderConfig::with_oauth_config(
        "test_client_id".to_string(),
        "test_client_secret".to_string(),
        "http://localhost:8080/oauth/callback".to_string(),
        "openid email profile".to_string(),
        "cognito".to_string(),
    );
    oauth_provider_rs::CognitoOAuthProvider::new_cognito(
        cognito_config,
        "mydomain.auth.us-east-1.amazoncognito.com".to_string(),
        "us-east-1".to_string(),
        "us-east-1_XXXXXXXXX".to_string(),
    )
}

#[test]
fn test_microkernel_builder_empty() {
    let microkernel: GitHubMicrokernelServer = MicrokernelServer::new();
    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[test]
fn test_microkernel_builder_oauth_only_github() {
    let oauth_provider = create_test_github_oauth_provider();
    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let microkernel: GitHubMicrokernelServer =
        MicrokernelServer::new().with_oauth_provider(wrapped_oauth_provider);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[test]
fn test_microkernel_builder_oauth_only_cognito() {
    let oauth_provider = create_test_cognito_oauth_provider();
    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let microkernel: CognitoMicrokernelServer =
        MicrokernelServer::new().with_oauth_provider(wrapped_oauth_provider);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_builder_full() {
    let oauth_provider = create_test_github_oauth_provider();
    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let mcp_server = McpServer::new();
    let streamable_handler = StreamableHttpHandler::new(mcp_server.clone());
    let sse_handler = SseHandler::new(mcp_server.clone());

    let microkernel: GitHubMicrokernelServer = MicrokernelServer::new()
        .with_oauth_provider(wrapped_oauth_provider)
        .with_streamable_handler(streamable_handler)
        .with_sse_handler(sse_handler, SseHandlerConfig::default());

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_factory_full() {
    let oauth_provider = create_test_github_oauth_provider();
    let microkernel = create_full_github_microkernel(oauth_provider);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[test]
fn test_microkernel_factory_oauth_only() {
    let oauth_provider = create_test_github_oauth_provider();
    let microkernel = create_github_oauth_only_microkernel(oauth_provider);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_factory_unauthenticated() {
    let oauth_provider = create_test_github_oauth_provider();
    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let microkernel = create_unauthenticated_microkernel(wrapped_oauth_provider.clone());

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_independence() {
    let oauth_provider = create_test_github_oauth_provider();

    // Test that each handler can work independently
    let oauth_only = create_github_oauth_only_microkernel(oauth_provider.clone());
    assert!(oauth_only.build_router().is_ok());

    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let mcp_server = McpServer::new();
    let streamable_handler = StreamableHttpHandler::new(mcp_server.clone());
    let streamable_only: GitHubMicrokernelServer =
        MicrokernelServer::new().with_streamable_handler(streamable_handler);
    assert!(streamable_only.build_router().is_ok());

    let sse_handler = SseHandler::new(mcp_server.clone());
    let sse_only: GitHubMicrokernelServer =
        MicrokernelServer::new().with_sse_handler(sse_handler, SseHandlerConfig::default());
    assert!(sse_only.build_router().is_ok());
}

#[tokio::test]
async fn test_microkernel_with_cognito() {
    let oauth_provider = create_test_cognito_oauth_provider();
    let microkernel = create_full_cognito_microkernel(oauth_provider);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_independence_cognito() {
    let oauth_provider = create_test_cognito_oauth_provider();

    // Test that Cognito OAuth works independently
    let oauth_only = create_cognito_oauth_only_microkernel(oauth_provider);
    assert!(oauth_only.build_router().is_ok());
}

#[tokio::test]
async fn test_microkernel_with_custom_router() {
    use axum::{response::Html, routing::get};

    async fn hello_handler() -> Html<&'static str> {
        Html("<h1>Hello from custom router!</h1>")
    }

    let custom_router = axum::Router::new().route("/hello", get(hello_handler));

    let microkernel: GitHubMicrokernelServer =
        MicrokernelServer::new().with_custom_router(custom_router);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_with_custom_router_config() {
    use axum::{response::Html, routing::get};

    async fn api_status_handler() -> Html<&'static str> {
        Html("<h1>API Status: OK</h1>")
    }

    let custom_router = axum::Router::new().route("/status", get(api_status_handler));

    let config = super::CustomRouterConfig::with_name_and_prefix("API Router", "/api");

    let microkernel: GitHubMicrokernelServer =
        MicrokernelServer::new().with_custom_router_config(custom_router, config);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_with_multiple_custom_routers() {
    use axum::{response::Html, routing::get};

    async fn health_handler() -> Html<&'static str> {
        Html("<h1>Health: OK</h1>")
    }

    async fn metrics_handler() -> Html<&'static str> {
        Html("<h1>Metrics: OK</h1>")
    }

    let health_router = axum::Router::new().route("/health", get(health_handler));

    let metrics_router = axum::Router::new().route("/metrics", get(metrics_handler));

    let routers = vec![
        (health_router, super::CustomRouterConfig::default()),
        (
            metrics_router,
            super::CustomRouterConfig::with_name_and_prefix("Metrics", "/monitoring"),
        ),
    ];

    let microkernel: GitHubMicrokernelServer =
        MicrokernelServer::new().with_custom_routers(routers);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[tokio::test]
async fn test_microkernel_full_with_custom_routers() {
    use axum::{response::Html, routing::get};

    async fn custom_handler() -> Html<&'static str> {
        Html("<h1>Custom Endpoint</h1>")
    }

    let oauth_provider = create_test_github_oauth_provider();
    let wrapped_oauth_provider = OAuthProvider::new(oauth_provider, HttpOAuthProviderConfig::default());
    let mcp_server = McpServer::new();
    let streamable_handler = StreamableHttpHandler::new(mcp_server.clone());
    let sse_handler = SseHandler::new(mcp_server.clone());

    let custom_router = axum::Router::new().route("/custom", get(custom_handler));

    let microkernel: GitHubMicrokernelServer = MicrokernelServer::new()
        .with_oauth_provider(wrapped_oauth_provider)
        .with_streamable_handler(streamable_handler)
        .with_sse_handler(sse_handler, SseHandlerConfig::default())
        .with_custom_router(custom_router);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}

#[test]
fn test_custom_router_config_builders() {
    let config_with_name = super::CustomRouterConfig::with_name("Test Router");
    assert_eq!(config_with_name.name, Some("Test Router".to_string()));
    assert_eq!(config_with_name.path_prefix, None);

    let config_with_prefix = super::CustomRouterConfig::with_prefix("/api");
    assert_eq!(config_with_prefix.name, None);
    assert_eq!(config_with_prefix.path_prefix, Some("/api".to_string()));

    let config_with_both = super::CustomRouterConfig::with_name_and_prefix("API", "/api");
    assert_eq!(config_with_both.name, Some("API".to_string()));
    assert_eq!(config_with_both.path_prefix, Some("/api".to_string()));
}

#[tokio::test]
async fn test_microkernel_custom_router_independence() {
    use axum::{response::Html, routing::get};

    async fn simple_handler() -> Html<&'static str> {
        Html("<h1>Simple</h1>")
    }

    let custom_router = axum::Router::new().route("/simple", get(simple_handler));

    // Test that custom router works independently without any other handlers
    let microkernel: GitHubMicrokernelServer =
        MicrokernelServer::new().with_custom_router(custom_router);

    let router_result = microkernel.build_router();
    assert!(router_result.is_ok());
}