"""Tests for onboarding status endpoints.""" from datetime import datetime, timezone import pytest from sqlalchemy import select from app.models.user import User @pytest.mark.asyncio async def test_onboarding_status_fresh_user(client, auth_headers): """Fresh user should have all onboarding items false.""" response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 data = response.json() assert data["created_flow"] is False assert data["ran_session"] is False assert data["exported_session"] is False assert data["tried_ai_assistant"] is False assert data["invited_teammate"] is False assert data["connected_psa"] is False assert data["is_team_user"] is False assert data["dismissed"] is False # Phase 2 fields default to false on a fresh, unverified user with no wizard progress. assert data["email_verified"] is False assert data["shop_setup_done"] is False @pytest.mark.asyncio async def test_onboarding_status_includes_email_verified_and_shop_setup_done( client, auth_headers, test_user, test_db ): """email_verified flips when email_verified_at is set; shop_setup_done flips at step >= 1.""" # Sanity-check baseline. response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 data = response.json() assert data["email_verified"] is False assert data["shop_setup_done"] is False # Mutate the underlying user, then re-fetch. user_email = test_user["email"] result = await test_db.execute(select(User).where(User.email == user_email)) user = result.scalar_one() user.email_verified_at = datetime.now(tz=timezone.utc) user.onboarding_step_completed = 1 await test_db.commit() response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 data = response.json() assert data["email_verified"] is True assert data["shop_setup_done"] is True @pytest.mark.asyncio async def test_onboarding_dismiss(client, auth_headers): """Dismiss endpoint should set dismissed to true.""" # Verify starts as false response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 assert response.json()["dismissed"] is False # Dismiss response = await client.post( "/api/v1/users/onboarding-status/dismiss", headers=auth_headers, ) assert response.status_code == 200 assert response.json()["dismissed"] is True # Verify persisted response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 assert response.json()["dismissed"] is True @pytest.mark.asyncio async def test_onboarding_created_flow_after_tree_creation(client, auth_headers, test_tree): """After creating a tree, created_flow should be true.""" response = await client.get( "/api/v1/users/onboarding-status", headers=auth_headers, ) assert response.status_code == 200 assert response.json()["created_flow"] is True @pytest.mark.asyncio async def test_onboarding_requires_auth(client): """Unauthenticated requests should be rejected.""" response = await client.get("/api/v1/users/onboarding-status") assert response.status_code == 401 response = await client.post("/api/v1/users/onboarding-status/dismiss") assert response.status_code == 401