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(), 10);
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(())
}