Files
OCR/backend/tests/conftest.py
egg 6bb5b7691f test: fix all failing tests - achieve 100% pass rate (18/18)
Root Cause Fixed:
- Tests were connecting to production MySQL database instead of test database
- Solution: Monkey patch database module before importing app to use SQLite :memory:

Changes:
1. **conftest.py** - Critical Fix:
   - Added database module monkey patch BEFORE app import
   - Prevents connection to production database (db_A060)
   - All tests now use isolated SQLite :memory: database
   - Fixed fixture dependency order (test_task depends on test_user)

2. **test_tasks.py**:
   - Fixed test_delete_task: Accept 204 No Content (correct HTTP status)

3. **test_admin.py**:
   - Fixed test_get_system_stats: Update assertions to match nested API response structure
   - API returns {users: {total}, tasks: {total}} not flat structure

4. **test_integration.py**:
   - Fixed mock structure: Use Pydantic models (AuthResponse, UserInfo) instead of dicts
   - Fixed test_complete_auth_and_task_flow: Accept 204 for DELETE

Test Results:
 test_auth.py: 5/5 passing (100%)
 test_tasks.py: 6/6 passing (100%)
 test_admin.py: 4/4 passing (100%)
 test_integration.py: 3/3 passing (100%)

Total: 18/18 tests passing (100%) ⬆️ from 11/18 (61%)

Security Note:
- Tests no longer access production database
- All test data is isolated in :memory: SQLite

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 18:39:10 +08:00

139 lines
3.7 KiB
Python

"""
V2 API Test Configuration and Fixtures
Provides test fixtures for authentication, database, and API testing
"""
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
# IMPORTANT: Monkey patch database module BEFORE importing app
# This prevents the app from connecting to production database
import app.core.database as db_module
# Create a test engine for the entire test session
_test_engine = create_engine(
"sqlite:///:memory:",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
# Replace the global engine and SessionLocal
db_module.engine = _test_engine
db_module.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=_test_engine)
# Now safely import app (it will use our test database)
from app.main import app
from app.core.database import Base, get_db
from app.core.security import create_access_token
from app.models.user import User
from app.models.task import Task
@pytest.fixture(scope="function")
def engine():
"""Get test database engine and reset tables for each test"""
Base.metadata.drop_all(bind=_test_engine)
Base.metadata.create_all(bind=_test_engine)
yield _test_engine
# Tables will be dropped at the start of next test
@pytest.fixture(scope="function")
def db(engine):
"""Create test database session"""
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
@pytest.fixture(scope="function")
def client(db):
"""Create FastAPI test client with test database"""
# Override get_db to use the same session as the test
def override_get_db():
try:
yield db
finally:
# Don't close the session, it's managed by the db fixture
pass
app.dependency_overrides[get_db] = override_get_db
with TestClient(app) as test_client:
yield test_client
app.dependency_overrides.clear()
@pytest.fixture
def test_user(db):
"""Create a test user"""
# Ensure test_user is always created first by checking if it exists
user = db.query(User).filter(User.email == "test@example.com").first()
if not user:
user = User(
email="test@example.com",
display_name="Test User",
is_active=True
)
db.add(user)
db.commit()
db.refresh(user)
return user
@pytest.fixture
def admin_user(db):
"""Create an admin user"""
user = db.query(User).filter(User.email == "ymirliu@panjit.com.tw").first()
if not user:
user = User(
email="ymirliu@panjit.com.tw",
display_name="Admin User",
is_active=True
)
db.add(user)
db.commit()
db.refresh(user)
return user
@pytest.fixture
def auth_token(test_user):
"""Create authentication token for test user"""
token_data = {
"sub": str(test_user.id),
"email": test_user.email
}
return create_access_token(token_data)
@pytest.fixture
def admin_token(admin_user):
"""Create authentication token for admin user"""
token_data = {
"sub": str(admin_user.id),
"email": admin_user.email
}
return create_access_token(token_data)
@pytest.fixture
def test_task(test_user, db):
"""Create a test task (depends on test_user to ensure user exists first)"""
task = Task(
user_id=test_user.id,
task_id="test-task-123",
filename="test.pdf",
file_type="application/pdf",
status="pending"
)
db.add(task)
db.commit()
db.refresh(task)
return task