"""Tests for Phase 5 endpoints: goal-history and smart-tagging suggestion.""" import json import uuid from datetime import datetime, timedelta, timezone import pytest API_KEY = {"X-API-Key": "test-api-key"} async def _seed_profile() -> str: 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", short_term_goals="run a pilot", long_term_goals="statewide outfit", ) db.add(profile) await db.commit() return profile.id async def _add_revision(profile_id, short, source, day): from app.auth import API_KEY_ADMIN_ID from app.database import AsyncSessionLocal from app.models import ProfileRevision async with AsyncSessionLocal() as db: db.add( ProfileRevision( id=str(uuid.uuid4()), profile_id=profile_id, user_id=API_KEY_ADMIN_ID, source=source, fields_json=json.dumps( {"short_term_goals": short, "long_term_goals": "statewide outfit"} ), note=None, created_at=datetime(2026, 6, day, tzinfo=timezone.utc), ) ) await db.commit() # ---- goal history ---------------------------------------------------------- async def test_goal_history_timeline(app_client): pid = await _seed_profile() await _add_revision(pid, "run a pilot", "extraction", 1) await _add_revision(pid, "run a pilot", "manual_edit", 2) # unchanged await _add_revision(pid, "launch fall cohort", "reflection", 3) r = await app_client.get( "/discovery/profile/me/goal-history", headers=API_KEY ) assert r.status_code == 200 st = r.json()["short_term_goals"] assert [e["value"] for e in st] == ["run a pilot", "launch fall cohort"] assert st[-1]["source"] == "reflection" async def test_goal_history_without_profile_404(app_client): r = await app_client.get( "/discovery/profile/me/goal-history", headers=API_KEY ) assert r.status_code == 404 # ---- smart tagging --------------------------------------------------------- class FakeTagger: result = {"foundation": "short_term", "rationale": "builds your pilot", "confidence": "high"} def __init__(self, api_key=None, model=None): pass async def suggest(self, task_label, foundations): FakeTagger.last_label = task_label return dict(FakeTagger.result) @pytest.fixture(autouse=True) async def fake_tagger(monkeypatch, app_client): monkeypatch.setattr("app.routers.integration.FoundationTagger", FakeTagger) yield async def test_suggest_foundation(app_client): await _seed_profile() r = await app_client.post( "/discovery/integration/suggest-foundation", headers=API_KEY, json={"task_label": "practice welding for the cohort"}, ) assert r.status_code == 200 body = r.json() assert body["foundation"] == "short_term" assert body["label"] # human label filled in assert body["confidence"] == "high" assert FakeTagger.last_label == "practice welding for the cohort" async def test_suggest_foundation_empty_label_400(app_client): await _seed_profile() r = await app_client.post( "/discovery/integration/suggest-foundation", headers=API_KEY, json={"task_label": " "}, ) assert r.status_code == 400 async def test_suggest_foundation_without_profile_404(app_client): r = await app_client.post( "/discovery/integration/suggest-foundation", headers=API_KEY, json={"task_label": "anything"}, ) assert r.status_code == 404 async def test_suggest_requires_auth(app_client): r = await app_client.post( "/discovery/integration/suggest-foundation", json={"task_label": "x"}, ) assert r.status_code == 401