- Parse existing NFO to extract TMDB ID from uniqueid or tmdbid element - Fetch fresh metadata from TMDB API - Regenerate NFO with updated data - Optionally re-download media files - Add comprehensive error handling (missing NFO, no TMDB ID, invalid XML) - Add unit tests for XML parsing logic (4 tests, all passing) - Add integration test script (requires TMDB API key)
184 lines
5.9 KiB
Python
184 lines
5.9 KiB
Python
"""Test script for NFOService.update_tvshow_nfo() functionality.
|
|
|
|
This script tests the update functionality by:
|
|
1. Creating a test NFO file with TMDB ID
|
|
2. Updating it with fresh data from TMDB
|
|
3. Verifying the update worked correctly
|
|
"""
|
|
|
|
import asyncio
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add src to path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from src.config.settings import settings
|
|
from src.core.services.nfo_service import NFOService
|
|
from src.core.services.tmdb_client import TMDBAPIError
|
|
|
|
# Configure logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def test_update_nfo():
|
|
"""Test NFO update functionality."""
|
|
|
|
# Check if TMDB API key is configured
|
|
if not settings.tmdb_api_key:
|
|
logger.error("TMDB_API_KEY not configured in environment")
|
|
logger.error("Set TMDB_API_KEY in .env file or environment variables")
|
|
return False
|
|
|
|
# Test series: Attack on Titan (TMDB ID: 1429)
|
|
test_serie_name = "Attack on Titan"
|
|
test_serie_folder = "test_update_nfo"
|
|
test_tmdb_id = 1429
|
|
|
|
# Create test folder
|
|
test_folder = Path(settings.anime_directory) / test_serie_folder
|
|
test_folder.mkdir(parents=True, exist_ok=True)
|
|
logger.info(f"Created test folder: {test_folder}")
|
|
|
|
# Initialize NFO service
|
|
nfo_service = NFOService(
|
|
tmdb_api_key=settings.tmdb_api_key,
|
|
anime_directory=settings.anime_directory,
|
|
image_size=settings.nfo_image_size
|
|
)
|
|
|
|
try:
|
|
# Step 1: Create initial NFO
|
|
logger.info("=" * 60)
|
|
logger.info("STEP 1: Creating initial NFO")
|
|
logger.info("=" * 60)
|
|
|
|
nfo_path = await nfo_service.create_tvshow_nfo(
|
|
serie_name=test_serie_name,
|
|
serie_folder=test_serie_folder,
|
|
year=2013,
|
|
download_poster=False, # Skip downloads for faster testing
|
|
download_logo=False,
|
|
download_fanart=False
|
|
)
|
|
|
|
logger.info(f"✓ Initial NFO created: {nfo_path}")
|
|
|
|
# Read initial NFO content
|
|
initial_content = nfo_path.read_text(encoding="utf-8")
|
|
logger.info(f"Initial NFO size: {len(initial_content)} bytes")
|
|
|
|
# Verify TMDB ID is in the file
|
|
if str(test_tmdb_id) not in initial_content:
|
|
logger.error(f"TMDB ID {test_tmdb_id} not found in NFO!")
|
|
return False
|
|
logger.info(f"✓ TMDB ID {test_tmdb_id} found in NFO")
|
|
|
|
# Step 2: Update the NFO
|
|
logger.info("")
|
|
logger.info("=" * 60)
|
|
logger.info("STEP 2: Updating NFO with fresh data")
|
|
logger.info("=" * 60)
|
|
|
|
updated_path = await nfo_service.update_tvshow_nfo(
|
|
serie_folder=test_serie_folder,
|
|
download_media=False # Skip downloads
|
|
)
|
|
|
|
logger.info(f"✓ NFO updated: {updated_path}")
|
|
|
|
# Read updated content
|
|
updated_content = updated_path.read_text(encoding="utf-8")
|
|
logger.info(f"Updated NFO size: {len(updated_content)} bytes")
|
|
|
|
# Verify TMDB ID is still in the file
|
|
if str(test_tmdb_id) not in updated_content:
|
|
logger.error(f"TMDB ID {test_tmdb_id} not found after update!")
|
|
return False
|
|
logger.info(f"✓ TMDB ID {test_tmdb_id} still present after update")
|
|
|
|
# Step 3: Test update on non-existent NFO (should fail)
|
|
logger.info("")
|
|
logger.info("=" * 60)
|
|
logger.info("STEP 3: Testing error handling")
|
|
logger.info("=" * 60)
|
|
|
|
try:
|
|
await nfo_service.update_tvshow_nfo(
|
|
serie_folder="non_existent_folder",
|
|
download_media=False
|
|
)
|
|
logger.error("✗ Should have raised FileNotFoundError!")
|
|
return False
|
|
except FileNotFoundError as e:
|
|
logger.info(f"✓ Correctly raised FileNotFoundError: {e}")
|
|
|
|
# Step 4: Test update on NFO without TMDB ID
|
|
logger.info("")
|
|
logger.info("STEP 4: Testing NFO without TMDB ID")
|
|
|
|
# Create a minimal NFO without TMDB ID
|
|
no_id_folder = test_folder.parent / "test_no_tmdb_id"
|
|
no_id_folder.mkdir(parents=True, exist_ok=True)
|
|
no_id_nfo = no_id_folder / "tvshow.nfo"
|
|
no_id_nfo.write_text(
|
|
'<?xml version="1.0" encoding="UTF-8"?>\n'
|
|
'<tvshow>\n'
|
|
' <title>Test Show</title>\n'
|
|
'</tvshow>',
|
|
encoding="utf-8"
|
|
)
|
|
|
|
try:
|
|
await nfo_service.update_tvshow_nfo(
|
|
serie_folder="test_no_tmdb_id",
|
|
download_media=False
|
|
)
|
|
logger.error("✗ Should have raised TMDBAPIError!")
|
|
return False
|
|
except TMDBAPIError as e:
|
|
logger.info(f"✓ Correctly raised TMDBAPIError: {e}")
|
|
|
|
logger.info("")
|
|
logger.info("=" * 60)
|
|
logger.info("✓ ALL TESTS PASSED")
|
|
logger.info("=" * 60)
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"✗ Test failed with error: {e}", exc_info=True)
|
|
return False
|
|
|
|
finally:
|
|
await nfo_service.close()
|
|
|
|
# Cleanup test folders
|
|
logger.info("\nCleaning up test folders...")
|
|
import shutil
|
|
try:
|
|
if test_folder.exists():
|
|
shutil.rmtree(test_folder)
|
|
logger.info(f"Removed: {test_folder}")
|
|
|
|
no_id_folder = test_folder.parent / "test_no_tmdb_id"
|
|
if no_id_folder.exists():
|
|
shutil.rmtree(no_id_folder)
|
|
logger.info(f"Removed: {no_id_folder}")
|
|
except Exception as e:
|
|
logger.warning(f"Cleanup error: {e}")
|
|
|
|
|
|
async def main():
|
|
"""Main entry point."""
|
|
success = await test_update_nfo()
|
|
sys.exit(0 if success else 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|