haematite-cli 0.21.0

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
use std::os::unix::ffi::OsStringExt;

use super::{Plan, destination, json, plugin};
use crate::install::files::Payload;
use crate::install::tests::{Fixture, TestResult};

struct FailedEncoding;
impl serde::Serialize for FailedEncoding {
    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        drop(serializer);
        Err(serde::ser::Error::custom("fixture encoding refused"))
    }
}

#[test]
fn malformed_plugin_sources_are_refused_without_indexing_or_panicking() -> TestResult {
    for source in ["{", "[]", "{}", r#"{"mcpServers":{"haematite":[]}}"#] {
        let error = plugin(source).err().ok_or("invalid plugin accepted")?;
        assert_eq!(error.code, "bundle_plugin_invalid");
    }
    Ok(())
}

#[test]
fn duplicate_plan_paths_are_named_without_changing_existing_entries() -> TestResult {
    let fixture = Fixture::new()?;
    let mut plan = Plan::new(&fixture.binary, &fixture.config, &fixture.bundle)?;
    let before = json(&plan.manifest)?;
    let error = plan
        .add(
            "bin/haematite",
            Payload::Bytes(b"replacement".to_vec()),
            0o700,
        )
        .err()
        .ok_or("duplicate path accepted")?;
    assert_eq!(error.code, "bundle_plan_invalid");
    assert_eq!(json(&plan.manifest)?, before);
    assert_eq!(plan.payloads.len(), 9);
    assert!(!fixture.bundle.exists());
    Ok(())
}

#[test]
fn encoding_failure_keeps_its_name() -> TestResult {
    let error = json(&FailedEncoding)
        .err()
        .ok_or("encoding failure accepted")?;
    assert_eq!(error.code, "bundle_encoding_failed");
    Ok(())
}

#[test]
fn invalid_utf8_destination_paths_are_named_before_writing() -> TestResult {
    let fixture = Fixture::new()?;
    let name = std::ffi::OsString::from_vec(vec![0xff]);
    let target = fixture.directory.path().join(name);
    let error = destination(&target).err().ok_or("invalid path accepted")?;
    assert_eq!(error.code, "bundle_path_invalid");
    assert!(!target.exists());
    Ok(())
}