- 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>
276 lines
9.5 KiB
Python
276 lines
9.5 KiB
Python
"""
|
|
Unit tests for Cardset model using proper testing patterns.
|
|
|
|
Tests data validation, field constraints, and model behavior with
|
|
transaction rollback for test isolation and factories for unique data.
|
|
"""
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
from sqlmodel import select
|
|
|
|
from app.models.cardset import Cardset, CardsetBase
|
|
from tests.factories import CardsetFactory
|
|
|
|
|
|
class TestCardsetBaseValidation:
|
|
"""Test CardsetBase model validation (no database needed)."""
|
|
|
|
def test_create_with_defaults(self):
|
|
"""Test creating Cardset with default values."""
|
|
cardset = CardsetFactory.build()
|
|
|
|
assert cardset.name.startswith("Cardset")
|
|
assert cardset.ranked_legal is False
|
|
assert cardset.id is not None
|
|
|
|
def test_create_with_custom_values(self):
|
|
"""Test creating Cardset with custom values."""
|
|
cardset = CardsetFactory.build(
|
|
name="Custom Season",
|
|
ranked_legal=True
|
|
)
|
|
|
|
assert cardset.name == "Custom Season"
|
|
assert cardset.ranked_legal is True
|
|
|
|
def test_create_with_explicit_id(self):
|
|
"""Test creating Cardset with explicit ID."""
|
|
cardset = CardsetFactory.build(
|
|
id=12345,
|
|
name="Specific ID Set"
|
|
)
|
|
|
|
assert cardset.id == 12345
|
|
assert cardset.name == "Specific ID Set"
|
|
|
|
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_empty_name_validation(self):
|
|
"""Test that empty name is not allowed."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
CardsetBase(name="")
|
|
assert "Name cannot be empty" in str(exc_info.value)
|
|
|
|
def test_whitespace_only_name_validation(self):
|
|
"""Test that whitespace-only name is not allowed."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
CardsetBase(name=" ")
|
|
assert "Name cannot be empty" in str(exc_info.value)
|
|
|
|
def test_none_name_not_allowed(self):
|
|
"""Test that None name is not allowed."""
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
CardsetBase(name=None)
|
|
assert "Input should be a valid string" in str(exc_info.value)
|
|
|
|
def test_boolean_validation_for_ranked_legal(self):
|
|
"""Test that ranked_legal field validates boolean values."""
|
|
# Valid boolean values
|
|
cardset_true = CardsetFactory.build(ranked_legal=True)
|
|
cardset_false = CardsetFactory.build(ranked_legal=False)
|
|
|
|
assert cardset_true.ranked_legal is True
|
|
assert cardset_false.ranked_legal is False
|
|
|
|
def test_field_descriptions(self):
|
|
"""Test that field descriptions are properly set."""
|
|
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'])
|
|
|
|
def test_id_field_accepts_none(self):
|
|
"""Test that ID field can be None."""
|
|
cardset = CardsetFactory.build(id=None)
|
|
assert cardset.id is None
|
|
|
|
|
|
class TestCardsetDatabaseOperations:
|
|
"""Test Cardset database operations with transaction rollback."""
|
|
|
|
def test_create_and_save(self, db_session):
|
|
"""Test creating and saving Cardset to database."""
|
|
cardset = CardsetFactory.create(
|
|
db_session,
|
|
name="Database Test Set",
|
|
ranked_legal=True
|
|
)
|
|
|
|
assert cardset.id is not None
|
|
assert cardset.name == "Database Test Set"
|
|
assert cardset.ranked_legal is True
|
|
|
|
def test_retrieve_from_database(self, db_session):
|
|
"""Test retrieving Cardset from database."""
|
|
# Create and save
|
|
original = CardsetFactory.create(
|
|
db_session,
|
|
name="Retrieval Test",
|
|
ranked_legal=False
|
|
)
|
|
|
|
# Retrieve by ID
|
|
retrieved = db_session.get(Cardset, original.id)
|
|
assert retrieved is not None
|
|
assert retrieved.name == "Retrieval Test"
|
|
assert retrieved.ranked_legal is False
|
|
assert retrieved.id == original.id
|
|
|
|
def test_update_values(self, db_session):
|
|
"""Test updating Cardset values."""
|
|
cardset = CardsetFactory.create(db_session, name="Update Test")
|
|
|
|
# Update values
|
|
cardset.ranked_legal = True
|
|
cardset.name = "Updated Name"
|
|
db_session.flush()
|
|
|
|
# Verify updates (no commit needed due to rollback)
|
|
assert cardset.name == "Updated Name"
|
|
assert cardset.ranked_legal is True
|
|
|
|
def test_multiple_instances(self, db_session):
|
|
"""Test creating multiple Cardset instances."""
|
|
cardsets = CardsetFactory.create_batch(
|
|
db_session, 3,
|
|
ranked_legal=True
|
|
)
|
|
|
|
# Verify all saved with unique IDs
|
|
ids = [c.id for c in cardsets]
|
|
assert len(set(ids)) == 3 # All IDs are unique
|
|
assert all(c.ranked_legal is True for c in cardsets)
|
|
|
|
def test_query_operations(self, db_session):
|
|
"""Test querying Cardset records."""
|
|
# Create test data
|
|
ranked_sets = CardsetFactory.create_batch(
|
|
db_session, 2,
|
|
ranked_legal=True
|
|
)
|
|
casual_sets = CardsetFactory.create_batch(
|
|
db_session, 3,
|
|
ranked_legal=False
|
|
)
|
|
|
|
# Query for ranked legal sets
|
|
ranked_results = db_session.exec(
|
|
select(Cardset).where(Cardset.ranked_legal == True)
|
|
).all()
|
|
|
|
# Query for casual sets
|
|
casual_results = db_session.exec(
|
|
select(Cardset).where(Cardset.ranked_legal == False)
|
|
).all()
|
|
|
|
assert len(ranked_results) == 2
|
|
assert len(casual_results) == 3
|
|
assert all(c.ranked_legal is True for c in ranked_results)
|
|
assert all(c.ranked_legal is False for c in casual_results)
|
|
|
|
|
|
class TestCardsetFactoryPresets:
|
|
"""Test CardsetFactory preset methods."""
|
|
|
|
def test_ranked_legal_preset(self, db_session):
|
|
"""Test ranked legal cardset factory."""
|
|
cardset = CardsetFactory.build_ranked_legal()
|
|
|
|
assert cardset.ranked_legal is True
|
|
assert "Ranked Set" in cardset.name
|
|
|
|
def test_casual_preset(self, db_session):
|
|
"""Test casual cardset factory."""
|
|
cardset = CardsetFactory.build_casual()
|
|
|
|
assert cardset.ranked_legal is False
|
|
assert "Casual Set" in cardset.name
|
|
|
|
def test_historic_preset(self, db_session):
|
|
"""Test historic cardset factory."""
|
|
cardset = CardsetFactory.build_historic()
|
|
|
|
assert cardset.ranked_legal is False
|
|
assert "Historic Set" in cardset.name
|
|
|
|
def test_custom_preset_override(self, db_session):
|
|
"""Test that preset defaults can be overridden."""
|
|
cardset = CardsetFactory.build_ranked_legal(
|
|
name="Custom Ranked Set",
|
|
ranked_legal=False # Override the preset
|
|
)
|
|
|
|
assert cardset.name == "Custom Ranked Set"
|
|
assert cardset.ranked_legal is False
|
|
|
|
|
|
class TestCardsetBusinessScenarios:
|
|
"""Test real-world Cardset usage scenarios."""
|
|
|
|
def test_unique_naming_across_tests(self, db_session):
|
|
"""Test that each test gets unique cardset names."""
|
|
cardset1 = CardsetFactory.create(db_session)
|
|
cardset2 = CardsetFactory.create(db_session)
|
|
|
|
# Names should be different due to unique generation
|
|
assert cardset1.name != cardset2.name
|
|
assert cardset1.id != cardset2.id
|
|
|
|
def test_batch_creation_uniqueness(self, db_session):
|
|
"""Test that batch creation produces unique items."""
|
|
cardsets = CardsetFactory.create_batch(db_session, 5)
|
|
|
|
# All should have unique IDs and names
|
|
ids = [c.id for c in cardsets]
|
|
names = [c.name for c in cardsets]
|
|
|
|
assert len(set(ids)) == 5 # All unique IDs
|
|
assert len(set(names)) == 5 # All unique names
|
|
|
|
def test_filtering_by_ranked_status(self, db_session):
|
|
"""Test filtering cardsets by ranked legal status."""
|
|
# Create mixed data
|
|
CardsetFactory.create_batch(db_session, 2, ranked_legal=True)
|
|
CardsetFactory.create_batch(db_session, 3, ranked_legal=False)
|
|
|
|
# Test filtering
|
|
all_cardsets = db_session.exec(select(Cardset)).all()
|
|
ranked_cardsets = db_session.exec(
|
|
select(Cardset).where(Cardset.ranked_legal == True)
|
|
).all()
|
|
casual_cardsets = db_session.exec(
|
|
select(Cardset).where(Cardset.ranked_legal == False)
|
|
).all()
|
|
|
|
assert len(all_cardsets) == 5
|
|
assert len(ranked_cardsets) == 2
|
|
assert len(casual_cardsets) == 3
|
|
|
|
def test_name_search_functionality(self, db_session):
|
|
"""Test searching cardsets by name patterns."""
|
|
# Create cardsets with specific names
|
|
season_sets = CardsetFactory.create_batch(
|
|
db_session, 2,
|
|
name="2024 Season"
|
|
)
|
|
historic_sets = CardsetFactory.create_batch(
|
|
db_session, 2,
|
|
name="Historic Collection"
|
|
)
|
|
|
|
# Search by name pattern
|
|
season_results = db_session.exec(
|
|
select(Cardset).where(Cardset.name.contains("Season"))
|
|
).all()
|
|
historic_results = db_session.exec(
|
|
select(Cardset).where(Cardset.name.contains("Historic"))
|
|
).all()
|
|
|
|
assert len(season_results) == 2
|
|
assert len(historic_results) == 2
|
|
assert all("Season" in c.name for c in season_results)
|
|
assert all("Historic" in c.name for c in historic_results) |