pmat 3.26.0

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod coverage_tests_mcp_http {
    use super::*;
    use serde_json::json;

    // MCP Adapter tests
    #[test]
    fn test_mcp_adapter_decode_analyze_complexity() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "analyze_complexity",
            "params": {
                "file_path": "src/main.rs",
                "max_cyclomatic": 20,
                "max_cognitive": 15
            },
            "id": 1
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());

        let unified = result.unwrap();
        assert!(matches!(unified.operation, Operation::AnalyzeComplexity(_)));
        assert_eq!(unified.context.protocol, "json-rpc");
    }

    #[test]
    fn test_mcp_adapter_decode_analyze_satd() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "analyze_satd",
            "params": {
                "file_path": "src/lib.rs",
                "strict": true
            },
            "id": 2
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_analyze_dead_code() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "analyze_dead_code",
            "params": {
                "include_tests": false
            },
            "id": 3
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_generate_context() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "generate_context",
            "params": {
                "format": "markdown"
            },
            "id": 4
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_quality_gate() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "quality_gate",
            "params": {
                "fail_on_violation": true
            },
            "id": 5
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_refactor_methods() {
        let adapter = McpAdapter;

        // refactor_start
        let request = json!({
            "jsonrpc": "2.0",
            "method": "refactor_start",
            "params": {
                "file_path": "src/complex.rs",
                "target_complexity": 15
            },
            "id": 6
        });
        let raw = serde_json::to_vec(&request).unwrap();
        assert!(adapter.decode(&raw).is_ok());

        // refactor_next
        let request = json!({
            "jsonrpc": "2.0",
            "method": "refactor_next",
            "params": {
                "session_id": "session-123"
            },
            "id": 7
        });
        let raw = serde_json::to_vec(&request).unwrap();
        assert!(adapter.decode(&raw).is_ok());

        // refactor_stop
        let request = json!({
            "jsonrpc": "2.0",
            "method": "refactor_stop",
            "params": {
                "session_id": "session-123"
            },
            "id": 8
        });
        let raw = serde_json::to_vec(&request).unwrap();
        assert!(adapter.decode(&raw).is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_scaffold_methods() {
        let adapter = McpAdapter;

        // scaffold_project
        let request = json!({
            "jsonrpc": "2.0",
            "method": "scaffold_project",
            "params": {
                "name": "my-project",
                "template": "rust-cli"
            },
            "id": 9
        });
        let raw = serde_json::to_vec(&request).unwrap();
        assert!(adapter.decode(&raw).is_ok());

        // scaffold_agent
        let request = json!({
            "jsonrpc": "2.0",
            "method": "scaffold_agent",
            "params": {
                "name": "my-agent",
                "capabilities": ["analyze"]
            },
            "id": 10
        });
        let raw = serde_json::to_vec(&request).unwrap();
        assert!(adapter.decode(&raw).is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_pdmt_todos() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "pdmt_todos",
            "params": {
                "requirement": "implement feature",
                "granularity": "fine"
            },
            "id": 11
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_quality_proxy() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "quality_proxy",
            "params": {
                "file_path": "src/main.rs",
                "content": "fn main() {}",
                "mode": "strict"
            },
            "id": 12
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_ok());
    }

    #[test]
    fn test_mcp_adapter_decode_unknown_method() {
        let adapter = McpAdapter;
        let request = json!({
            "jsonrpc": "2.0",
            "method": "unknown_method",
            "params": {},
            "id": 1
        });

        let raw = serde_json::to_vec(&request).unwrap();
        let result = adapter.decode(&raw);
        assert!(result.is_err());

        if let Err(ProtocolError::UnknownMethod(method)) = result {
            assert_eq!(method, "unknown_method");
        }
    }

    #[test]
    fn test_mcp_adapter_encode_success_response() {
        let adapter = McpAdapter;
        let response = UnifiedResponse {
            result: Some(json!({"status": "ok"})),
            error: None,
            metadata: super::super::ResponseMetadata {
                request_id: "req-1".to_string(),
                duration_ms: 42,
                version: "1.0.0".to_string(),
            },
        };

        let encoded = adapter.encode(response).unwrap();
        let decoded: JsonRpcResponse = serde_json::from_slice(&encoded).unwrap();

        assert_eq!(decoded.jsonrpc, "2.0");
        assert!(decoded.result.is_some());
        assert!(decoded.error.is_none());
    }

    #[test]
    fn test_mcp_adapter_encode_error_response() {
        let adapter = McpAdapter;
        let response = UnifiedResponse {
            result: None,
            error: Some(super::super::ErrorInfo {
                code: -32600,
                message: "Invalid request".to_string(),
                details: None,
            }),
            metadata: super::super::ResponseMetadata {
                request_id: "req-2".to_string(),
                duration_ms: 10,
                version: "1.0.0".to_string(),
            },
        };

        let encoded = adapter.encode(response).unwrap();
        let decoded: JsonRpcResponse = serde_json::from_slice(&encoded).unwrap();

        assert!(decoded.error.is_some());
        assert_eq!(decoded.error.unwrap().code, -32600);
    }

    #[tokio::test]
    async fn test_mcp_adapter_handle() {
        let adapter = McpAdapter;
        let request = JsonRpcRequest {
            jsonrpc: "2.0".to_string(),
            method: "test.method".to_string(),
            params: json!({}),
            id: json!(1),
        };

        let response = adapter.handle(request).await;
        assert_eq!(response.jsonrpc, "2.0");
        assert!(response.result.is_some());
    }

    // HTTP Adapter tests
    #[test]
    fn test_http_adapter_decode_complexity() {
        let adapter = HttpAdapter;
        let request =
            "GET /analyze/complexity HTTP/1.1\r\nContent-Type: application/json\r\n\r\n{}";

        let result = adapter.decode(request.as_bytes());
        assert!(result.is_ok());
    }

    #[test]
    fn test_http_adapter_decode_satd() {
        let adapter = HttpAdapter;
        let request = "POST /analyze/satd HTTP/1.1\r\nContent-Type: application/json\r\n\r\n{}";

        let result = adapter.decode(request.as_bytes());
        assert!(result.is_ok());
    }

    #[test]
    fn test_http_adapter_decode_dead_code() {
        let adapter = HttpAdapter;
        let request = "GET /analyze/dead-code HTTP/1.1\r\nContent-Type: application/json\r\n\r\n{}";

        let result = adapter.decode(request.as_bytes());
        assert!(result.is_ok());
    }

    #[test]
    fn test_http_adapter_decode_quality_gate() {
        let adapter = HttpAdapter;
        let request = "POST /quality/gate HTTP/1.1\r\nContent-Type: application/json\r\n\r\n{}";

        let result = adapter.decode(request.as_bytes());
        assert!(result.is_ok());
    }

    #[test]
    fn test_http_adapter_decode_unknown_route() {
        let adapter = HttpAdapter;
        let request = "GET /unknown/route HTTP/1.1\r\n\r\n";

        let result = adapter.decode(request.as_bytes());
        assert!(result.is_err());
    }

    #[test]
    fn test_http_adapter_encode_success() {
        let adapter = HttpAdapter;
        let response = UnifiedResponse {
            result: Some(json!({"status": "ok"})),
            error: None,
            metadata: super::super::ResponseMetadata {
                request_id: "req-1".to_string(),
                duration_ms: 42,
                version: "1.0.0".to_string(),
            },
        };

        let encoded = adapter.encode(response).unwrap();
        let response_str = String::from_utf8_lossy(&encoded);

        assert!(response_str.contains("HTTP/1.1 200"));
        assert!(response_str.contains("Content-Type: application/json"));
    }

    #[test]
    fn test_http_adapter_encode_error() {
        let adapter = HttpAdapter;
        let response = UnifiedResponse {
            result: None,
            error: Some(super::super::ErrorInfo {
                code: -32600,
                message: "Error".to_string(),
                details: None,
            }),
            metadata: super::super::ResponseMetadata {
                request_id: "req-2".to_string(),
                duration_ms: 10,
                version: "1.0.0".to_string(),
            },
        };

        let encoded = adapter.encode(response).unwrap();
        let response_str = String::from_utf8_lossy(&encoded);

        assert!(response_str.contains("HTTP/1.1 400"));
    }

    #[tokio::test]
    async fn test_http_adapter_handle() {
        let adapter = HttpAdapter;
        let request = HttpRequest {
            method: "GET".to_string(),
            path: "/test".to_string(),
            headers: HashMap::new(),
            body: json!({}),
        };

        let response = adapter.handle(request).await;
        assert_eq!(response.status, 200);
    }
}