"""Tests for authentication endpoints.""" import pytest from unittest.mock import MagicMock, patch def make_auth_user(user_id="user-123", email="test@example.com"): user = MagicMock() user.id = user_id user.email = email return user def make_session(token="test-access-token"): session = MagicMock() session.access_token = token return session class TestSignup: def test_signup_returns_401_without_body(self, client): resp = client.post("/api/v1/auth/signup") assert resp.status_code == 422 # validation error def test_signup_success(self, client): user = make_auth_user() session = make_session() with patch("app.routers.auth.get_supabase") as mock_sb: sb = MagicMock() auth_resp = MagicMock() auth_resp.user = user auth_resp.session = session sb.auth.sign_up.return_value = auth_resp sb.table.return_value.insert.return_value.execute.return_value = MagicMock(data=[{}]) sb.table.return_value.select.return_value.eq.return_value.execute.return_value = MagicMock(data=[]) mock_sb.return_value = sb resp = client.post("/api/v1/auth/signup", json={ "email": "new@example.com", "password": "password123", "company_name": "Test Corp", }) assert resp.status_code == 200 data = resp.json() assert "access_token" in data assert data["user"]["email"] == "test@example.com" assert data["user"]["plan"] == "free" assert data["user"]["is_admin"] == False class TestLogin: def test_login_returns_422_without_body(self, client): resp = client.post("/api/v1/auth/login") assert resp.status_code == 422 def test_login_success(self, client): user = make_auth_user() session = make_session() with patch("app.routers.auth.get_supabase") as mock_sb: sb = MagicMock() auth_resp = MagicMock() auth_resp.user = user auth_resp.session = session sb.auth.sign_in_with_password.return_value = auth_resp # company query comp_exec = MagicMock(data=[{"name": "Test Corp"}]) # subscription query sub_exec = MagicMock(data=[{"plan": "starter"}]) # profile query profile_exec = MagicMock(data=[{"is_admin": False}]) # Chain: table().select().eq().eq().execute() def table_side(name): t = MagicMock() t.select.return_value = t t.eq.return_value = t if name == "companies": t.execute.return_value = comp_exec elif name == "subscriptions": t.execute.return_value = sub_exec elif name == "user_profiles": t.execute.return_value = profile_exec else: t.execute.return_value = MagicMock(data=[]) return t sb.table.side_effect = table_side mock_sb.return_value = sb resp = client.post("/api/v1/auth/login", json={ "email": "test@example.com", "password": "password123", }) assert resp.status_code == 200 data = resp.json() assert data["access_token"] == "test-access-token" assert data["user"]["plan"] == "starter" class TestMe: def test_me_returns_401_without_auth(self, client): resp = client.get("/api/v1/auth/me") assert resp.status_code == 401 def test_forgot_password_always_returns_200(self, client): with patch("app.routers.auth.get_supabase") as mock_sb: sb = MagicMock() sb.auth.reset_password_for_email.return_value = None mock_sb.return_value = sb resp = client.post("/api/v1/auth/forgot-password", json={"email": "any@example.com"}) assert resp.status_code == 200 assert "message" in resp.json()