test: Add comprehensive unit and integration test suite

Implement a complete test suite for Ohm Stream Downloader with over 300 tests covering:

Test Files:
- tests/test_models.py: Pydantic model validation tests
  * DownloadTask, DownloadRequest, DownloadStatus, HostType
  * AnimeMetadata, AnimeSearchResult
  * Field validation, edge cases, error handling

- tests/test_downloaders.py: Downloader implementation tests
  * BaseDownloader abstract class
  * Unfichier, Doodstream, Rapidfile, Uptobox downloaders
  * Video downloaders (VidMoly, SendVid)
  * Anime provider downloaders (Anime-Sama, Neko-Sama, etc.)
  * URL detection and handling

- tests/test_download_manager.py: Core download management tests
  * Task creation and lifecycle
  * Pause/resume/cancel operations
  * Progress tracking and file handling
  * Concurrency and semaphore limits
  * Error handling and edge cases

- tests/test_favorites.py: Favorites system tests
  * Add, remove, get, list favorites
  * Sorting and filtering (by title, rating, provider, genre)
  * Toggle functionality
  * Statistics generation
  * Concurrent operations

- tests/test_api.py: FastAPI endpoint tests
  * Root, health, providers endpoints
  * Download CRUD operations
  * Anime search and metadata endpoints
  * Favorites API endpoints
  * Sorting and filtering
  * Error handling and validation
  * CORS headers

Infrastructure:
- tests/conftest.py: Pytest configuration and fixtures
  * Temporary directories for isolation
  * Sample data fixtures
  * Mock clients for network operations
  * Custom markers (unit, integration, slow, network)

- pytest.ini: Pytest configuration
  * Coverage reporting (term + HTML)
  * Verbose output with locals
  * Strict markers
  * Async test support
  * Timeout configuration

- requirements.txt: Updated with testing dependencies
  * pytest, pytest-asyncio, pytest-cov
  * pytest-mock, pytest-timeout, pytest-html

- .gitignore: Updated to ignore test artifacts
  * .pytest_cache/, coverage reports
  * Project data files (favorites.json, *.db)

- tests/README.md: Test documentation
  * How to run tests
  * Available fixtures and markers
  * Coverage reporting instructions

Test Coverage Areas:
✓ Model validation and serialization
✓ All downloader implementations
✓ Download queue management
✓ Favorites persistence and retrieval
✓ REST API endpoints
✓ Error handling and edge cases
✓ Async/await operations
✓ Concurrent operations
✓ File system operations

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
root
2026-01-23 10:28:47 +00:00
parent 5805f1036f
commit 785147b1b1
11 changed files with 2456 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
[pytest]
# Pytest configuration for Ohm Stream Downloader
# Test discovery patterns
python_files = test_*.py
python_classes = Test*
python_functions = test_*
# Test paths
testpaths = tests
# Output options
addopts =
# Verbose output
-v
# Show local variables in tracebacks
--showlocals
# Show summary of all test outcomes
-ra
# Strict markers
--strict-markers
# Warn about assertions that aren't being used
--warn=assertions
# Coverage reporting (if pytest-cov is installed)
--cov=app
--cov-report=term-missing
--cov-report=html
--no-cov-on-fail
# Markers
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
integration: marks tests as integration tests
unit: marks tests as unit tests
asyncio: marks tests as async tests
network: marks tests that require network access
# Ignore paths
norecursedir = .git .tox dist build *.egg venv .venv
# Logging
log_cli = true
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)s] %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
# Timeout (if pytest-timeout is installed)
timeout = 300
# Asyncio mode (if pytest-asyncio is installed)
asyncio_mode = auto
# Coverage options (if pytest-cov is installed)
[coverage:run]
source = app
omit =
*/tests/*
*/test_*.py
*/__pycache__/*
*/venv/*
*/.venv/*
[coverage:report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if __name__ == .__main__.:
if TYPE_CHECKING:
@abstractmethod