""" Tests for StaticItemLoader service. Tests the service that loads predefined items (consumables, materials) from YAML files for use in loot tables. """ import pytest from pathlib import Path from app.services.static_item_loader import StaticItemLoader, get_static_item_loader from app.models.enums import ItemType, ItemRarity class TestStaticItemLoaderInitialization: """Test service initialization.""" def test_init_with_default_path(self): """Service should initialize with default data path.""" loader = StaticItemLoader() assert loader.data_dir.exists() or not loader._loaded def test_init_with_custom_path(self, tmp_path): """Service should accept custom data path.""" loader = StaticItemLoader(data_dir=str(tmp_path)) assert loader.data_dir == tmp_path def test_singleton_returns_same_instance(self): """get_static_item_loader should return singleton.""" loader1 = get_static_item_loader() loader2 = get_static_item_loader() assert loader1 is loader2 class TestStaticItemLoaderLoading: """Test YAML loading functionality.""" def test_loads_consumables(self): """Should load consumable items from YAML.""" loader = get_static_item_loader() # Check that health potion exists assert loader.has_item("health_potion_small") assert loader.has_item("health_potion_medium") def test_loads_materials(self): """Should load material items from YAML.""" loader = get_static_item_loader() # Check that materials exist assert loader.has_item("goblin_ear") assert loader.has_item("wolf_pelt") def test_get_all_item_ids_returns_list(self): """get_all_item_ids should return list of item IDs.""" loader = get_static_item_loader() item_ids = loader.get_all_item_ids() assert isinstance(item_ids, list) assert len(item_ids) > 0 assert "health_potion_small" in item_ids def test_has_item_returns_false_for_missing(self): """has_item should return False for non-existent items.""" loader = get_static_item_loader() assert not loader.has_item("nonexistent_item_xyz") class TestStaticItemLoaderGetItem: """Test item retrieval.""" def test_get_item_returns_item_object(self): """get_item should return an Item instance.""" loader = get_static_item_loader() item = loader.get_item("health_potion_small") assert item is not None assert item.name == "Small Health Potion" assert item.item_type == ItemType.CONSUMABLE assert item.rarity == ItemRarity.COMMON def test_get_item_has_unique_id(self): """Each call should create item with unique ID.""" loader = get_static_item_loader() item1 = loader.get_item("health_potion_small") item2 = loader.get_item("health_potion_small") assert item1.item_id != item2.item_id assert "health_potion_small" in item1.item_id assert "health_potion_small" in item2.item_id def test_get_item_returns_none_for_missing(self): """get_item should return None for non-existent items.""" loader = get_static_item_loader() item = loader.get_item("nonexistent_item_xyz") assert item is None def test_get_item_consumable_has_effects(self): """Consumable items should have effects_on_use.""" loader = get_static_item_loader() item = loader.get_item("health_potion_small") assert len(item.effects_on_use) > 0 effect = item.effects_on_use[0] assert effect.name == "Minor Healing" assert effect.power > 0 def test_get_item_quest_item_type(self): """Quest items should have correct type.""" loader = get_static_item_loader() item = loader.get_item("goblin_ear") assert item is not None assert item.item_type == ItemType.QUEST_ITEM assert item.rarity == ItemRarity.COMMON def test_get_item_has_value(self): """Items should have value set.""" loader = get_static_item_loader() item = loader.get_item("health_potion_small") assert item.value > 0 def test_get_item_is_tradeable(self): """Items should default to tradeable.""" loader = get_static_item_loader() item = loader.get_item("goblin_ear") assert item.is_tradeable is True class TestStaticItemLoaderVariousItems: """Test loading various item types.""" def test_medium_health_potion(self): """Test medium health potion properties.""" loader = get_static_item_loader() item = loader.get_item("health_potion_medium") assert item is not None assert item.rarity == ItemRarity.UNCOMMON assert item.value > 25 # More expensive than small def test_large_health_potion(self): """Test large health potion properties.""" loader = get_static_item_loader() item = loader.get_item("health_potion_large") assert item is not None assert item.rarity == ItemRarity.RARE def test_chieftain_token_rarity(self): """Test that chieftain token is rare.""" loader = get_static_item_loader() item = loader.get_item("goblin_chieftain_token") assert item is not None assert item.rarity == ItemRarity.RARE def test_elixir_has_buff_effect(self): """Test that elixirs have buff effects.""" loader = get_static_item_loader() item = loader.get_item("elixir_of_strength") if item: # Only test if item exists assert len(item.effects_on_use) > 0 class TestStaticItemLoaderCache: """Test caching behavior.""" def test_clear_cache(self): """clear_cache should reset loaded state.""" loader = StaticItemLoader() # Trigger loading loader._ensure_loaded() assert loader._loaded is True # Clear cache loader.clear_cache() assert loader._loaded is False assert len(loader._cache) == 0 def test_lazy_loading(self): """Items should be loaded lazily on first access.""" loader = StaticItemLoader() assert loader._loaded is False # Access triggers loading _ = loader.has_item("health_potion_small") assert loader._loaded is True