S.H.O.N.A.R._Desktop_Companion/backend/tests/test_provider_info.py
avi 76c867fca4 Standalone Shonar Desktop: vendor portable sources + local engine; decouple from ~/Projects/Shonar
- shared/ = portable Android-origin sources vendored from deferred/desktop-server
  (app/build.gradle.kts srcDir repointed; PlaybackController.kt excluded as Android-only)
- backend/ = bundled-lite engine (SQLite + inline queue); .venv symlinked from the
  old checkout, PYTHONPATH pins THIS backend's code over any editable install
- repoRoot() resolves this project dir (env SHONAR_REPO still wins); desktop-dev.sh
  watches shared/ + backend/
- Verified: :app:compileKotlin + :app:test green (23 tests); engine boots on :8010,
  self-migrates, /healthz ok
2026-09-14 17:14:54 -05:00

35 lines
1.3 KiB
Python

"""provider-info handshake tests (P2/P3 client probing depends on this)."""
async def test_provider_info_identifies_shonar(client):
r = await client.get("/api/v1/provider-info")
assert r.status_code == 200
body = r.json()
assert body["kind"] == "shonar"
assert body["api_version"] == "v1"
caps = body["capabilities"]
assert caps["chunked_upload"] is True
assert caps["account_deletion"] is True
# test env configures no AI providers -> flags must be false
assert caps["server_transcription"] is False
assert caps["server_summary"] is False
assert body["storage_backend"] in ("local", "s3")
async def test_provider_info_leaks_no_paths_or_secrets(client):
r = await client.get("/api/v1/provider-info")
body = r.json()
# every string value must be a bare identifier, never a filesystem path
def walk(v):
if isinstance(v, str):
assert not v.startswith("/"), f"path-like value in handshake: {v!r}"
low = v.lower()
for banned in ("secret", "token", "password", "key"):
assert banned not in low
elif isinstance(v, dict):
for x in v.values():
walk(x)
elif isinstance(v, list):
for x in v:
walk(x)
walk(body)