paper-dynasty-gameplay-webapp/tests/unit/models/test_cardset.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

243 lines
8.6 KiB
Python

"""
Unit tests for Cardset model.
Tests data validation, field constraints, and model behavior.
"""
import pytest
from pydantic import ValidationError
from sqlmodel import Session, SQLModel, create_engine, text
from app.models.cardset import Cardset, CardsetBase
from tests.factories.cardset_factory import CardsetFactory
# Using centralized fixtures from conftest.py for proper test isolation
class TestCardsetBase:
"""Test CardsetBase model validation."""
def test_create_with_defaults(self):
"""Test creating Cardset with default values."""
cardset = CardsetBase(name="2024 Season")
assert cardset.name == "2024 Season"
assert cardset.ranked_legal is False # Default value
def test_create_with_custom_values(self):
"""Test creating Cardset with custom values."""
cardset = CardsetBase(
name="2023 Season",
ranked_legal=True
)
assert cardset.name == "2023 Season"
assert cardset.ranked_legal is True
def test_create_with_id(self):
"""Test creating Cardset with explicit ID."""
cardset = CardsetBase(
id=100,
name="Historic Set",
ranked_legal=False
)
assert cardset.id == 100
assert cardset.name == "Historic Set"
assert cardset.ranked_legal is False
def test_required_name_field(self):
"""Test that name field is required."""
with pytest.raises(ValidationError) as exc_info:
CardsetBase()
assert "Field required" in str(exc_info.value)
def test_field_descriptions(self):
"""Test that field descriptions are properly set."""
# Access field descriptions through the model class using Pydantic v2
fields = CardsetBase.model_fields
assert "Name of the card set" in str(fields['name'])
assert "Whether this cardset is legal for ranked play" in str(fields['ranked_legal'])
class TestCardset:
"""Test Cardset table model."""
def test_create_and_save(self, db_session):
"""Test creating and saving Cardset to database."""
cardset = CardsetFactory.create(
db_session,
name="2024 Season",
ranked_legal=True
)
assert cardset.id is not None
assert cardset.name == "2024 Season"
assert cardset.ranked_legal is True
def test_retrieve_from_database(self, db_session):
"""Test retrieving Cardset from database."""
# Create and save
cardset = CardsetFactory.create(
db_session,
name="Test Retrieval Set",
ranked_legal=False
)
# Retrieve
retrieved = db_session.get(Cardset, cardset.id)
assert retrieved is not None
assert retrieved.name == "Test Retrieval Set"
assert retrieved.ranked_legal is False
def test_update_values(self, db_session):
"""Test updating Cardset values."""
cardset = Cardset(id=3, name="Update Test")
db_session.add(cardset)
db_session.commit()
# Update values
cardset.ranked_legal = True
cardset.name = "Updated Name"
db_session.commit()
# Verify updates
db_session.refresh(cardset)
assert cardset.name == "Updated Name"
assert cardset.ranked_legal is True
def test_multiple_instances(self, db_session):
"""Test creating multiple Cardset instances."""
cardset1 = Cardset(id=10, name="Set A", ranked_legal=True)
cardset2 = Cardset(id=11, name="Set B", ranked_legal=False)
cardset3 = Cardset(id=12, name="Set C", ranked_legal=True)
db_session.add_all([cardset1, cardset2, cardset3])
db_session.commit()
# Verify all saved with correct values
assert cardset1.name == "Set A"
assert cardset1.ranked_legal is True
assert cardset2.name == "Set B"
assert cardset2.ranked_legal is False
assert cardset3.name == "Set C"
assert cardset3.ranked_legal is True
def test_name_is_indexed(self):
"""Test that name field has index configuration."""
fields = Cardset.model_fields
name_field = fields['name']
# Check if field has index configuration
assert hasattr(name_field, 'json_schema_extra') or 'index' in str(name_field)
class TestCardsetBusinessScenarios:
"""Test real-world Cardset usage scenarios."""
def test_ranked_legal_cardsets(self, db_session):
"""Test filtering for ranked legal cardsets."""
# Create multiple cardsets using factory
ranked_set = CardsetFactory.create(db_session, name="2024 Ranked", ranked_legal=True)
casual_set = CardsetFactory.create(db_session, name="2024 Casual", ranked_legal=False)
historic_set = CardsetFactory.create(db_session, name="Historic Collection", ranked_legal=False)
# Query for ranked legal sets (would be done in service layer)
from sqlmodel import select
ranked_cardsets = db_session.exec(
select(Cardset).where(Cardset.ranked_legal == True)
).all()
assert len(ranked_cardsets) == 1
assert ranked_cardsets[0].name == "2024 Ranked"
def test_cardset_naming_conventions(self, db_session):
"""Test various cardset naming scenarios."""
cardsets = [
Cardset(id=30, name="2024 Season", ranked_legal=True),
Cardset(id=31, name="2023 Season", ranked_legal=False),
Cardset(id=32, name="Historic Collection", ranked_legal=False),
Cardset(id=33, name="Special Event - All-Stars", ranked_legal=True),
Cardset(id=34, name="Beta Test Set", ranked_legal=False),
]
db_session.add_all(cardsets)
db_session.commit()
# Verify all names are preserved correctly
for cardset in cardsets:
db_session.refresh(cardset)
# Names should be preserved exactly as entered
assert len(cardset.name) > 0
assert cardset.name in [
"2024 Season", "2023 Season", "Historic Collection",
"Special Event - All-Stars", "Beta Test Set"
]
def test_default_ranked_legal_behavior(self, db_session):
"""Test that cardsets default to not ranked legal."""
cardset = Cardset(id=40, name="Default Test")
db_session.add(cardset)
db_session.commit()
db_session.refresh(cardset)
# Should default to False
assert cardset.ranked_legal is False
def test_explicit_id_assignment(self, db_session):
"""Test that IDs can be explicitly assigned (not auto-increment)."""
# Based on Discord app model, ID is not auto-increment
cardset1 = Cardset(id=1000, name="High ID Set")
cardset2 = Cardset(id=2000, name="Another High ID Set")
db_session.add_all([cardset1, cardset2])
db_session.commit()
assert cardset1.id == 1000
assert cardset2.id == 2000
def test_unique_id_constraint(self, db_session):
"""Test that duplicate IDs are not allowed."""
cardset1 = Cardset(id=500, name="First Set")
cardset2 = Cardset(id=500, name="Duplicate ID Set")
db_session.add(cardset1)
db_session.commit()
# Adding second cardset with same ID should fail
db_session.add(cardset2)
with pytest.raises(Exception): # SQLAlchemy will raise an IntegrityError
db_session.commit()
class TestCardsetDataIntegrity:
"""Test data integrity and validation."""
def test_empty_name_not_allowed(self):
"""Test that empty name is not allowed."""
with pytest.raises(ValidationError):
CardsetBase(name="")
def test_none_name_not_allowed(self):
"""Test that None name is not allowed."""
with pytest.raises(ValidationError):
CardsetBase(name=None)
def test_boolean_validation_for_ranked_legal(self):
"""Test that ranked_legal field only accepts boolean values."""
# Valid boolean values
cardset_true = CardsetBase(name="Test", ranked_legal=True)
cardset_false = CardsetBase(name="Test", ranked_legal=False)
assert cardset_true.ranked_legal is True
assert cardset_false.ranked_legal is False
# Invalid values should be coerced or raise validation error
with pytest.raises(ValidationError):
CardsetBase(name="Test", ranked_legal="invalid")
def test_id_field_accepts_none(self):
"""Test that ID field can be None (for cases where ID isn't known yet)."""
cardset = CardsetBase(name="No ID Set", id=None)
assert cardset.id is None
assert cardset.name == "No ID Set"