Files
reyna-cli/tests/test_contacts.py
T
Adolfo Reyna 9fd04b0ce4 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.
2026-08-03 20:27:54 -04:00

168 lines
6.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tests for contacts native wrappers and CLI – TDD fakes only, no live Contacts access."""
from pathlib import Path
import json
import pytest
from typer.testing import CliRunner
from reyna_cli.cli import app
runner = CliRunner()
def test_native_contacts_search_success(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["op"] = op
captured["args"] = args
return {"id": "abc", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "contacts.search", "contacts": [{"id": "1", "name": "Alice", "organization": "OrgA", "modifiedAt": "2026-01-01T00:00:00Z"}]}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_contacts_search(query="alice", limit=20)
assert captured["op"] == "contacts.search"
assert captured["args"]["query"] == "alice"
assert captured["args"]["limit"] == 20
assert result["ok"] is True
assert result["source"] == "native_privacy_host"
assert len(result["result"]["contacts"]) == 1
def test_native_contacts_search_no_query(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["args"] = args
return {"id": "x", "ok": True, "result": {"contacts": []}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
ph_mod.native_contacts_search(query=None, limit=10)
assert "query" not in captured["args"]
def test_native_contacts_read_success(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["op"] = op
captured["args"] = args
return {"id": "a", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "contacts.read", "contact": {"id": "1", "name": "Alice"}}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_contacts_read(contact_id="1")
assert captured["op"] == "contacts.read"
assert captured["args"]["id"] == "1"
assert result["ok"] is True
def test_native_contacts_create_success(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["op"] = op
captured["args"] = args
return {"id": "b", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "contacts.create", "created_contact": {"id": "new", "name": "Alice", "organization": ""}}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_contacts_create(first_name="Alice", last_name="Smith", email="alice@example.com")
assert captured["op"] == "contacts.create"
assert captured["args"]["firstName"] == "Alice"
assert captured["args"]["lastName"] == "Smith"
assert captured["args"]["email"]["value"] == "alice@example.com"
assert result["ok"] is True
def test_native_contacts_request_access_explicit_op(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": "contacts.request_access", "status": "authorized"}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_contacts_request_access()
assert captured["op"] == "contacts.request_access"
assert captured["args"] == {}
assert captured["timeout"] == 35
assert result["result"]["status"] == "authorized"
def test_native_contacts_no_mcp_import():
from reyna_cli import privacy_host as ph_mod
import pathlib
src = pathlib.Path(ph_mod.__file__).read_text()
assert "call_macmini_tool" not in src
assert "macmini_client" not in src
assert "def native_contacts_request_access" in src
assert "contacts.request_access" in src
assert "def native_contacts_search" in src
assert "def native_contacts_read" in src
assert "def native_contacts_create" in src
def test_cli_contacts_search_uses_native(monkeypatch):
def fake_search(query=None, limit=20):
return {"ok": True, "source": "native_privacy_host", "result": {"contacts": [{"id": "1", "name": "Alice", "organization": "", "modifiedAt": "2026-01-01T00:00:00Z"}]}}
monkeypatch.setattr("reyna_cli.privacy_host.native_contacts_search", fake_search)
res = runner.invoke(app, ["macmini", "contacts", "search", "--query", "alice", "--json"])
assert res.exit_code == 0, res.stdout + res.stderr
payload = json.loads(res.stdout)
assert payload["ok"] is True
def test_cli_contacts_read_uses_native(monkeypatch):
def fake_read(contact_id):
return {"ok": True, "source": "native_privacy_host", "result": {"contact": {"id": contact_id, "name": "Alice", "firstName": "Alice", "lastName": "", "organization": "", "jobTitle": "", "emails": [], "phones": [], "modifiedAt": "2026-01-01T00:00:00Z"}}}
monkeypatch.setattr("reyna_cli.privacy_host.native_contacts_read", fake_read)
res = runner.invoke(app, ["macmini", "contacts", "read", "abc-123", "--json"])
assert res.exit_code == 0, res.stdout + res.stderr
payload = json.loads(res.stdout)
assert payload["ok"] is True
def test_cli_contacts_create_uses_native(monkeypatch):
captured = {}
def fake_create(first_name=None, last_name=None, organization=None, job_title=None, note=None, email=None, phone=None):
captured["first_name"] = first_name
captured["email"] = email
return {"ok": True, "source": "native_privacy_host", "result": {"created_contact": {"id": "new", "name": "Alice", "organization": ""}}}
monkeypatch.setattr("reyna_cli.privacy_host.native_contacts_create", fake_create)
res = runner.invoke(app, ["macmini", "contacts", "create", "--first-name", "Alice", "--email", "alice@example.com", "--json"])
assert res.exit_code == 0, res.stdout + res.stderr
assert captured["first_name"] == "Alice"
assert captured["email"] == "alice@example.com"
def test_cli_contacts_no_mcp_tool_call_remaining():
from reyna_cli import cli as cli_mod
src = Path(cli_mod.__file__).read_text()
assert "native_contacts_search" in src
assert "native_contacts_read" in src
assert "native_contacts_create" in src
assert 'call_macmini_tool("contacts_search"' not in src
assert 'call_macmini_tool("contacts_read"' not in src
assert 'call_macmini_tool("contacts_create"' not in src