paper-dynasty-gameplay-webapp/tests/factories/manager_ai_factory.py
Cal Corum 1c24161e76 CLAUDE: Achieve 100% test pass rate with comprehensive AI service testing
- Fix TypeError in check_steal_opportunity by properly mocking catcher defense
- Correct tag_from_third test calculation to account for all adjustment conditions
- Fix pitcher replacement test by setting appropriate allowed runners threshold
- Add comprehensive test coverage for AI service business logic
- Implement VS Code testing panel configuration with pytest integration
- Create pytest.ini for consistent test execution and warning management
- Add test isolation guidelines and factory pattern implementation
- Establish 102 passing tests with zero failures

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-28 17:55:34 -05:00

154 lines
4.3 KiB
Python

"""
ManagerAi factory for generating test data.
Provides methods to create unique, valid ManagerAi instances for testing
without conflicts between test runs.
"""
from app.models.manager_ai import ManagerAi
from tests.conftest import generate_unique_name
class ManagerAiFactory:
"""Factory for creating ManagerAi test instances."""
@staticmethod
def build(**kwargs):
"""
Build a ManagerAi instance without saving to database.
Args:
**kwargs: Override default field values
Returns:
ManagerAi: Configured manager AI instance
Example:
ai = ManagerAiFactory.build(name="Test AI")
ai = ManagerAiFactory.build(steal=10, running=8)
"""
defaults = {
'name': generate_unique_name("AI Manager"),
'steal': 5,
'running': 5,
'hold': 5,
'catcher_throw': 5,
'uncapped_home': 5,
'uncapped_third': 5,
'uncapped_trail': 5,
'bullpen_matchup': 5,
'behind_aggression': 5,
'ahead_aggression': 5,
'decide_throw': 5
}
defaults.update(kwargs)
return ManagerAi(**defaults)
@classmethod
def create(cls, session, **kwargs):
"""
Create and save a ManagerAi instance to database.
Args:
session: Database session
**kwargs: Override default field values
Returns:
ManagerAi: Saved manager AI instance
Example:
ai = ManagerAiFactory.create(session, steal=10)
"""
ai = cls.build(**kwargs)
session.add(ai)
session.flush() # Get ID without committing
return ai
@classmethod
def build_batch(cls, count, **kwargs):
"""
Build multiple ManagerAi instances.
Args:
count: Number of AIs to create
**kwargs: Common field values for all AIs
Returns:
list[ManagerAi]: List of AI instances
Example:
ais = ManagerAiFactory.build_batch(3, steal=8)
"""
return [cls.build(**kwargs) for _ in range(count)]
@classmethod
def create_batch(cls, session, count, **kwargs):
"""
Create and save multiple ManagerAi instances.
Args:
session: Database session
count: Number of AIs to create
**kwargs: Common field values for all AIs
Returns:
list[ManagerAi]: List of saved AI instances
Example:
ais = ManagerAiFactory.create_batch(session, 3, steal=8)
"""
ais = cls.build_batch(count, **kwargs)
session.add_all(ais)
session.flush()
return ais
# Preset factories for common AI configurations
@classmethod
def build_balanced(cls, **kwargs):
"""Build a balanced AI (all 5s)."""
defaults = {
'name': generate_unique_name("Balanced AI"),
# All defaults are already 5
}
defaults.update(kwargs)
return cls.build(**defaults)
@classmethod
def build_aggressive(cls, **kwargs):
"""Build an aggressive AI (YOLO preset)."""
defaults = {
'name': generate_unique_name("Aggressive AI"),
'steal': 10,
'running': 10,
'hold': 5,
'catcher_throw': 10,
'uncapped_home': 10,
'uncapped_third': 10,
'uncapped_trail': 10,
'bullpen_matchup': 3,
'behind_aggression': 10,
'ahead_aggression': 10,
'decide_throw': 10
}
defaults.update(kwargs)
return cls.build(**defaults)
@classmethod
def build_conservative(cls, **kwargs):
"""Build a conservative AI (Safe preset)."""
defaults = {
'name': generate_unique_name("Conservative AI"),
'steal': 3,
'running': 3,
'hold': 8,
'catcher_throw': 5,
'uncapped_home': 5,
'uncapped_third': 3,
'uncapped_trail': 5,
'bullpen_matchup': 8,
'behind_aggression': 5,
'ahead_aggression': 1,
'decide_throw': 1
}
defaults.update(kwargs)
return cls.build(**defaults)