haematite-cli 0.21.8

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
use ureq::http::{HeaderMap, HeaderValue, header};

use super::protocol;
use crate::mcp::rpc;

type TestResult = Result<(), Box<dyn std::error::Error>>;

fn headers() -> HeaderMap {
    let mut headers = HeaderMap::new();
    headers.insert(
        header::CONTENT_TYPE,
        HeaderValue::from_static("application/json"),
    );
    headers.insert(
        header::ACCEPT,
        HeaderValue::from_static("application/json, text/event-stream"),
    );
    headers
}

#[test]
fn one_supported_protocol_header_is_accepted() -> TestResult {
    let mut headers = headers();
    headers.append(
        "mcp-protocol-version",
        HeaderValue::from_str(rpc::SUPPORTED_PROTOCOL_VERSION)?,
    );
    protocol(&headers)?;
    Ok(())
}

#[test]
fn duplicate_protocol_headers_are_refused_before_dispatch() -> TestResult {
    for second in [rpc::SUPPORTED_PROTOCOL_VERSION, "unsupported"] {
        let mut headers = headers();
        headers.append(
            "mcp-protocol-version",
            HeaderValue::from_str(rpc::SUPPORTED_PROTOCOL_VERSION)?,
        );
        headers.append("mcp-protocol-version", HeaderValue::from_str(second)?);
        let error = protocol(&headers)
            .err()
            .ok_or("duplicate versions were accepted")?;
        assert_eq!(error.status, 400);
        assert_eq!(error.code, "mcp_http_protocol_version_unsupported");
    }
    Ok(())
}