ppt-tool/backend/tests/test_auth_service.py
Vadym Samoilenko f2f729a50b Switch Azure AD auth to MSAL SPA (browser-side token exchange)
- Replace server-side ConfidentialClientApplication + OAuth callback
  with MSAL browser popup flow (PKCE, no client_secret required)
- Backend: add POST /sso-token endpoint that validates Azure AD ID token
  via Microsoft JWKS, issues session cookie; remove /login + /callback
- Frontend: install @azure/msal-browser + @azure/msal-react, wrap app
  with MsalProvider, login page uses loginPopup() → sends id_token to backend
- Pass NEXT_PUBLIC_AZURE_* env vars through next.config.mjs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 12:34:52 +00:00

78 lines
2.7 KiB
Python

"""Tests for auth_service: JWT creation/validation, dev login, user creation."""
import uuid
import pytest
from services.auth_service import AuthService
@pytest.fixture
def auth_service():
return AuthService()
class TestJWT:
def test_create_and_validate_token(self, auth_service):
"""Token round-trip: create → validate → same payload."""
from models.sql.user import UserModel
user = UserModel(
id=uuid.uuid4(),
email="jwt@test.com",
display_name="JWT User",
role="user",
is_active=True,
)
token = auth_service.create_session_jwt(user)
payload = auth_service.validate_token(token)
assert payload is not None
assert payload["sub"] == str(user.id)
assert payload["email"] == "jwt@test.com"
assert payload["role"] == "user"
def test_validate_invalid_token(self, auth_service):
assert auth_service.validate_token("garbage.token.here") is None
def test_validate_tampered_token(self, auth_service):
from models.sql.user import UserModel
user = UserModel(
id=uuid.uuid4(),
email="tamper@test.com",
display_name="Tamper",
role="user",
is_active=True,
)
token = auth_service.create_session_jwt(user)
# Tamper with the token
tampered = token[:-5] + "XXXXX"
assert auth_service.validate_token(tampered) is None
class TestDevLogin:
async def test_dev_login_success(self, auth_service, session):
"""Dev mode: correct password creates user."""
user = await auth_service.dev_login("dev@test.com", "testpass", session)
assert user is not None
assert user.email == "dev@test.com"
async def test_dev_login_wrong_password(self, auth_service, session):
user = await auth_service.dev_login("dev@test.com", "wrongpass", session)
assert user is None
async def test_dev_login_idempotent(self, auth_service, session):
"""Logging in twice with same email returns same user."""
user1 = await auth_service.dev_login("dev@test.com", "testpass", session)
user2 = await auth_service.dev_login("dev@test.com", "testpass", session)
assert user1.id == user2.id
class TestDevMode:
def test_is_dev_mode_when_no_azure(self, auth_service):
"""Without AZURE_AD_TENANT_ID, service is in dev mode."""
assert auth_service.is_dev_mode is True
async def test_validate_azure_token_raises_in_dev_mode(self, auth_service):
with pytest.raises(ValueError, match="not configured"):
await auth_service.validate_azure_token("dummy.token.here")