1 line
8.0 KiB
JSON
1 line
8.0 KiB
JSON
{"repo": "averatec0773/beatos", "files": {"packages/beatos-http/tests/test_ai_settings.py": {"4d8d9409c219a9003ba2a4bc3bdd1bdf51ef4fe4": {"t": 1785746913.024639, "n": 2447, "h": "b64c553d0592c71a", "c": "\"\"\"EPIC-D4a: in-app AI config + status + secret-key redaction.\"\"\"\nfrom __future__ import annotations\n\nimport pytest\n\nfrom beatos_core.app_settings.service import set_setting\nfrom beatos_core.db import run_migrations\n\nfrom beatos_http.ai.service import AI_API_KEY, AI_PROVIDER_KEY, get_ai_status, has_api_key\nfrom beatos_http.api_auth import SECRET_SETTING_KEYS, SENSITIVE_SETTING_KEYS\nfrom beatos_http.routes.app_settings import get as get_setting_route\n\n\n@pytest.fixture\ndef db(tmp_path, monkeypatch):\n p = tmp_path / \"global.db\"\n monkeypatch.setenv(\"BEATOS_DB_PATH\", str(p))\n return p\n\n\nasync def test_status_default_off(db):\n await run_migrations(db)\n s = await get_ai_status()\n assert s == {\n \"provider\": None,\n \"has_key\": False,\n \"enabled\": False,\n \"model\": \"claude-haiku-4-5\",\n \"supported\": [\"anthropic\", \"openai\", \"deepseek\"],\n \"supported_models\": [\"claude-haiku-4-5\", \"claude-sonnet-4-6\"],\n }\n\n\nasync def test_status_enabled_with_provider_and_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n await set_setting(AI_API_KEY, \"sk-super-secret\")\n s = await get_ai_status()\n assert s[\"provider\"] == \"anthropic\"\n assert s[\"has_key\"] is True\n assert s[\"enabled\"] is True\n # The status must never carry the key value.\n assert \"sk-super-secret\" not in str(s)\n\n\nasync def test_provider_without_key_is_not_enabled(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n s = await get_ai_status()\n assert s[\"has_key\"] is False\n assert s[\"enabled\"] is False\n\n\nasync def test_unknown_provider_not_enabled_even_with_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"totally-made-up\")\n await set_setting(AI_API_KEY, \"sk-x\")\n s = await get_ai_status()\n assert s[\"enabled\"] is False\n\n\nasync def test_get_route_never_returns_the_secret_key(db):\n await run_migrations(db)\n await set_setting(AI_API_KEY, \"sk-leak-me-not\")\n out = await get_setting_route(AI_API_KEY)\n assert out[\"value\"] is None\n assert out[\"secret\"] is True\n assert out[\"is_set\"] is True\n assert \"sk-leak-me-not\" not in str(out)\n # The service still sees it (server-side use only).\n assert await has_api_key() is True\n\n\ndef test_key_classification():\n assert \"ai_api_key\" in SECRET_SETTING_KEYS\n assert {\"ai_api_key\", \"ai_provider\"} <= SENSITIVE_SETTING_KEYS\n"}, "63c4138dfa8f502c865d832ac069bdb9e65fd3a4": {"t": 1785768855.115779, "n": 2447, "h": "b64c553d0592c71a", "c": "\"\"\"EPIC-D4a: in-app AI config + status + secret-key redaction.\"\"\"\nfrom __future__ import annotations\n\nimport pytest\n\nfrom beatos_core.app_settings.service import set_setting\nfrom beatos_core.db import run_migrations\n\nfrom beatos_http.ai.service import AI_API_KEY, AI_PROVIDER_KEY, get_ai_status, has_api_key\nfrom beatos_http.api_auth import SECRET_SETTING_KEYS, SENSITIVE_SETTING_KEYS\nfrom beatos_http.routes.app_settings import get as get_setting_route\n\n\n@pytest.fixture\ndef db(tmp_path, monkeypatch):\n p = tmp_path / \"global.db\"\n monkeypatch.setenv(\"BEATOS_DB_PATH\", str(p))\n return p\n\n\nasync def test_status_default_off(db):\n await run_migrations(db)\n s = await get_ai_status()\n assert s == {\n \"provider\": None,\n \"has_key\": False,\n \"enabled\": False,\n \"model\": \"claude-haiku-4-5\",\n \"supported\": [\"anthropic\", \"openai\", \"deepseek\"],\n \"supported_models\": [\"claude-haiku-4-5\", \"claude-sonnet-4-6\"],\n }\n\n\nasync def test_status_enabled_with_provider_and_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n await set_setting(AI_API_KEY, \"sk-super-secret\")\n s = await get_ai_status()\n assert s[\"provider\"] == \"anthropic\"\n assert s[\"has_key\"] is True\n assert s[\"enabled\"] is True\n # The status must never carry the key value.\n assert \"sk-super-secret\" not in str(s)\n\n\nasync def test_provider_without_key_is_not_enabled(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n s = await get_ai_status()\n assert s[\"has_key\"] is False\n assert s[\"enabled\"] is False\n\n\nasync def test_unknown_provider_not_enabled_even_with_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"totally-made-up\")\n await set_setting(AI_API_KEY, \"sk-x\")\n s = await get_ai_status()\n assert s[\"enabled\"] is False\n\n\nasync def test_get_route_never_returns_the_secret_key(db):\n await run_migrations(db)\n await set_setting(AI_API_KEY, \"sk-leak-me-not\")\n out = await get_setting_route(AI_API_KEY)\n assert out[\"value\"] is None\n assert out[\"secret\"] is True\n assert out[\"is_set\"] is True\n assert \"sk-leak-me-not\" not in str(out)\n # The service still sees it (server-side use only).\n assert await has_api_key() is True\n\n\ndef test_key_classification():\n assert \"ai_api_key\" in SECRET_SETTING_KEYS\n assert {\"ai_api_key\", \"ai_provider\"} <= SENSITIVE_SETTING_KEYS\n"}, "4d9045906d303c2f6b8c28f0a30fd69ecd6551c5": {"t": 1785768857.3636682, "n": 2425, "h": "a8257e80da15f48d", "c": "\"\"\"EPIC-D4a: in-app AI config + status + secret-key redaction.\"\"\"\nfrom __future__ import annotations\n\nimport pytest\n\nfrom beatos_core.app_settings.service import set_setting\nfrom beatos_core.db import run_migrations\n\nfrom beatos_http.ai.service import AI_API_KEY, AI_PROVIDER_KEY, get_ai_status, has_api_key\nfrom beatos_http.api_auth import SECRET_SETTING_KEYS, SENSITIVE_SETTING_KEYS\nfrom beatos_http.routes.app_settings import get as get_setting_route\n\n\n@pytest.fixture\ndef db(tmp_path, monkeypatch):\n p = tmp_path / \"global.db\"\n monkeypatch.setenv(\"BEATOS_DB_PATH\", str(p))\n return p\n\n\nasync def test_status_default_off(db):\n await run_migrations(db)\n s = await get_ai_status()\n assert s == {\n \"provider\": None,\n \"has_key\": False,\n \"enabled\": False,\n \"model\": \"claude-haiku-4-5\",\n \"supported\": [\"anthropic\"],\n \"supported_models\": [\"claude-haiku-4-5\", \"claude-sonnet-4-6\"],\n }\n\n\nasync def test_status_enabled_with_provider_and_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n await set_setting(AI_API_KEY, \"sk-super-secret\")\n s = await get_ai_status()\n assert s[\"provider\"] == \"anthropic\"\n assert s[\"has_key\"] is True\n assert s[\"enabled\"] is True\n # The status must never carry the key value.\n assert \"sk-super-secret\" not in str(s)\n\n\nasync def test_provider_without_key_is_not_enabled(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"anthropic\")\n s = await get_ai_status()\n assert s[\"has_key\"] is False\n assert s[\"enabled\"] is False\n\n\nasync def test_unknown_provider_not_enabled_even_with_key(db):\n await run_migrations(db)\n await set_setting(AI_PROVIDER_KEY, \"totally-made-up\")\n await set_setting(AI_API_KEY, \"sk-x\")\n s = await get_ai_status()\n assert s[\"enabled\"] is False\n\n\nasync def test_get_route_never_returns_the_secret_key(db):\n await run_migrations(db)\n await set_setting(AI_API_KEY, \"sk-leak-me-not\")\n out = await get_setting_route(AI_API_KEY)\n assert out[\"value\"] is None\n assert out[\"secret\"] is True\n assert out[\"is_set\"] is True\n assert \"sk-leak-me-not\" not in str(out)\n # The service still sees it (server-side use only).\n assert await has_api_key() is True\n\n\ndef test_key_classification():\n assert \"ai_api_key\" in SECRET_SETTING_KEYS\n assert {\"ai_api_key\", \"ai_provider\"} <= SENSITIVE_SETTING_KEYS\n"}}}} |