feat(privacy-host): add signed native calendar contacts and reminders host
Add the owner-only AF_UNIX Reyna CLI privacy host, strict signed-app installation, and typed native routing for Calendar, Contacts, and Reminders.\n\nAdd bounded system-status paths and config-only direct local-service wrappers. Preserve MacMiniMCP pending explicit cutover approval.\n\nApple Notes is intentionally deferred: no native Notes operations, Apple Events declaration, or Automation helper are included; legacy Notes handling remains untouched.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
"""Tests for explicit calendar-authorize operation – TDD fakes only, no live service."""
|
||||
import json
|
||||
import pytest
|
||||
from typer.testing import CliRunner
|
||||
from reyna_cli.cli import app
|
||||
|
||||
runner = CliRunner()
|
||||
|
||||
|
||||
def test_privacy_client_direct_op_uses_explicit_operation(monkeypatch):
|
||||
from reyna_cli import privacy_host as ph_mod
|
||||
|
||||
captured = {}
|
||||
|
||||
class FakeClient:
|
||||
def __init__(self, timeout):
|
||||
captured["timeout"] = timeout
|
||||
|
||||
def call(self, op, args):
|
||||
captured["op"] = op
|
||||
captured["args"] = args
|
||||
return {"id": "x", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "calendar.request_full_access", "status": "authorized"}}
|
||||
|
||||
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
|
||||
result = ph_mod.native_calendar_request_full_access()
|
||||
assert captured["op"] == "calendar.request_full_access"
|
||||
assert captured["args"] == {}
|
||||
assert captured["timeout"] == 35
|
||||
assert result["ok"] is True
|
||||
assert result["source"] == "native_privacy_host"
|
||||
assert result["result"]["status"] == "authorized"
|
||||
|
||||
|
||||
def test_calendar_authorize_cli_no_generic_fallback(monkeypatch):
|
||||
from reyna_cli import privacy_host as ph_mod
|
||||
|
||||
calls = {"count": 0}
|
||||
|
||||
def fake_native():
|
||||
calls["count"] += 1
|
||||
return {"ok": True, "source": "native_privacy_host", "result": {"protocol_version": "1.0.0", "operation": "calendar.request_full_access", "status": "authorized"}}
|
||||
|
||||
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_request_full_access", fake_native)
|
||||
|
||||
# Ensure src does not use generic call / MCP fallback
|
||||
src = ph_mod.__file__
|
||||
import pathlib
|
||||
text = pathlib.Path(src).read_text()
|
||||
# The new function must call PrivacyClient directly with explicit op and not use generic 'call' helper referencing arbitrary operation arg
|
||||
# CLI command must import the explicit function, not PrivacyClient directly (checked via cli source)
|
||||
cli_text = pathlib.Path("src/reyna_cli/cli.py").read_text() if pathlib.Path("src/reyna_cli/cli.py").exists() else pathlib.Path(__file__).parents[1].joinpath("src/reyna_cli/cli.py").read_text()
|
||||
|
||||
res = runner.invoke(app, ["privacy-host", "calendar-authorize", "--json"])
|
||||
assert res.exit_code == 0, res.stdout + res.stderr
|
||||
payload = json.loads(res.stdout)
|
||||
assert payload["ok"] is True
|
||||
assert payload["result"]["status"] == "authorized"
|
||||
assert calls["count"] == 1
|
||||
|
||||
|
||||
def test_calendar_authorize_cli_help_mentions_prompt():
|
||||
res = runner.invoke(app, ["privacy-host", "calendar-authorize", "--help"])
|
||||
assert res.exit_code == 0
|
||||
out = res.stdout.lower()
|
||||
# Help must make prompting clear
|
||||
assert "calendar" in out
|
||||
assert "permission" in out or "prompt" in out or "privacy" in out
|
||||
|
||||
|
||||
def test_calendar_authorize_failures_surface(monkeypatch):
|
||||
from reyna_cli.privacy_client import PrivacyClientError
|
||||
|
||||
def fake_fail():
|
||||
raise PrivacyClientError("privacy RPC returned ok=false: {'code': 'permission_denied'}")
|
||||
|
||||
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_request_full_access", fake_fail)
|
||||
|
||||
res = runner.invoke(app, ["privacy-host", "calendar-authorize", "--json"])
|
||||
assert res.exit_code != 0
|
||||
# payload should have ok:false
|
||||
payload = json.loads(res.stdout)
|
||||
assert payload["ok"] is False
|
||||
|
||||
|
||||
def test_native_calendar_request_full_access_no_mcp_import():
|
||||
from reyna_cli import privacy_host as ph_mod
|
||||
import pathlib
|
||||
src = pathlib.Path(ph_mod.__file__).read_text()
|
||||
# Ensure new function does not import MCP fallback
|
||||
# We locate function definition region
|
||||
# Simple guard: whole module still must not reference MCP fallback helpers
|
||||
assert "call_macmini_tool" not in src
|
||||
assert "macmini_client" not in src
|
||||
# The specific new function should exist
|
||||
assert "def native_calendar_request_full_access" in src
|
||||
assert "calendar.request_full_access" in src
|
||||
|
||||
|
||||
def test_privacy_host_cli_has_calendar_authorize():
|
||||
res = runner.invoke(app, ["privacy-host", "--help"])
|
||||
assert res.exit_code == 0
|
||||
assert "calendar-authorize" in res.stdout
|
||||
# Ensure no generic 'call' command exposed
|
||||
assert "call" not in res.stdout.lower() or "calendar-authorize" in res.stdout
|
||||
Reference in New Issue
Block a user