From 6193ce27240b1fa04d7e0653d3546bdcd35eafc8 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Tue, 6 Jan 2026 15:26:31 -0500 Subject: [PATCH] Fix domain vault init check in finish_crawl/get_stats - Add _initialized check to finish_crawl() and get_stats() in all 3 vault classes - Prevents FileNotFoundError when git commands run on non-existent directories - Update test_crawl.py to use pytest tmp_path fixture - Add network marker to skip functional tests in CI with '-m "not network"' --- neopig/domain_vault.py | 18 ++++++++++++++++++ pytest.ini | 2 ++ tests/test_crawl.py | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/neopig/domain_vault.py b/neopig/domain_vault.py index ea06dcc..6f9be28 100644 --- a/neopig/domain_vault.py +++ b/neopig/domain_vault.py @@ -372,6 +372,9 @@ class DomainHtmlVault: async def finish_crawl(self, stats: Dict[str, Any]) -> Optional[str]: """Finish crawl, log it, and commit if changes.""" + if not self._initialized: + await self.init() + log = await self._load_crawl_log() log['crawls'].append({ 'timestamp': datetime.now(timezone.utc).isoformat(), @@ -386,6 +389,9 @@ class DomainHtmlVault: async def get_stats(self) -> Dict[str, Any]: """Get vault statistics.""" + if not self._initialized: + await self.init() + log = await self._load_crawl_log() commits = await self._git.log(5) @@ -510,6 +516,9 @@ class DomainMediaVault: async def finish_crawl(self, stats: Dict[str, Any]) -> Optional[str]: """Finish crawl and commit if changes.""" + if not self._initialized: + await self.init() + media_new = stats.get('media_new', 0) if media_new > 0: return await self._git.commit(f"Crawl: {media_new} media files") @@ -517,6 +526,9 @@ class DomainMediaVault: async def get_stats(self) -> Dict[str, Any]: """Get vault statistics.""" + if not self._initialized: + await self.init() + index = await self._load_index() commits = await self._git.log(5) @@ -649,6 +661,9 @@ class DomainLinkpeekVault: async def finish_crawl(self, stats: Dict[str, Any]) -> Optional[str]: """Finish crawl and commit if changes.""" + if not self._initialized: + await self.init() + screenshots_new = stats.get('screenshots_new', 0) if screenshots_new > 0: return await self._git.commit(f"Crawl: {screenshots_new} screenshots") @@ -656,6 +671,9 @@ class DomainLinkpeekVault: async def get_stats(self) -> Dict[str, Any]: """Get vault statistics.""" + if not self._initialized: + await self.init() + index = await self._load_index() commits = await self._git.log(5) diff --git a/pytest.ini b/pytest.ini index f9815bd..b29b317 100644 --- a/pytest.ini +++ b/pytest.ini @@ -5,3 +5,5 @@ testpaths = tests python_files = test_*.py python_classes = Test* python_functions = test_* +markers = + network: tests that require network access (deselect with '-m "not network"') diff --git a/tests/test_crawl.py b/tests/test_crawl.py index 003009e..1d5bb14 100644 --- a/tests/test_crawl.py +++ b/tests/test_crawl.py @@ -3,12 +3,17 @@ Functional test for neopig crawler. Tests crawling upload.unturf.com for images. + +These tests hit live network and are marked with @pytest.mark.network. +To skip in CI: pytest -m "not network" """ import asyncio import sys from pathlib import Path +import pytest + # Add current dir to path sys.path.insert(0, str(Path(__file__).parent)) @@ -16,17 +21,21 @@ from neopig import NeoPig from neopig.async_web_fetcher import CrawlMode -async def test_crawl_upload_unturf(): +@pytest.mark.network +async def test_crawl_upload_unturf(tmp_path): """Test crawling upload.unturf.com for images.""" print("=" * 60) print("neopig functional test") print("Target: https://upload.unturf.com") print("=" * 60) - # Use test database and vault + # Use temp directory for test database and vault + db_path = tmp_path / "test_neopig.db" + vault_path = tmp_path / "test_vault" + pig = NeoPig( - db_path="test_neopig.db", - vault_path="test_vault" + db_path=str(db_path), + vault_path=str(vault_path) ) await pig.init() @@ -59,7 +68,7 @@ async def test_crawl_upload_unturf(): # Check database from neopig.database import Database - db = Database("test_neopig.db") + db = Database(str(db_path)) await db.init() db_stats = await db.get_stats() print(f"\n Database stats:") @@ -79,15 +88,20 @@ async def test_crawl_upload_unturf(): return stats -async def test_crawl_modes(): +@pytest.mark.network +async def test_crawl_modes(tmp_path): """Test different crawl modes.""" print("\n" + "=" * 60) print("Testing crawl modes...") print("=" * 60) + # Use temp directory for test database and vault + db_path = tmp_path / "test_neopig.db" + vault_path = tmp_path / "test_vault" + pig = NeoPig( - db_path="test_neopig.db", - vault_path="test_vault" + db_path=str(db_path), + vault_path=str(vault_path) ) await pig.init() @@ -107,10 +121,13 @@ async def test_crawl_modes(): if __name__ == "__main__": + import tempfile print("neopig functional test suite\n") - # Run tests - asyncio.run(test_crawl_upload_unturf()) - asyncio.run(test_crawl_modes()) + # Run tests with temp directory + with tempfile.TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + asyncio.run(test_crawl_upload_unturf(tmp_path)) + asyncio.run(test_crawl_modes(tmp_path)) - print("\nDone! Check test_vault/ and test_neopig.db for results.") + print("\nDone!")