cueward-adapter-macos 0.5.0

macOS adapter for Cueward with Safari, Notes, Messages, Reminders, Calendar, Screenshot, Clipboard, and OCR integrations.
use super::tests::{fixture, request};
use super::*;
use cueward_core::files::{FileErrorCode, ResourceValue};
use std::fs;
use std::os::unix::fs::symlink;
#[test]
fn package_inclusion_plans_selected_and_nested_known_packages_only_when_opted_in() {
    let root = fixture();
    fs::create_dir_all(root.path().join("source/Owned.app/Nested.app")).unwrap();
    fs::write(
        root.path()
            .join("source/Owned.app/Nested.app/臺灣\n<external>"),
        b"OWNED package bytes",
    )
    .unwrap();
    for selected_root in [false, true] {
        let mut selected = request(root.path());
        if selected_root {
            selected.path = "source/Owned.app".into();
            selected.destination = "Owned-copy.app".into();
            selected.expected_version =
                crate::files::observe(root.path(), &selected.path, false, None)
                    .unwrap()
                    .version;
        }
        let blocked = plan_worker(&selected).unwrap();
        assert!(blocked.has_blockers && !blocked.enumeration_complete);
        assert!(
            !blocked.entries.iter().any(
                |e| e.source.path.contains("Nested.app") && e.source.name == "臺灣\n<external>"
            )
        );
        selected.include_packages = true;
        let plan = plan_worker(&selected).unwrap();
        assert!(!plan.has_blockers && plan.enumeration_complete && !plan.execution_supported);
        assert!(
            plan.entries.iter().any(
                |e| e.source.path.contains("Nested.app") && e.source.name == "臺灣\n<external>"
            )
        );
        let packages: Vec<_> = plan
            .entries
            .iter()
            .filter(|e| {
                e.resources
                    .as_ref()
                    .is_some_and(|r| r.is_package == (ResourceValue::Available { value: true }))
            })
            .collect();
        assert_eq!(packages.len(), 2);
        assert!(packages.iter().all(|e| e.error.is_none()));
        assert!(!root.path().join(&selected.destination).exists());
    }
}
#[test]
fn package_inclusion_does_not_follow_links_and_still_enforces_tree_budgets() {
    let root = fixture();
    let outside = tempfile::tempdir().unwrap();
    fs::write(outside.path().join("PRIVATE"), b"not selected").unwrap();
    fs::create_dir(root.path().join("source/Owned.app")).unwrap();
    symlink(outside.path(), root.path().join("source/Owned.app/link")).unwrap();
    let mut selected = request(root.path());
    selected.include_packages = true;
    let plan = plan_worker(&selected).unwrap();
    assert!(!plan.has_blockers);
    assert!(!serde_json::to_string(&plan).unwrap().contains("PRIVATE"));
    let link = plan
        .entries
        .iter()
        .find(|e| e.relative_path == Path::new("Owned.app/link"))
        .unwrap();
    assert!(link.error.is_none());
    assert_eq!(link.source.link_target.as_deref(), outside.path().to_str());
    for mode in 0..3 {
        let mut limited = selected.clone();
        match mode {
            0 => limited.max_entries = 1,
            1 => limited.max_depth = 1,
            2 => limited.max_bytes = 1,
            _ => unreachable!(),
        }
        assert_eq!(
            plan_worker(&limited).unwrap_err().code,
            FileErrorCode::ScanLimit
        );
    }
    assert!(!root.path().join("copy").exists());
}
#[test]
fn package_request_schema_defaults_old_requests_to_safe_skip_and_rejects_non_boolean_inclusion() {
    let root = fixture();
    let selected = request(root.path());
    let mut json = serde_json::to_value(&selected).unwrap();
    assert!(json.get("include_packages").is_none());
    let old: CopyTreeRequest = serde_json::from_value(json.clone()).unwrap();
    assert!(!old.include_packages);
    json["include_packages"] = serde_json::json!(true);
    let included: CopyTreeRequest = serde_json::from_value(json.clone()).unwrap();
    assert!(included.include_packages);
    assert_eq!(
        serde_json::to_value(included).unwrap()["include_packages"],
        true
    );
    for value in [
        serde_json::json!("true"),
        serde_json::Value::Null,
        serde_json::json!(1),
    ] {
        json["include_packages"] = value;
        assert!(serde_json::from_value::<CopyTreeRequest>(json.clone()).is_err());
    }
}