""" Tests for recipe visibility in web UI. Bug found 2026-01-12: Recipes not showing in list even after upload. """ import pytest from pathlib import Path class TestRecipeListingFlow: """Tests for recipe listing data flow.""" def test_cache_manager_has_list_by_type(self) -> None: """L1CacheManager should have list_by_type method.""" # Read cache_manager.py and verify list_by_type exists path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() assert 'def list_by_type' in content, \ "L1CacheManager should have list_by_type method" def test_list_by_type_returns_node_id(self) -> None: """list_by_type should return entry.node_id values (IPFS CID).""" path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() # Find list_by_type function and verify it appends entry.node_id assert 'cids.append(entry.node_id)' in content, \ "list_by_type should append entry.node_id (IPFS CID) to results" def test_recipe_service_uses_database_items(self) -> None: """Recipe service should use database.get_user_items for listing.""" path = Path('/home/giles/art/art-celery/app/services/recipe_service.py') content = path.read_text() assert 'get_user_items' in content, \ "Recipe service should use database.get_user_items for listing" def test_recipe_upload_uses_recipe_node_type(self) -> None: """Recipe upload should store with node_type='recipe'.""" path = Path('/home/giles/art/art-celery/app/services/recipe_service.py') content = path.read_text() assert 'node_type="recipe"' in content, \ "Recipe upload should use node_type='recipe'" def test_get_by_cid_uses_find_by_cid(self) -> None: """get_by_cid should use cache.find_by_cid to locate entries.""" path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() # Verify get_by_cid uses find_by_cid assert 'find_by_cid(cid)' in content, \ "get_by_cid should use find_by_cid to locate entries" def test_no_duplicate_get_by_cid_methods(self) -> None: """ Regression test: There should only be ONE get_by_cid method. Bug: Two get_by_cid methods existed, the second shadowed the first, breaking recipe lookup because the comprehensive method was hidden. """ path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() # Count occurrences of 'def get_by_cid' count = content.count('def get_by_cid') assert count == 1, \ f"Should have exactly 1 get_by_cid method, found {count}" class TestRecipeFilterLogic: """Tests for recipe filtering logic via database.""" def test_recipes_filtered_by_actor_id(self) -> None: """list_recipes should filter by actor_id parameter.""" path = Path('/home/giles/art/art-celery/app/services/recipe_service.py') content = path.read_text() assert 'actor_id' in content, \ "list_recipes should accept actor_id parameter" def test_recipes_uses_item_type_filter(self) -> None: """list_recipes should filter by item_type='recipe'.""" path = Path('/home/giles/art/art-celery/app/services/recipe_service.py') content = path.read_text() assert 'item_type="recipe"' in content, \ "Recipe listing should filter by item_type='recipe'" class TestCacheEntryHasCid: """Tests for cache entry cid field.""" def test_artdag_cache_entry_has_cid(self) -> None: """artdag CacheEntry should have cid field.""" from artdag import CacheEntry import dataclasses fields = {f.name for f in dataclasses.fields(CacheEntry)} assert 'cid' in fields, \ "CacheEntry should have cid field" def test_artdag_cache_put_computes_cid(self) -> None: """artdag Cache.put should compute and store cid in metadata.""" from artdag import Cache import inspect source = inspect.getsource(Cache.put) assert '"cid":' in source or "'cid':" in source, \ "Cache.put should store cid in metadata" class TestListByTypeReturnsEntries: """Tests for list_by_type returning cached entries.""" def test_list_by_type_iterates_cache_entries(self) -> None: """list_by_type should iterate self.cache.list_entries().""" path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() assert 'self.cache.list_entries()' in content, \ "list_by_type should iterate cache entries" def test_list_by_type_filters_by_node_type(self) -> None: """list_by_type should filter entries by node_type.""" path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() assert 'entry.node_type == node_type' in content, \ "list_by_type should filter by node_type" def test_list_by_type_returns_node_id(self) -> None: """list_by_type should return entry.node_id (IPFS CID).""" path = Path('/home/giles/art/art-celery/cache_manager.py') content = path.read_text() assert 'cids.append(entry.node_id)' in content, \ "list_by_type should append entry.node_id (IPFS CID)" def test_artdag_cache_list_entries_returns_all(self) -> None: """artdag Cache.list_entries should return all entries.""" from artdag import Cache import inspect source = inspect.getsource(Cache.list_entries) # Should return self._entries.values() assert '_entries' in source, \ "list_entries should access _entries dict"