Initial commit: KPI Management System Backend
Features: - FastAPI backend with JWT authentication - MySQL database with SQLAlchemy ORM - KPI workflow: draft → pending → approved → evaluation → completed - Ollama LLM API integration for AI features - Gitea API integration for version control - Complete API endpoints for KPI, dashboard, notifications Tables: KPI_D_* prefix naming convention 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
126
tests/conftest.py
Normal file
126
tests/conftest.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
共用測試 Fixture
|
||||
"""
|
||||
import pytest
|
||||
from typing import Generator
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker, Session
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
from app.core.database import Base, get_db
|
||||
from app.core.security import create_access_token, get_password_hash
|
||||
from app.models.employee import Employee
|
||||
from app.models.department import Department
|
||||
|
||||
# 測試資料庫 URL (使用 SQLite 進行測試)
|
||||
TEST_DATABASE_URL = "sqlite:///./test.db"
|
||||
|
||||
# 建立測試引擎
|
||||
engine = create_engine(TEST_DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def setup_database():
|
||||
"""建立測試資料庫"""
|
||||
Base.metadata.create_all(bind=engine)
|
||||
yield
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def db() -> Generator[Session, None, None]:
|
||||
"""
|
||||
每個測試函式使用獨立的資料庫 Session
|
||||
測試結束後自動 rollback
|
||||
"""
|
||||
connection = engine.connect()
|
||||
transaction = connection.begin()
|
||||
|
||||
session = TestingSessionLocal(bind=connection)
|
||||
|
||||
yield session
|
||||
|
||||
session.close()
|
||||
transaction.rollback()
|
||||
connection.close()
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def client(db: Session) -> Generator[TestClient, None, None]:
|
||||
"""FastAPI 測試客戶端"""
|
||||
|
||||
def override_get_db():
|
||||
yield db
|
||||
|
||||
app.dependency_overrides[get_db] = override_get_db
|
||||
|
||||
with TestClient(app) as c:
|
||||
yield c
|
||||
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_department(db: Session) -> Department:
|
||||
"""建立測試部門"""
|
||||
dept = Department(
|
||||
code="TEST_DEPT",
|
||||
name="測試部門",
|
||||
level="DEPT",
|
||||
is_active=True,
|
||||
)
|
||||
db.add(dept)
|
||||
db.flush()
|
||||
return dept
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_employee(db: Session, test_department: Department) -> Employee:
|
||||
"""建立測試員工"""
|
||||
employee = Employee(
|
||||
employee_no="TEST001",
|
||||
name="測試員工",
|
||||
email="test@example.com",
|
||||
password_hash=get_password_hash("password123"),
|
||||
department_id=test_department.id,
|
||||
job_title="工程師",
|
||||
role="employee",
|
||||
status="active",
|
||||
)
|
||||
db.add(employee)
|
||||
db.flush()
|
||||
return employee
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_manager(db: Session, test_department: Department) -> Employee:
|
||||
"""建立測試主管"""
|
||||
manager = Employee(
|
||||
employee_no="MGR001",
|
||||
name="測試主管",
|
||||
email="manager@example.com",
|
||||
password_hash=get_password_hash("password123"),
|
||||
department_id=test_department.id,
|
||||
job_title="經理",
|
||||
role="manager",
|
||||
status="active",
|
||||
)
|
||||
db.add(manager)
|
||||
db.flush()
|
||||
return manager
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def auth_headers(test_employee: Employee) -> dict:
|
||||
"""取得認證 Headers"""
|
||||
token = create_access_token({"sub": str(test_employee.id)})
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def manager_headers(test_manager: Employee) -> dict:
|
||||
"""取得主管認證 Headers"""
|
||||
token = create_access_token({"sub": str(test_manager.id)})
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
Reference in New Issue
Block a user