"""Tests for remaining coverage migration — fully consolidated no-Notes CLI. This file replaces the old Notes-native tests. Validates: - privacy contract contains only calendar/contacts/reminders/system/speech/apple_llm (no notes) - coverage matrix exists and says Notes deferred + legacy untouched - system info still works via native host - local-services direct wrappers offline safe (no Notes) - docs mention Notes deferred """ import json import pytest from typer.testing import CliRunner from unittest.mock import MagicMock from reyna_cli.cli import app runner = CliRunner() # ─── Coverage matrix existence ─────────────────────────────────────────── def test_coverage_matrix_exists(): from pathlib import Path p = Path(__file__).parents[1] / "docs" / "remaining-coverage-matrix.md" assert p.exists(), f"matrix doc missing at {p}" content = p.read_text() # Must mention Notes deferred assert "Notes" in content assert "deferred" in content.lower(), "matrix must say Notes deferred" assert "legacy" in content.lower() assert "untouched" in content.lower() # ─── Privacy contract — no notes, deferred ──────────────────────────────── def test_privacy_contract_no_notes_ops(): from reyna_cli.privacy_contract import ALLOWED_OPERATIONS, _COMMAND_TO_OPERATION for op in ALLOWED_OPERATIONS.keys(): assert not op.startswith("notes."), f"forbidden notes op {op} present — Notes deferred" forbidden = {"notes.list", "notes.read", "notes.create", "notes.request_access"} for fo in forbidden: assert fo not in ALLOWED_OPERATIONS for cmd, op in _COMMAND_TO_OPERATION.items(): assert not op.startswith("notes.") assert not cmd.startswith("notes_") # Should still contain calendar/contacts/reminders/system/speech assert "calendar.list" in ALLOWED_OPERATIONS assert "contacts.search" in ALLOWED_OPERATIONS assert "reminders.lists" in ALLOWED_OPERATIONS assert "system.get_info" in ALLOWED_OPERATIONS assert "apple_llm.check" in ALLOWED_OPERATIONS def test_privacy_contract_mapping(): from reyna_cli.privacy_contract import command_to_operation assert command_to_operation("system_get_info") == "system.get_info" assert command_to_operation("apple_llm_check") == "apple_llm.check" # ─── System info wrappers still work ───────────────────────────────────── def test_native_system_get_info_wrapper(monkeypatch): from reyna_cli import privacy_host as ph_mod class FakeClient: def call(self, op, args): assert op == "system.get_info" return {"id": "x", "ok": True, "result": {"system_info": {"macos_version": "26.0"}}} monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient) res = ph_mod.native_system_get_info() assert res["ok"] is True def test_cli_system_info_uses_native(monkeypatch): def fake_native(): return {"ok": True, "source": "native_privacy_host", "result": {"system_info": {"macos_version": "15.0"}}} monkeypatch.setattr("reyna_cli.privacy_host.native_system_get_info", fake_native) result = runner.invoke(app, ["macmini", "system-info", "--json"]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload["ok"] is True # ─── No Notes CLI ───────────────────────────────────────────────────────── def test_cli_macmini_no_notes_subcommand(): result = runner.invoke(app, ["macmini", "--help"]) assert result.exit_code == 0 assert "notes" not in result.stdout.lower(), f"macmini must not list notes — Notes deferred, got: {result.stdout}" def test_cli_privacy_host_no_notes_authorize(): result = runner.invoke(app, ["privacy-host", "--help"]) assert result.exit_code == 0 # notes-authorize must be gone assert "notes" not in result.stdout.lower() # ─── Local services direct wrappers offline safe ─────────────────────────── def test_speech_direct_config_offline(): from reyna_cli.local_services_direct import SpeechDirectClient c = SpeechDirectClient().config_status() assert "say_available" in c assert "source" in c assert c["source"] == "direct" assert isinstance(c.get("say_path"), str) def test_speech_direct_validate_args(): from reyna_cli.local_services_direct import SpeechDirectClient cli = SpeechDirectClient() ok = cli.synthesize_args("hello", voice="Alex", rate=200) assert ok["text"] == "hello" with pytest.raises(ValueError): cli.synthesize_args("", voice="Alex") with pytest.raises(ValueError): cli.synthesize_args("hi", rate=10) def test_kokoro_config_offline_no_network(): from reyna_cli.local_services_direct import KokoroDirectClient c = KokoroDirectClient(url="http://127.0.0.1:7332").config_status() assert c["url"] == "http://127.0.0.1:7332" assert c["source"] == "direct" assert "note" in c v = KokoroDirectClient().validate_synthesize("hello world") assert v["offline_validation"] is True with pytest.raises(ValueError): KokoroDirectClient().validate_synthesize("") def test_kokoro_no_secret_exposure(monkeypatch): from reyna_cli.local_services_direct import KokoroDirectClient monkeypatch.setenv("KSAY_URL", "http://127.0.0.1:7332") c = KokoroDirectClient().config_status() for k in c: assert "token" not in k.lower() or "password" not in str(c[k]).lower() def test_voicebox_config_offline(): from reyna_cli.local_services_direct import VoiceboxDirectClient c = VoiceboxDirectClient().config_status() assert "url" in c assert c["source"] == "direct" assert "known_profiles" in c v = VoiceboxDirectClient().validate_generate("hello", profile="Aiden") assert v["offline_validation"] is True def test_apple_llm_config_offline(): from reyna_cli.local_services_direct import AppleLLMDirectClient c = AppleLLMDirectClient().config_status() assert "swift_available" in c or "swiftc_available" in c assert c["source"] == "direct" v = AppleLLMDirectClient().validate_polish("hello world", mode="line") assert v["offline_validation"] is True def test_image_config_offline_no_key_exposure(monkeypatch): from reyna_cli.local_services_direct import ImageDirectClient monkeypatch.delenv("GEMINI_API_KEY", raising=False) c = ImageDirectClient().config_status() assert c["source"] == "direct" assert "gemini_api_key_configured" in c assert c["gemini_api_key_configured"] is False assert "GEMINI_API_KEY" not in json.dumps(c) monkeypatch.setenv("GEMINI_API_KEY", "secret123") c2 = ImageDirectClient().config_status() assert c2["gemini_api_key_configured"] is True assert "secret123" not in json.dumps(c2) def test_system_direct_offline(): from reyna_cli.local_services_direct import SystemDirectClient c = SystemDirectClient().config_status() assert c["requires_tcc"] is False info = SystemDirectClient().get_info_offline() assert "macos_version" in info # ─── CLI local-services commands offline ────────────────────────────────── def test_cli_local_services_speech_config(): result = runner.invoke(app, ["local-services", "speech", "config", "--json"]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload["ok"] is True assert payload["source"] == "direct" def test_cli_local_services_kokoro_config(): result = runner.invoke(app, ["local-services", "kokoro", "config", "--json"]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload["result"]["source"] == "direct" def test_cli_local_services_voicebox_config(): result = runner.invoke(app, ["local-services", "voicebox", "config", "--json"]) assert result.exit_code == 0 def test_cli_local_services_apple_llm_config(): result = runner.invoke(app, ["local-services", "apple-llm", "config", "--json"]) assert result.exit_code == 0 def test_cli_local_services_image_config(): result = runner.invoke(app, ["local-services", "image", "config", "--json"]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload["ok"] is True def test_cli_local_services_system_info(): result = runner.invoke(app, ["local-services", "system", "info", "--json"]) assert result.exit_code == 0 def test_no_mcp_imports_in_direct_wrappers(): from pathlib import Path p = Path(__file__).parents[1] / "src" / "reyna_cli" / "local_services_direct.py" src = p.read_text() assert "MCPClient" not in src assert "call_macmini_tool" not in src assert "macmini_client" not in src assert "httpx.Client" not in src assert "requests.get" not in src def test_direct_wrappers_no_credential_exposure(): from pathlib import Path src = (Path(__file__).parents[1] / "src" / "reyna_cli" / "local_services_direct.py").read_text() assert "DECO_PASSWORD" not in src from reyna_cli.local_services_direct import KokoroDirectClient, VoiceboxDirectClient, AppleLLMDirectClient for c in [KokoroDirectClient().config_status(), VoiceboxDirectClient().config_status(), AppleLLMDirectClient().config_status()]: for k, v in c.items(): if isinstance(v, str): assert len(v) < 5000 def test_no_notes_wrappers_in_privacy_host(): from pathlib import Path src = (Path(__file__).parents[1] / "src" / "reyna_cli" / "privacy_host.py").read_text() assert "native_notes" not in src assert "NotesProvider" not in src