92 lines
3.2 KiB
Python
92 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any, cast
|
|
|
|
import pytest
|
|
|
|
from auditui.constants import MIN_FILE_SIZE
|
|
from auditui.downloads import DownloadManager
|
|
|
|
|
|
def _manager_with_cache_dir(tmp_path: Path) -> DownloadManager:
|
|
"""Build a lightweight DownloadManager instance without real HTTP clients."""
|
|
manager = DownloadManager.__new__(DownloadManager)
|
|
manager.cache_dir = tmp_path
|
|
manager.chunk_size = 1024
|
|
return manager
|
|
|
|
|
|
def test_sanitize_filename_replaces_invalid_characters() -> None:
|
|
"""Ensure filename normalization uses ASCII words and dashes."""
|
|
manager = DownloadManager.__new__(DownloadManager)
|
|
assert (
|
|
manager._sanitize_filename("Stephen King 11/22/63") == "Stephen-King-11-22-63"
|
|
)
|
|
|
|
|
|
def test_validate_download_url_accepts_only_http_schemes() -> None:
|
|
"""Ensure download URL validation only accepts HTTP and HTTPS links."""
|
|
manager = DownloadManager.__new__(DownloadManager)
|
|
assert manager._validate_download_url("https://example.com/file") is True
|
|
assert manager._validate_download_url("http://example.com/file") is True
|
|
assert manager._validate_download_url("ftp://example.com/file") is False
|
|
|
|
|
|
def test_get_cached_path_and_remove_cached(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""Ensure cache lookup and cache deletion work for valid files."""
|
|
manager = _manager_with_cache_dir(tmp_path)
|
|
monkeypatch.setattr(
|
|
manager,
|
|
"_get_filename_stems_from_asin",
|
|
lambda asin: ["Stephen-King_11-22-63", "11-22-63"],
|
|
)
|
|
cached_path = tmp_path / "Stephen-King_11-22-63.aax"
|
|
cached_path.write_bytes(b"0" * MIN_FILE_SIZE)
|
|
messages: list[str] = []
|
|
assert manager.get_cached_path("ASIN123") == cached_path
|
|
assert manager.is_cached("ASIN123") is True
|
|
assert manager.remove_cached("ASIN123", notify=messages.append) is True
|
|
assert not cached_path.exists()
|
|
assert "Removed from cache" in messages[-1]
|
|
|
|
|
|
def test_get_cached_path_ignores_small_files(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""Ensure undersized files are not treated as valid cache entries."""
|
|
manager = _manager_with_cache_dir(tmp_path)
|
|
monkeypatch.setattr(
|
|
manager,
|
|
"_get_filename_stems_from_asin",
|
|
lambda asin: ["Stephen-King_11-22-63", "11-22-63"],
|
|
)
|
|
cached_path = tmp_path / "Stephen-King_11-22-63.aax"
|
|
cached_path.write_bytes(b"0" * (MIN_FILE_SIZE - 1))
|
|
assert manager.get_cached_path("ASIN123") is None
|
|
|
|
|
|
def test_get_filename_stems_include_author_title_and_legacy_title() -> None:
|
|
"""Ensure filename candidates include new author_title and legacy title names."""
|
|
manager = DownloadManager.__new__(DownloadManager)
|
|
manager.client = cast(
|
|
Any,
|
|
type(
|
|
"Client",
|
|
(),
|
|
{
|
|
"get": lambda self, path, **kwargs: {
|
|
"product": {
|
|
"title": "11/22/63",
|
|
"authors": [{"name": "Stephen King"}],
|
|
}
|
|
}
|
|
},
|
|
)(),
|
|
)
|
|
stems = manager._get_filename_stems_from_asin("B00TEST")
|
|
assert stems[0] == "Stephen-King_11-22-63"
|
|
assert "11-22-63" in stems
|