""" 共用測試 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}"}