feat: Add AI report generation with DIFY integration
- Add Users table for display name resolution from AD authentication - Integrate DIFY AI service for report content generation - Create docx assembly service with image embedding from MinIO - Add REST API endpoints for report generation and download - Add WebSocket notifications for generation progress - Add frontend UI with progress modal and download functionality - Add integration tests for report generation flow Report sections (Traditional Chinese): - 事件摘要 (Summary) - 時間軸 (Timeline) - 參與人員 (Participants) - 處理過程 (Resolution Process) - 目前狀態 (Current Status) - 最終處置結果 (Final Resolution) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
164
tests/test_user_service.py
Normal file
164
tests/test_user_service.py
Normal file
@@ -0,0 +1,164 @@
|
||||
"""Unit tests for user service
|
||||
|
||||
Tests for the users table and upsert operations used in report generation.
|
||||
"""
|
||||
import pytest
|
||||
from datetime import datetime, timedelta
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.core.database import Base
|
||||
from app.modules.auth.models import User
|
||||
from app.modules.auth.services.user_service import upsert_user, get_user_by_id, get_display_name
|
||||
|
||||
|
||||
# Create in-memory SQLite database for testing
|
||||
@pytest.fixture
|
||||
def db_session():
|
||||
"""Create a fresh database session for each test"""
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
Base.metadata.create_all(bind=engine)
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
class TestUpsertUser:
|
||||
"""Tests for upsert_user function"""
|
||||
|
||||
def test_create_new_user(self, db_session):
|
||||
"""Test creating a new user record"""
|
||||
user = upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User 測試用戶",
|
||||
office_location="Taipei",
|
||||
job_title="Engineer",
|
||||
)
|
||||
|
||||
assert user.user_id == "test@example.com"
|
||||
assert user.display_name == "Test User 測試用戶"
|
||||
assert user.office_location == "Taipei"
|
||||
assert user.job_title == "Engineer"
|
||||
assert user.last_login_at is not None
|
||||
assert user.created_at is not None
|
||||
|
||||
def test_update_existing_user(self, db_session):
|
||||
"""Test updating an existing user record"""
|
||||
# Create initial user
|
||||
user1 = upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Original Name",
|
||||
office_location="Taipei",
|
||||
job_title="Junior Engineer",
|
||||
)
|
||||
original_created_at = user1.created_at
|
||||
original_last_login = user1.last_login_at
|
||||
|
||||
# Wait a tiny bit to ensure timestamp difference
|
||||
import time
|
||||
time.sleep(0.01)
|
||||
|
||||
# Update same user
|
||||
user2 = upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Updated Name 更新名稱",
|
||||
office_location="Kaohsiung",
|
||||
job_title="Senior Engineer",
|
||||
)
|
||||
|
||||
# Verify update
|
||||
assert user2.user_id == "test@example.com"
|
||||
assert user2.display_name == "Updated Name 更新名稱"
|
||||
assert user2.office_location == "Kaohsiung"
|
||||
assert user2.job_title == "Senior Engineer"
|
||||
# created_at should be preserved
|
||||
assert user2.created_at == original_created_at
|
||||
# last_login_at should be updated
|
||||
assert user2.last_login_at >= original_last_login
|
||||
|
||||
def test_upsert_with_null_optional_fields(self, db_session):
|
||||
"""Test upsert with null office_location and job_title"""
|
||||
user = upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User",
|
||||
office_location=None,
|
||||
job_title=None,
|
||||
)
|
||||
|
||||
assert user.office_location is None
|
||||
assert user.job_title is None
|
||||
|
||||
def test_update_clears_optional_fields(self, db_session):
|
||||
"""Test that updating with None clears optional fields"""
|
||||
# Create with values
|
||||
upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User",
|
||||
office_location="Taipei",
|
||||
job_title="Engineer",
|
||||
)
|
||||
|
||||
# Update with None
|
||||
user = upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User",
|
||||
office_location=None,
|
||||
job_title=None,
|
||||
)
|
||||
|
||||
assert user.office_location is None
|
||||
assert user.job_title is None
|
||||
|
||||
|
||||
class TestGetUserById:
|
||||
"""Tests for get_user_by_id function"""
|
||||
|
||||
def test_get_existing_user(self, db_session):
|
||||
"""Test getting an existing user"""
|
||||
upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User",
|
||||
)
|
||||
|
||||
user = get_user_by_id(db_session, "test@example.com")
|
||||
|
||||
assert user is not None
|
||||
assert user.display_name == "Test User"
|
||||
|
||||
def test_get_nonexistent_user(self, db_session):
|
||||
"""Test getting a user that doesn't exist"""
|
||||
user = get_user_by_id(db_session, "nonexistent@example.com")
|
||||
|
||||
assert user is None
|
||||
|
||||
|
||||
class TestGetDisplayName:
|
||||
"""Tests for get_display_name function"""
|
||||
|
||||
def test_get_display_name_existing_user(self, db_session):
|
||||
"""Test getting display name for existing user"""
|
||||
upsert_user(
|
||||
db=db_session,
|
||||
user_id="test@example.com",
|
||||
display_name="Test User 測試用戶",
|
||||
)
|
||||
|
||||
name = get_display_name(db_session, "test@example.com")
|
||||
|
||||
assert name == "Test User 測試用戶"
|
||||
|
||||
def test_get_display_name_nonexistent_user(self, db_session):
|
||||
"""Test fallback to email for nonexistent user"""
|
||||
name = get_display_name(db_session, "unknown@example.com")
|
||||
|
||||
# Should return email as fallback
|
||||
assert name == "unknown@example.com"
|
||||
Reference in New Issue
Block a user