Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions tests/test_provision.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ def isolate_claude_skill(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> Pat
return skill_dir


@pytest.fixture
def posix_form(monkeypatch: pytest.MonkeyPatch) -> None:
"""Pin the POSIX .sh hook form: these tests assert omi-guard.sh wiring,
which native Windows deliberately no longer uses (#259) — without this
pin they fail on the windows-latest CI runners."""
monkeypatch.setattr(provision, "_windows", lambda: False)


def _config(tmp_path: Path, **kw: object) -> SetupConfig:
return SetupConfig(vault=tmp_path / "vault", **kw) # type: ignore[arg-type]

Expand Down Expand Up @@ -654,7 +662,11 @@ def test_secret_output_guard_dry_run_writes_nothing(
assert not (tmp_path / ".claude" / "hooks" / "secret-output-guard.sh").exists()


def test_setup_writes_omi_guard_scripts(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
def test_setup_writes_omi_guard_scripts(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
posix_form: None,
) -> None:
monkeypatch.setattr(provision.Path, "home", classmethod(lambda cls: tmp_path))
Provisioner(_config(tmp_path), log=_quiet)._write_omi_guard_scripts()
hooks = tmp_path / ".claude" / "hooks"
Expand All @@ -668,7 +680,9 @@ def test_setup_writes_omi_guard_scripts(monkeypatch: pytest.MonkeyPatch, tmp_pat
assert "__OMIND_BIN__" not in body


def test_omi_guard_installed_idempotently(tmp_path: Path, isolate_settings: Path) -> None:
def test_omi_guard_installed_idempotently(
tmp_path: Path, isolate_settings: Path, posix_form: None
) -> None:
config = _config(tmp_path)
Provisioner(config, log=_quiet).ensure_omi_guard_installed()
before = isolate_settings.read_text(encoding="utf-8")
Expand All @@ -685,7 +699,9 @@ def test_omi_guard_installed_idempotently(tmp_path: Path, isolate_settings: Path
assert "mcp__omi__help" in data["permissions"]["allow"]


def test_omi_guard_preserves_user_hooks(tmp_path: Path, isolate_settings: Path) -> None:
def test_omi_guard_preserves_user_hooks(
tmp_path: Path, isolate_settings: Path, posix_form: None
) -> None:
user_pre = {"matcher": "Bash", "hooks": [{"type": "command", "command": "/x/mine.sh"}]}
isolate_settings.write_text(json.dumps({"hooks": {"PreToolUse": [user_pre]}}))
Provisioner(_config(tmp_path), log=_quiet).ensure_omi_guard_installed()
Expand Down Expand Up @@ -877,7 +893,7 @@ def test_provision_manifest_roundtrip_and_drift(

def test_autoheal_installs_guard_when_drifted(
tmp_path: Path, fake_tools: None, monkeypatch: pytest.MonkeyPatch
) -> None:
, posix_form: None) -> None:
monkeypatch.setattr(provision.Path, "home", classmethod(lambda cls: tmp_path))
monkeypatch.delenv("OMIND_NO_AUTOHEAL", raising=False)
config = _config(tmp_path)
Expand All @@ -904,7 +920,7 @@ def test_autoheal_respects_opt_out(

def test_provision_migrates_legacy_guard(
tmp_path: Path, fake_tools: None, isolate_settings: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
, posix_form: None) -> None:
monkeypatch.setattr(provision.Path, "home", classmethod(lambda cls: tmp_path))
hooks_dir = tmp_path / ".claude" / "hooks"
hooks_dir.mkdir(parents=True)
Expand Down Expand Up @@ -1183,7 +1199,7 @@ def _guard_entry() -> dict[str, object]:

def test_guard_hook_install_is_idempotent_when_our_entry_is_first(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
, posix_form: None) -> None:
"""Setup must want NO write when the wiring already matches, whatever the
order. It rebuilt the list as `kept + [desired]`, appending our entry, so
with it first in the file — the shipped layout — the equality check failed
Expand Down Expand Up @@ -1227,7 +1243,7 @@ def test_guard_hook_install_is_idempotent_when_our_entry_is_first(

def test_guard_hook_install_keeps_our_entry_in_place(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
, posix_form: None) -> None:
"""A stale entry is refreshed where it sits, not moved to the end, and the
user's own PreToolUse hooks keep their positions."""
stale = _guard_entry()
Expand Down