Files
Meeting_Assistant/backend/tests/test_auth.py
egg 8b6184ecc5 feat: Meeting Assistant MVP - Complete implementation
Enterprise Meeting Knowledge Management System with:

Backend (FastAPI):
- Authentication proxy with JWT (pj-auth-api integration)
- MySQL database with 4 tables (users, meetings, conclusions, actions)
- Meeting CRUD with system code generation (C-YYYYMMDD-XX, A-YYYYMMDD-XX)
- Dify LLM integration for AI summarization
- Excel export with openpyxl
- 20 unit tests (all passing)

Client (Electron):
- Login page with company auth
- Meeting list with create/delete
- Meeting detail with real-time transcription
- Editable transcript textarea (single block, easy editing)
- AI summarization with conclusions/action items
- 5-second segment recording (efficient for long meetings)

Sidecar (Python):
- faster-whisper medium model with int8 quantization
- ONNX Runtime VAD (lightweight, ~20MB vs PyTorch ~2GB)
- Chinese punctuation processing
- OpenCC for Traditional Chinese conversion
- Anti-hallucination parameters
- Auto-cleanup of temp audio files

OpenSpec:
- add-meeting-assistant-mvp (47 tasks, archived)
- add-realtime-transcription (29 tasks, archived)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 20:17:44 +08:00

139 lines
4.6 KiB
Python

"""
Unit tests for authentication functionality.
"""
import pytest
from unittest.mock import patch, MagicMock, AsyncMock
from fastapi.testclient import TestClient
from jose import jwt
pytestmark = pytest.mark.asyncio
class TestAdminRoleDetection:
"""Tests for admin role detection."""
def test_admin_email_gets_admin_role(self):
"""Test that admin email is correctly identified."""
from app.config import settings
admin_email = settings.ADMIN_EMAIL
test_email = "regular@example.com"
# Admin email should be set (either from env or default)
assert admin_email is not None
assert len(admin_email) > 0
assert test_email != admin_email
@patch("app.routers.auth.settings")
def test_create_token_includes_role(self, mock_settings):
"""Test that created tokens include the role."""
mock_settings.JWT_SECRET = "test-secret"
mock_settings.ADMIN_EMAIL = "admin@test.com"
from app.routers.auth import create_token
# Test admin token
admin_token = create_token("admin@test.com", "admin")
admin_payload = jwt.decode(admin_token, "test-secret", algorithms=["HS256"])
assert admin_payload["role"] == "admin"
# Test user token
user_token = create_token("user@test.com", "user")
user_payload = jwt.decode(user_token, "test-secret", algorithms=["HS256"])
assert user_payload["role"] == "user"
class TestTokenValidation:
"""Tests for JWT token validation."""
@patch("app.routers.auth.settings")
def test_decode_valid_token(self, mock_settings):
"""Test decoding a valid token."""
mock_settings.JWT_SECRET = "test-secret"
from app.routers.auth import create_token, decode_token
token = create_token("test@example.com", "user")
payload = decode_token(token)
assert payload.email == "test@example.com"
assert payload.role == "user"
@patch("app.routers.auth.settings")
def test_decode_invalid_token_raises_error(self, mock_settings):
"""Test that invalid tokens raise an error."""
mock_settings.JWT_SECRET = "test-secret"
from app.routers.auth import decode_token
from fastapi import HTTPException
with pytest.raises(HTTPException) as exc_info:
decode_token("invalid-token")
assert exc_info.value.status_code == 401
class TestLoginEndpoint:
"""Tests for the login endpoint."""
@pytest.fixture
def client(self):
"""Create test client."""
from app.main import app
# Skip lifespan for tests
app.router.lifespan_context = None
return TestClient(app, raise_server_exceptions=False)
@patch("app.routers.auth.httpx.AsyncClient")
@patch("app.routers.auth.settings")
async def test_login_success(self, mock_settings, mock_client_class):
"""Test successful login."""
mock_settings.AUTH_API_URL = "https://auth.test.com/login"
mock_settings.ADMIN_EMAIL = "admin@test.com"
mock_settings.JWT_SECRET = "test-secret"
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {"token": "external-token"}
mock_client = AsyncMock()
mock_client.post.return_value = mock_response
mock_client.__aenter__.return_value = mock_client
mock_client.__aexit__.return_value = None
mock_client_class.return_value = mock_client
from app.routers.auth import login
from app.models import LoginRequest
result = await login(LoginRequest(email="user@test.com", password="password"))
assert result.email == "user@test.com"
assert result.role == "user"
assert result.token is not None
@patch("app.routers.auth.httpx.AsyncClient")
@patch("app.routers.auth.settings")
async def test_login_admin_gets_admin_role(self, mock_settings, mock_client_class):
"""Test that admin email gets admin role."""
mock_settings.AUTH_API_URL = "https://auth.test.com/login"
mock_settings.ADMIN_EMAIL = "admin@test.com"
mock_settings.JWT_SECRET = "test-secret"
mock_response = MagicMock()
mock_response.status_code = 200
mock_client = AsyncMock()
mock_client.post.return_value = mock_response
mock_client.__aenter__.return_value = mock_client
mock_client.__aexit__.return_value = None
mock_client_class.return_value = mock_client
from app.routers.auth import login
from app.models import LoginRequest
result = await login(LoginRequest(email="admin@test.com", password="password"))
assert result.role == "admin"