Files
impactflow_discovery/tests/conftest.py
T
Joel Salmon 33674f92f4 Complete Phase 1: goals, cookie auth, profile editing
Close the remaining Phase 1 DoD gaps and reconcile the browser flow with
the auth layer.

Goals (5 -> 7 prompts):
- Add near-term (6-12mo) and long-term (3-5yr) goal prompts; collect raw
  text on the conversation and store AI-articulated goal summaries on the
  profile. Extractor articulates the person's own stated goals (mirror,
  not compass) and never fabricates. Alembic 003 adds the four columns.

Cookie-based browser sessions (fixes frontend<->auth desync):
- OAuth callback now sets httpOnly session cookies and redirects into the
  app instead of returning JSON. get_current_user gains a cookie fallback
  (X-API-Key -> Bearer -> cookie). refresh/logout read the refresh cookie
  and set/clear cookies. New shared auth.js (authedFetch) sends cookies and
  silently refreshes on 401. Static pages drop the bogus user_id and call
  the correct /me endpoints.

Profile editing (read/edit/affirm):
- PATCH /discovery/profile/me edits the prose (Ikigai summaries, overlap
  narrative, goals); owner-scoped, partial update, 409 when locked. Edit
  mode in profile.html with Save/Cancel.

Also: bump default model to claude-sonnet-4-6, align ports to 8011
(OAuth redirect, CORS), add COOKIE_SECURE/POST_LOGIN_REDIRECT config, and
refresh the README to match the shipped behavior.

Tests: 33 passing (added cookie-auth, profile-edit, goal-extraction cases;
factored a shared app_client fixture into conftest.py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 18:26:08 -05:00

46 lines
1.4 KiB
Python

"""Shared test fixtures.
`app_client` spins up the FastAPI app against an isolated temp SQLite DB with
known auth secrets, so any test can exercise the real routes over httpx
without touching the developer's database.
"""
import pytest
from httpx import ASGITransport, AsyncClient
@pytest.fixture
async def app_client(tmp_path, monkeypatch):
db_path = tmp_path / "test.db"
monkeypatch.setenv("DATABASE_URL", f"sqlite+aiosqlite:///{db_path}")
monkeypatch.setenv("JWT_SECRET", "test-jwt-secret")
monkeypatch.setenv("IMPACTFLOW_API_KEY", "test-api-key")
monkeypatch.setenv("GOOGLE_CLIENT_ID", "fake-client-id")
monkeypatch.setenv("GOOGLE_CLIENT_SECRET", "fake-client-secret")
monkeypatch.setenv("ALLOWED_EMAIL_DOMAINS", "")
# Plain http test transport: non-Secure cookies so the jar replays them.
monkeypatch.setenv("COOKIE_SECURE", "false")
# Clear app modules so they re-read the patched env at import time.
import importlib
import sys
for mod in list(sys.modules):
if mod.startswith("app"):
del sys.modules[mod]
from app import database
importlib.reload(database)
from app.database import Base, engine
from app.main import app
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
transport = ASGITransport(app=app)
async with AsyncClient(
transport=transport, base_url="http://test"
) as client:
yield client