"""Tests for DownloadProcessor and DownloadInput/DownloadOutput schemas. Test coverage: - DownloadInput schema validation - DownloadOutput schema validation - DownloadProcessor metadata fetching - DownloadProcessor content downloading - DownloadProcessor state recording """ import pytest from datetime import datetime from unittest.mock import AsyncMock, MagicMock, patch from pathlib import Path from kb_pipeline.schemas import DownloadInput, DownloadOutput class TestDownloadInputSchema: """Tests for DownloadInput schema validation.""" def test_schema_download_input_validates_required_fields(self): """Test 1: DownloadInput validates required fields""" # Test with all required fields input_data = DownloadInput( content_id="BV1xx", platform="bilibili", content_dir="/tmp/content", content_type="video" ) assert input_data.content_id == "BV1xx" assert input_data.platform == "bilibili" assert input_data.content_dir == "/tmp/content" assert input_data.content_type == "video" def test_schema_download_input_requires_content_dir(self): """DownloadInput should require content_dir""" with pytest.raises(Exception): # ValidationError from pydantic DownloadInput( content_id="BV1xx", platform="bilibili", content_type="video" # Missing content_dir ) def test_schema_download_input_requires_content_type(self): """DownloadInput should require content_type""" with pytest.raises(Exception): # ValidationError from pydantic DownloadInput( content_id="BV1xx", platform="bilibili", content_dir="/tmp/content" # Missing content_type ) class TestDownloadOutputSchema: """Tests for DownloadOutput schema validation.""" def test_schema_download_output_validates_required_fields(self): """Test 2: DownloadOutput validates required fields""" output = DownloadOutput( success=True, metadata_file="/tmp/content/bilibili_BV1xx_metadata.json", content_file="/tmp/content/bilibili_BV1xx_content.md", title="Test Video", author="Test Author" ) assert output.success is True assert output.metadata_file == "/tmp/content/bilibili_BV1xx_metadata.json" assert output.content_file == "/tmp/content/bilibili_BV1xx_content.md" assert output.title == "Test Video" assert output.author == "Test Author" assert output.duration is None # Optional field def test_schema_download_output_handles_video_content_type(self): """Test 3: DownloadOutput handles video content type with duration""" output = DownloadOutput( success=True, metadata_file="/tmp/content/bilibili_BV1xx_metadata.json", content_file="", # Video content handled by ASR title="Test Video", author="Test Author", duration=300 # 5 minutes ) assert output.success is True assert output.duration == 300 assert output.content_file == "" def test_schema_download_output_handles_article_content_type(self): """Test 3: DownloadOutput handles article content type without duration""" output = DownloadOutput( success=True, metadata_file="/tmp/content/bilibili_CV123_metadata.json", content_file="/tmp/content/bilibili_CV123_content.md", title="Test Article", author="Test Author", duration=None # Articles don't have duration ) assert output.success is True assert output.duration is None assert output.content_file == "/tmp/content/bilibili_CV123_content.md" def test_schema_download_output_handles_zhihu_answer(self): """Test 3: DownloadOutput handles Zhihu answer content type""" output = DownloadOutput( success=True, metadata_file="/tmp/content/zhihu_123456_metadata.json", content_file="/tmp/content/zhihu_123456_content.md", title="Test Answer", author="Test Author" ) assert output.success is True assert "zhihu" in output.metadata_file def test_schema_download_output_handles_failure(self): """DownloadOutput should handle failure case""" output = DownloadOutput( success=False, error_message="Network error", metadata_file="", content_file="", title="", author="" ) assert output.success is False assert output.error_message == "Network error"