## 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>
79 lines
2.3 KiB
Python
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]}" |