paper-dynasty-gameplay-webapp/tests/conftest.py
Cal Corum 559fe73f07 CLAUDE: Complete Player model migration with service layer and integration test infrastructure
## Player Model Migration
- Migrate Player model from Discord app following Model/Service Architecture pattern
- Extract all business logic from Player model to PlayerService
- Create pure data model with PostgreSQL relationships (Cardset, PositionRating)
- Implement comprehensive PlayerFactory with specialized methods for test data

## PlayerService Implementation
- Extract 5 business logic methods from original Player model:
  - get_batter_card_url() - batting card URL retrieval
  - get_pitcher_card_url() - pitching card URL retrieval
  - generate_name_card_link() - markdown link generation
  - get_formatted_name_with_description() - name formatting
  - get_player_description() - description from object or dict
- Follow BaseService pattern with dependency injection and logging

## Comprehensive Testing
- 35 passing Player tests (14 model + 21 service tests)
- PlayerFactory with specialized methods (batting/pitching cards, positions)
- Test isolation following factory pattern and db_session guidelines
- Fix PostgreSQL integer overflow in test ID generation

## Integration Test Infrastructure
- Create integration test framework for improving service coverage
- Design AIService integration tests targeting uncovered branches
- Demonstrate real database query testing with proper isolation
- Establish patterns for testing complex game scenarios

## Service Coverage Analysis
- Current service coverage: 61% overall
- PlayerService: 100% coverage (excellent migration example)
- AIService: 60% coverage (improvement opportunities identified)
- Integration test strategy designed to achieve 90%+ coverage

## Database Integration
- Update Cardset model to include players relationship
- Update PositionRating model with proper Player foreign key
- Maintain all existing relationships and constraints
- Demonstrate data isolation and automatic cleanup in tests

## Test Suite Status
- 137 tests passing, 0 failures (maintained 100% pass rate)
- Added 35 new tests while preserving all existing functionality
- Integration test infrastructure ready for coverage improvements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 16:20:29 -05:00

79 lines
2.3 KiB
Python

"""
Shared pytest fixtures for Paper Dynasty web app testing.
Provides database sessions, test data factories, and common testing utilities
following the transaction rollback pattern for test isolation.
"""
import pytest
from sqlmodel import Session, SQLModel, create_engine
from uuid import uuid4
# Test Database Configuration
TEST_DATABASE_URL = "postgresql://paper_dynasty_user:paper_dynasty_test_password@localhost:5434/paper_dynasty_test"
@pytest.fixture(scope="session")
def test_engine():
"""Create test database engine for the entire test session."""
engine = create_engine(TEST_DATABASE_URL, echo=False)
# Create all tables
SQLModel.metadata.create_all(engine)
yield engine
# Optional: Drop all tables after test session
# SQLModel.metadata.drop_all(engine)
@pytest.fixture
def db_session(test_engine):
"""
Create database session with transaction rollback for test isolation.
This is the primary fixture for database tests. Each test runs in a
transaction that is rolled back after the test completes, ensuring
complete isolation between tests.
"""
# Create a connection and start a transaction
connection = test_engine.connect()
transaction = connection.begin()
# Create session bound to the connection
session = Session(bind=connection)
try:
yield session
finally:
# Close session and rollback transaction
session.close()
transaction.rollback()
connection.close()
@pytest.fixture
def fresh_db_session(test_engine):
"""
Create database session for integration tests that need real commits.
Use this fixture for tests that specifically need to test commit behavior
or cross-transaction functionality. Use sparingly as these tests are slower
and require manual cleanup.
"""
with Session(test_engine) as session:
yield session
# Manual cleanup would go here if needed
def generate_unique_id():
"""Generate unique integer ID for test data."""
# Use last 6 digits of uuid4 as integer to avoid PostgreSQL integer overflow
# This gives us numbers up to ~16 million, well under PostgreSQL's 2.1 billion limit
return int(str(uuid4()).replace('-', '')[-6:], 16)
def generate_unique_name(prefix="Test"):
"""Generate unique name for test data."""
return f"{prefix} {uuid4().hex[:8]}"