Files
Aniworld/scripts/test_nfo_integration.py

295 lines
9.9 KiB
Python

"""Manual integration test for NFO functionality.
This script tests the complete NFO generation workflow with real TMDB API calls.
It's intended for manual verification, not automated testing.
Usage:
1. Set TMDB_API_KEY environment variable
2. Run: python scripts/test_nfo_integration.py
3. Check output in test_output/ directory
Requirements:
- Valid TMDB API key (get from https://www.themoviedb.org/settings/api)
- Internet connection
- Write permissions for test_output/ directory
"""
import asyncio
import os
import sys
from pathlib import Path
# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.core.entities.nfo_models import TVShowNFO
from src.core.services.nfo_service import NFOService
from src.core.services.tmdb_client import TMDBAPIError, TMDBClient
from src.core.utils.nfo_generator import generate_tvshow_nfo, validate_nfo_xml
async def test_tmdb_client():
"""Test TMDB client basic functionality."""
print("\n=== Testing TMDB Client ===")
api_key = os.getenv("TMDB_API_KEY")
if not api_key:
print("❌ TMDB_API_KEY environment variable not set")
print(" Get your API key from: https://www.themoviedb.org/settings/api")
return False
try:
async with TMDBClient(api_key=api_key) as client:
# Test 1: Search for a show
print("\n1. Searching for 'Attack on Titan'...")
results = await client.search_tv_show("Attack on Titan")
if results and results.get("results"):
show = results["results"][0]
print(f" ✅ Found: {show['name']} (ID: {show['id']})")
show_id = show["id"]
else:
print(" ❌ No results found")
return False
# Test 2: Get show details
print(f"\n2. Getting details for show ID {show_id}...")
details = await client.get_tv_show_details(
show_id,
append_to_response="credits,external_ids,images"
)
print(f" ✅ Title: {details['name']}")
print(f" ✅ First Air Date: {details.get('first_air_date', 'N/A')}")
print(f" ✅ Rating: {details.get('vote_average', 'N/A')}/10")
# Test 3: Get external IDs
if "external_ids" in details:
ext_ids = details["external_ids"]
print(f" ✅ IMDB ID: {ext_ids.get('imdb_id', 'N/A')}")
print(f" ✅ TVDB ID: {ext_ids.get('tvdb_id', 'N/A')}")
# Test 4: Get images
if "images" in details:
images = details["images"]
print(f" ✅ Posters: {len(images.get('posters', []))}")
print(f" ✅ Backdrops: {len(images.get('backdrops', []))}")
print(f" ✅ Logos: {len(images.get('logos', []))}")
# Test 5: Get image URL
if details.get("poster_path"):
url = client.get_image_url(details["poster_path"], "w500")
print(f" ✅ Poster URL: {url[:60]}...")
return True
except TMDBAPIError as e:
print(f" ❌ TMDB API Error: {e}")
return False
except Exception as e:
print(f" ❌ Unexpected Error: {e}")
import traceback
traceback.print_exc()
return False
async def test_nfo_generation():
"""Test NFO XML generation."""
print("\n=== Testing NFO Generation ===")
try:
# Create a sample NFO model
print("\n1. Creating sample TVShowNFO model...")
from src.core.entities.nfo_models import (
ActorInfo,
ImageInfo,
RatingInfo,
UniqueID,
)
nfo = TVShowNFO(
title="Test Show",
originaltitle="Test Show Original",
year=2020,
plot="This is a test show for NFO generation validation.",
runtime=45,
premiered="2020-01-15",
status="Continuing",
genre=["Action", "Drama", "Animation"],
studio=["Test Studio"],
country=["Japan"],
ratings=[RatingInfo(
name="themoviedb",
value=8.5,
votes=1000,
max_rating=10,
default=True
)],
actors=[
ActorInfo(name="Test Actor 1", role="Main Character"),
ActorInfo(name="Test Actor 2", role="Villain")
],
thumb=[ImageInfo(url="https://image.tmdb.org/t/p/w500/poster.jpg")],
fanart=[ImageInfo(url="https://image.tmdb.org/t/p/original/fanart.jpg")],
uniqueid=[
UniqueID(type="tmdb", value="12345", default=False),
UniqueID(type="tvdb", value="67890", default=True)
],
tmdbid=12345,
tvdbid=67890,
imdbid="tt1234567"
)
print(" ✅ TVShowNFO model created")
# Test 2: Generate XML
print("\n2. Generating XML...")
xml_string = generate_tvshow_nfo(nfo)
print(f" ✅ Generated {len(xml_string)} characters")
# Test 3: Validate XML
print("\n3. Validating XML...")
validate_nfo_xml(xml_string)
print(" ✅ XML is valid")
# Test 4: Save to file
output_dir = Path("test_output")
output_dir.mkdir(exist_ok=True)
nfo_path = output_dir / "test_tvshow.nfo"
nfo_path.write_text(xml_string, encoding="utf-8")
print(f" ✅ Saved to: {nfo_path}")
# Test 5: Show sample
print("\n4. Sample XML (first 500 chars):")
print(" " + xml_string[:500].replace("\n", "\n "))
return True
except Exception as e:
print(f" ❌ Error: {e}")
import traceback
traceback.print_exc()
return False
async def test_nfo_service():
"""Test complete NFO service workflow."""
print("\n=== Testing NFO Service ===")
api_key = os.getenv("TMDB_API_KEY")
if not api_key:
print("❌ TMDB_API_KEY environment variable not set")
return False
try:
# Create test output directory
output_dir = Path("test_output")
output_dir.mkdir(exist_ok=True)
# Create a test series folder
test_series = output_dir / "Attack_on_Titan"
test_series.mkdir(exist_ok=True)
print(f"\n1. Creating NFO for 'Attack on Titan'...")
print(f" Output directory: {test_series}")
# Initialize NFO service
nfo_service = NFOService(
tmdb_api_key=api_key,
anime_directory=str(output_dir),
image_size="w500"
)
# Create NFO
nfo_path = await nfo_service.create_tvshow_nfo(
serie_name="Attack on Titan",
serie_folder="Attack_on_Titan",
year=2013,
download_poster=True,
download_logo=True,
download_fanart=True
)
print(f" ✅ NFO created: {nfo_path}")
# Check if files were created
print("\n2. Checking created files...")
files_created = {
"tvshow.nfo": (test_series / "tvshow.nfo").exists(),
"poster.jpg": (test_series / "poster.jpg").exists(),
"logo.png": (test_series / "logo.png").exists(),
"fanart.jpg": (test_series / "fanart.jpg").exists(),
}
for filename, exists in files_created.items():
status = "" if exists else ""
size = ""
if exists:
file_path = test_series / filename
size = f" ({file_path.stat().st_size:,} bytes)"
print(f" {status} {filename}{size}")
# Read and validate NFO
if files_created["tvshow.nfo"]:
print("\n3. Validating generated NFO...")
nfo_content = nfo_path.read_text(encoding="utf-8")
validate_nfo_xml(nfo_content)
print(" ✅ NFO is valid XML")
# Show sample
print("\n4. NFO Content (first 800 chars):")
print(" " + nfo_content[:800].replace("\n", "\n "))
return all(files_created.values())
except Exception as e:
print(f" ❌ Error: {e}")
import traceback
traceback.print_exc()
return False
async def main():
"""Run all integration tests."""
print("=" * 70)
print("NFO Functionality Integration Tests")
print("=" * 70)
print("\nNOTE: This requires a valid TMDB API key set as environment variable.")
print("Get your API key from: https://www.themoviedb.org/settings/api")
print("Set it with: export TMDB_API_KEY='your_api_key_here'")
results = []
# Test 1: TMDB Client
results.append(("TMDB Client", await test_tmdb_client()))
# Test 2: NFO Generation
results.append(("NFO Generation", await test_nfo_generation()))
# Test 3: NFO Service (full workflow)
results.append(("NFO Service", await test_nfo_service()))
# Summary
print("\n" + "=" * 70)
print("SUMMARY")
print("=" * 70)
for test_name, passed in results:
status = "✅ PASSED" if passed else "❌ FAILED"
print(f"{test_name:.<50} {status}")
all_passed = all(result for _, result in results)
if all_passed:
print("\n🎉 All tests passed!")
print("\nGenerated files are in the 'test_output/' directory.")
print("You can import tvshow.nfo into Kodi/Plex/Jellyfin to verify compatibility.")
else:
print("\n⚠️ Some tests failed. Check the output above for details.")
return 1
return 0
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)