cueward-adapter-macos 0.5.0

macOS adapter for Cueward with Safari, Notes, Messages, Reminders, Calendar, Screenshot, Clipboard, and OCR integrations.
use super::tests::{direct, fixture, owned, perform, request};
use super::*;
use cueward_core::files::mutation::MutationStatus;
use std::fs;
use std::os::unix::fs::{MetadataExt, symlink};
fn package_fixture() -> tests::Owned {
    let root = fixture();
    let mut selected = request(root.path());
    fs::rename(root.path().join("source"), root.path().join("Owned.app")).unwrap();
    fs::create_dir(root.path().join("Owned.app/Nested.app")).unwrap();
    fs::write(
        root.path().join("Owned.app/Nested.app/Info.plist"),
        b"OWNED nested package",
    )
    .unwrap();
    selected.path = "Owned.app".into();
    selected.destination = "Owned-copy.app".into();
    selected.include_packages = true;
    refresh(root.path(), &mut selected);
    owned(root, selected)
}
fn refresh(root: &Path, selected: &mut CopyTreeRequest) {
    selected.expected_version = crate::files::observe(root, &selected.path, false, None)
        .unwrap()
        .version;
    selected.expected_parent_version = crate::files::observe(root, Path::new("."), false, None)
        .unwrap()
        .version;
}
#[test]
fn package_execute_uses_verified_tree_copy_with_independent_nodes_and_persistent_opt_in() {
    let mut value = package_fixture();
    let source = value.root.path().join("Owned.app");
    assert!(
        std::process::Command::new("/usr/bin/xattr")
            .args(["-w", "com.cueward.owned-package", "OWNED metadata"])
            .arg(&source)
            .status()
            .unwrap()
            .success()
    );
    refresh(value.root.path(), &mut value.receipt.request);
    save(&value.receipt).unwrap();
    perform(&mut value);
    assert_eq!(
        value.receipt.status,
        MutationStatus::Completed,
        "{:?}",
        value.receipt.error
    );
    assert!(value.receipt.completion_verified && value.receipt.staging_verified);
    assert!(
        value
            .receipt
            .nodes
            .iter()
            .any(|n| n.relative_path == Path::new("Nested.app/Info.plist"))
    );
    for node in &value.receipt.nodes {
        let before = source.join(&node.relative_path);
        let after = value
            .root
            .path()
            .join("Owned-copy.app")
            .join(&node.relative_path);
        assert_ne!(
            fs::metadata(&before).unwrap().ino(),
            fs::metadata(&after).unwrap().ino()
        );
        assert_eq!(
            fs::metadata(&before).unwrap().modified().unwrap(),
            fs::metadata(&after).unwrap().modified().unwrap()
        );
        assert_eq!(
            fs::metadata(&before).unwrap().permissions(),
            fs::metadata(&after).unwrap().permissions()
        );
        if node.kind == FileKind::File {
            assert_eq!(fs::read(&before).unwrap(), fs::read(after).unwrap());
            assert!(node.verification.is_some());
        }
    }
    let attribute = std::process::Command::new("/usr/bin/xattr")
        .args(["-p", "com.cueward.owned-package"])
        .arg(value.root.path().join("Owned-copy.app"))
        .output()
        .unwrap();
    assert!(attribute.status.success());
    assert_eq!(
        String::from_utf8(attribute.stdout).unwrap().trim_end(),
        "OWNED metadata"
    );
    let saved = read_receipt(&value.receipt.operation_id).unwrap();
    assert!(saved.request.include_packages);
    assert_eq!(
        serde_json::to_value(&saved).unwrap(),
        serde_json::to_value(&value.receipt).unwrap()
    );
}
#[test]
fn package_execute_copies_link_objects_and_refuses_missing_opt_in_limits_or_conflicts() {
    for mode in 0..5 {
        let mut value = package_fixture();
        match mode {
            0 => value.receipt.request.include_packages = false,
            1 => symlink("missing", value.root.path().join("Owned.app/link")).unwrap(),
            2 => value.receipt.request.max_entries = 1,
            3 => fs::write(value.root.path().join("Owned-copy.app"), b"OWNED conflict").unwrap(),
            4 => value.receipt.request.max_bytes = 1,
            _ => unreachable!(),
        }
        if mode == 1 || mode == 3 {
            refresh(value.root.path(), &mut value.receipt.request);
        }
        save(&value.receipt).unwrap();
        perform(&mut value);
        if mode == 1 {
            assert_eq!(
                value.receipt.status,
                MutationStatus::Completed,
                "{:?}",
                value.receipt.error
            );
            assert_eq!(
                fs::read_link(value.root.path().join("Owned-copy.app/link")).unwrap(),
                Path::new("missing")
            );
            continue;
        }
        assert_eq!(
            value.receipt.status,
            MutationStatus::NotStarted,
            "mode={mode} {:?}",
            value.receipt.error
        );
        assert!(value.receipt.staging_path.is_none() && !value.receipt.mutation_attempted);
        assert!(
            value
                .root
                .path()
                .join("Owned.app/sub/臺灣\n<external>")
                .is_file()
        );
    }
}
#[test]
fn package_copy_stops_on_nested_content_edit_after_staging_without_touching_source_or_publishing() {
    let mut value = package_fixture();
    let source = value.root.path().join("Owned.app/Nested.app/Info.plist");
    direct(&MacFiles, &mut value, |r| {
        if r.stage == TreeStage::Staged {
            fs::write(&source, b"OWNED external change").unwrap();
        }
        Ok(())
    });
    assert_eq!(
        value.receipt.status,
        MutationStatus::NotStarted,
        "{:?}",
        value.receipt.error
    );
    assert!(!value.root.path().join("Owned-copy.app").exists());
    assert_eq!(fs::read(&source).unwrap(), b"OWNED external change");
    assert_eq!(
        fs::read(
            Path::new(value.receipt.staging_path.as_ref().unwrap()).join("Nested.app/Info.plist")
        )
        .unwrap(),
        b"OWNED nested package"
    );
}