Files
ebook-extension/ebook_backend&admin_panel/admin-backend/tests/conftest.py

168 lines
4.5 KiB
Python

import pytest
import os
import tempfile
import shutil
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
from unittest.mock import patch, MagicMock
# Import the app and models
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from main import app
from models.user import AdminUser
from models.coupon import Coupon
from utils.auth import Base, get_db, hash_password
from utils.template_loader import templates
# Test database configuration
TEST_DATABASE_URL = "sqlite:///:memory:"
@pytest.fixture(scope="session")
def test_engine():
"""Create test database engine"""
engine = create_engine(
TEST_DATABASE_URL,
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
return engine
@pytest.fixture(scope="session")
def test_session_factory(test_engine):
"""Create test session factory"""
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)
return TestingSessionLocal
@pytest.fixture(scope="session")
def test_db_setup(test_engine):
"""Create test database tables once for the session"""
Base.metadata.create_all(bind=test_engine)
yield
Base.metadata.drop_all(bind=test_engine)
@pytest.fixture(scope="function")
def test_db(test_engine, test_session_factory, test_db_setup):
"""Create test database session"""
# Create session
session = test_session_factory()
# Clear any existing data
for table in reversed(Base.metadata.sorted_tables):
session.execute(table.delete())
session.commit()
yield session
# Cleanup - rollback and close
session.rollback()
session.close()
@pytest.fixture(scope="function")
def client(test_db):
"""Create test client with database dependency override"""
def override_get_db():
try:
yield test_db
finally:
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 admin_user(test_db):
"""Create a test admin user"""
# Clear existing users first
test_db.query(AdminUser).delete()
test_db.commit()
user = AdminUser(
username="testadmin",
password_hash=hash_password("testpassword123")
)
test_db.add(user)
test_db.commit()
test_db.refresh(user)
return user
@pytest.fixture
def sample_coupons(test_db):
"""Create sample coupon codes for testing"""
# Clear existing coupons first
test_db.query(Coupon).delete()
test_db.commit()
coupons = []
codes = ["TEST123", "SAMPLE456", "DEMO789"]
for code in codes:
coupon = Coupon(code=code, usage_count=0)
test_db.add(coupon)
coupons.append(coupon)
test_db.commit()
for coupon in coupons:
test_db.refresh(coupon)
return coupons
@pytest.fixture
def used_coupon(test_db):
"""Create a used coupon for testing"""
from datetime import datetime
import pytz
# Clear existing coupons first
test_db.query(Coupon).delete()
test_db.commit()
coupon = Coupon(
code="USED123",
usage_count=1,
used_at=datetime.now(pytz.timezone('Asia/Kolkata'))
)
test_db.add(coupon)
test_db.commit()
test_db.refresh(coupon)
return coupon
@pytest.fixture
def temp_translation_dir():
"""Create temporary directory for translation files"""
temp_dir = tempfile.mkdtemp()
original_dir = os.path.join(os.path.dirname(__file__), '..', 'translationfile')
# Mock the translation directory path
with patch('routes.auth.TRANSLATION_DIR', temp_dir):
with patch('routes.auth.TRANSLATION_PATH', os.path.join(temp_dir, 'translation.xlsx')):
yield temp_dir
# Cleanup
shutil.rmtree(temp_dir, ignore_errors=True)
@pytest.fixture
def mock_templates():
"""Mock Jinja2 templates"""
mock_template = MagicMock()
mock_template.TemplateResponse.return_value = MagicMock()
with patch('routes.auth.templates', mock_template):
yield mock_template
@pytest.fixture
def auth_headers():
"""Return headers for authenticated requests"""
return {"Cookie": "admin_logged_in=true"}
@pytest.fixture
def mock_logger():
"""Mock logger to avoid file operations during tests"""
with patch('utils.logger.setup_logger') as mock:
mock.return_value = MagicMock()
yield mock