Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart with Orion/orion/ORION across 184 files. This includes database identifiers, email addresses, domain references, R2 bucket names, DNS prefixes, encryption salt, Celery app name, config defaults, Docker configs, CI configs, documentation, seed data, and templates. Renames homepage-wizamart.html template to homepage-orion.html. Fixes duplicate file_pattern key in api.yaml architecture rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
181 lines
5.6 KiB
Python
181 lines
5.6 KiB
Python
# conftest.py - PostgreSQL test configuration (project root)
|
|
"""
|
|
Core pytest configuration and fixtures.
|
|
|
|
This project uses PostgreSQL for testing. Start the test database with:
|
|
make test-db-up
|
|
|
|
IMPORTANT - Fixture Best Practices:
|
|
===================================
|
|
1. DO NOT use db.expunge() on fixtures - it detaches objects from the session
|
|
and breaks lazy loading of relationships (e.g., product.marketplace_product).
|
|
|
|
2. Test isolation is achieved through TRUNCATE CASCADE after each test,
|
|
which is much faster than dropping/recreating tables.
|
|
|
|
3. If you need to ensure an object has fresh data, use db.refresh(obj) instead
|
|
of expunge/re-query patterns.
|
|
|
|
4. The session uses expire_on_commit=False to prevent objects from being expired
|
|
after commits, which helps with relationship access across operations.
|
|
|
|
See docs/testing/testing-guide.md for comprehensive testing documentation.
|
|
"""
|
|
|
|
import os
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import create_engine, text
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from app.core.database import Base, get_db
|
|
from main import app
|
|
|
|
# PostgreSQL test database URL
|
|
# Use environment variable or default to local Docker test database
|
|
TEST_DATABASE_URL = os.getenv(
|
|
"TEST_DATABASE_URL",
|
|
"postgresql://test_user:test_password@localhost:5433/orion_test"
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def engine():
|
|
"""Create test database engine.
|
|
|
|
Verifies PostgreSQL connection on startup and provides helpful
|
|
error message if the test database is not running.
|
|
"""
|
|
engine = create_engine(
|
|
TEST_DATABASE_URL,
|
|
pool_pre_ping=True,
|
|
echo=False, # Set to True for SQL debugging
|
|
)
|
|
|
|
# Verify connection on startup
|
|
try:
|
|
with engine.connect() as conn:
|
|
conn.execute(text("SELECT 1"))
|
|
except Exception as e:
|
|
pytest.exit(
|
|
f"\n\nCannot connect to test database at {TEST_DATABASE_URL}\n"
|
|
f"Error: {e}\n\n"
|
|
"Start the test database with:\n"
|
|
" make test-db-up\n\n"
|
|
"Or manually:\n"
|
|
" docker-compose -f docker-compose.test.yml up -d\n"
|
|
)
|
|
|
|
return engine
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def testing_session_local(engine):
|
|
"""
|
|
Create session factory for tests.
|
|
|
|
Uses expire_on_commit=False to prevent objects from being expired after
|
|
commits. This allows fixtures to remain usable after database operations
|
|
without needing to refresh or re-query them.
|
|
"""
|
|
return sessionmaker(
|
|
autocommit=False,
|
|
autoflush=False,
|
|
bind=engine,
|
|
expire_on_commit=False, # Prevents lazy-load issues after commits
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def setup_database(engine):
|
|
"""Create all tables once at the start of the test session."""
|
|
with engine.connect() as conn:
|
|
# Terminate any other connections to avoid deadlocks
|
|
conn.execute(text("""
|
|
SELECT pg_terminate_backend(pid)
|
|
FROM pg_stat_activity
|
|
WHERE datname = current_database() AND pid <> pg_backend_pid()
|
|
"""))
|
|
conn.execute(text("DROP SCHEMA public CASCADE"))
|
|
conn.execute(text("CREATE SCHEMA public"))
|
|
conn.commit()
|
|
Base.metadata.create_all(bind=engine)
|
|
yield
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def db(engine, testing_session_local):
|
|
"""
|
|
Create a database session for each test function.
|
|
|
|
Provides test isolation by:
|
|
- Using a fresh session for each test
|
|
- Truncating all tables after each test (fast cleanup)
|
|
|
|
Note: Fixtures should NOT use db.expunge() as this detaches objects
|
|
from the session and breaks lazy loading. The TRUNCATE provides
|
|
sufficient isolation between tests.
|
|
"""
|
|
db_session = testing_session_local()
|
|
|
|
try:
|
|
yield db_session
|
|
finally:
|
|
db_session.close()
|
|
# Fast cleanup with TRUNCATE CASCADE
|
|
with engine.connect() as conn:
|
|
# Disable FK checks temporarily for fast truncation
|
|
conn.execute(text("SET session_replication_role = 'replica'"))
|
|
for table in reversed(Base.metadata.sorted_tables):
|
|
conn.execute(text(f'TRUNCATE TABLE "{table.name}" CASCADE'))
|
|
conn.execute(text("SET session_replication_role = 'origin'"))
|
|
conn.commit()
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def client(db):
|
|
"""Create a test client with database dependency override"""
|
|
|
|
# Override the dependency to use our test database
|
|
def override_get_db():
|
|
try:
|
|
yield db
|
|
finally:
|
|
pass # Don't close here, the db fixture handles it
|
|
|
|
app.dependency_overrides[get_db] = override_get_db
|
|
|
|
try:
|
|
client = TestClient(app)
|
|
yield client
|
|
finally:
|
|
# Clean up the dependency override
|
|
if get_db in app.dependency_overrides:
|
|
del app.dependency_overrides[get_db]
|
|
|
|
|
|
# Cleanup fixture to ensure clean state
|
|
@pytest.fixture(autouse=True)
|
|
def cleanup():
|
|
"""Automatically clean up after each test"""
|
|
yield
|
|
# Clear any remaining dependency overrides
|
|
app.dependency_overrides.clear()
|
|
|
|
|
|
# Import fixtures from fixture modules
|
|
pytest_plugins = [
|
|
"tests.fixtures.admin_platform_fixtures",
|
|
"tests.fixtures.auth_fixtures",
|
|
"tests.fixtures.loyalty_fixtures",
|
|
"tests.fixtures.marketplace_product_fixtures",
|
|
"tests.fixtures.store_fixtures",
|
|
"tests.fixtures.customer_fixtures",
|
|
"tests.fixtures.marketplace_import_job_fixtures",
|
|
"tests.fixtures.message_fixtures",
|
|
"tests.fixtures.testing_fixtures",
|
|
"tests.fixtures.content_page_fixtures",
|
|
"tests.fixtures.merchant_domain_fixtures",
|
|
]
|