"""Tests for PATCH /discovery/profile/me (profile editing). These run under the X-API-Key admin identity, editing a profile seeded for that user, so they don't depend on the Google OAuth flow. """ import uuid from datetime import datetime, timezone API_KEY = {"X-API-Key": "test-api-key"} async def _seed_profile(locked: bool = False) -> str: """Insert a conversation + profile for the API-key admin user.""" from app.auth import API_KEY_ADMIN_ID, ensure_api_key_admin from app.database import AsyncSessionLocal from app.models import DiscoveryConversation, DiscoveryProfile async with AsyncSessionLocal() as db: await ensure_api_key_admin(db) conv = DiscoveryConversation( id=str(uuid.uuid4()), user_id=API_KEY_ADMIN_ID, started_at=datetime.now(timezone.utc), ) db.add(conv) await db.commit() profile = DiscoveryProfile( id=str(uuid.uuid4()), user_id=API_KEY_ADMIN_ID, conversation_id=conv.id, generated_at=datetime.now(timezone.utc), triad="gut", probable_type=8, wing=9, instinctual_variant="sp", love_summary="orig love", strength_summary="orig strength", mission_summary="orig mission", vocation_summary="orig vocation", overlap_narrative="orig narrative", short_term_goals="orig short", long_term_goals="orig long", locked=locked, ) db.add(profile) await db.commit() return profile.id async def test_patch_updates_prose(app_client): await _seed_profile() r = await app_client.patch( "/discovery/profile/me", headers=API_KEY, json={"love_summary": "new love", "overlap_narrative": "new narrative"}, ) assert r.status_code == 200 body = r.json() assert body["love_summary"] == "new love" assert body["overlap_narrative"] == "new narrative" # Untouched prose preserved; structural inference is never editable here. assert body["strength_summary"] == "orig strength" assert body["triad"] == "gut" assert body["probable_type"] == 8 async def test_patch_partial_does_not_clear_other_fields(app_client): await _seed_profile() r = await app_client.patch( "/discovery/profile/me", headers=API_KEY, json={"short_term_goals": "updated goal"}, ) assert r.status_code == 200 body = r.json() assert body["short_term_goals"] == "updated goal" assert body["long_term_goals"] == "orig long" async def test_patch_locked_profile_returns_409(app_client): await _seed_profile(locked=True) r = await app_client.patch( "/discovery/profile/me", headers=API_KEY, json={"love_summary": "x"}, ) assert r.status_code == 409 async def test_patch_without_profile_returns_404(app_client): r = await app_client.patch( "/discovery/profile/me", headers=API_KEY, json={"love_summary": "x"}, ) assert r.status_code == 404 async def test_patch_empty_payload_returns_400(app_client): await _seed_profile() r = await app_client.patch( "/discovery/profile/me", headers=API_KEY, json={} ) assert r.status_code == 400 async def test_patch_requires_auth(app_client): r = await app_client.patch( "/discovery/profile/me", json={"love_summary": "x"} ) assert r.status_code == 401