124 lines
4.0 KiB
Python
124 lines
4.0 KiB
Python
"""Tests for the Jellyfin client + pool verification. Network is monkeypatched."""
|
|
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from src.core import jellyfin
|
|
from src.core.jellyfin import JellyfinError, JellyfinMovie
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _configured(monkeypatch):
|
|
monkeypatch.setenv("JELLYFIN_URL", "http://jf:8096/")
|
|
monkeypatch.setenv("JELLYFIN_API_KEY", "key")
|
|
|
|
|
|
def _resp(status=200, payload=None):
|
|
return SimpleNamespace(
|
|
status_code=status, ok=(200 <= status < 300), json=lambda: payload or {}
|
|
)
|
|
|
|
|
|
def test_base_url_strips_trailing_slash():
|
|
assert jellyfin.base_url() == "http://jf:8096"
|
|
|
|
|
|
def test_api_available(monkeypatch):
|
|
assert jellyfin.api_available()
|
|
monkeypatch.delenv("JELLYFIN_API_KEY", raising=False)
|
|
assert not jellyfin.api_available()
|
|
|
|
|
|
def test_server_version(monkeypatch):
|
|
monkeypatch.setattr(
|
|
jellyfin.requests, "request", lambda *a, **k: _resp(200, {"Version": "10.9.11"})
|
|
)
|
|
assert jellyfin.server_version() == "10.9.11"
|
|
|
|
|
|
def test_scan_all_posts_refresh(monkeypatch):
|
|
seen = {}
|
|
|
|
def fake(method, url, **k):
|
|
seen["method"], seen["url"] = method, url
|
|
return _resp(200, {})
|
|
|
|
monkeypatch.setattr(jellyfin.requests, "request", fake)
|
|
jellyfin.scan_all()
|
|
assert seen["method"] == "POST" and seen["url"].endswith("/Library/Refresh")
|
|
|
|
|
|
def test_fetch_movies_maps_tmdb_id(monkeypatch):
|
|
payload = {
|
|
"Items": [
|
|
{
|
|
"Id": "a1",
|
|
"Name": "Matrix",
|
|
"ProductionYear": 1999,
|
|
"ProviderIds": {"Tmdb": "603"},
|
|
"Path": "/m/Matrix (1999) [tmdbid-603].mkv",
|
|
},
|
|
{"Id": "a2", "Name": "Bez ID", "ProductionYear": 2000, "ProviderIds": {}},
|
|
]
|
|
}
|
|
monkeypatch.setattr(
|
|
jellyfin.requests, "request", lambda *a, **k: _resp(200, payload)
|
|
)
|
|
movies = jellyfin.fetch_movies()
|
|
assert movies[0] == JellyfinMovie(
|
|
"a1", "Matrix", 1999, 603, "/m/Matrix (1999) [tmdbid-603].mkv"
|
|
)
|
|
assert movies[1].tmdb_id is None
|
|
|
|
|
|
def test_missing_config_raises(monkeypatch):
|
|
monkeypatch.delenv("JELLYFIN_URL", raising=False)
|
|
with pytest.raises(JellyfinError):
|
|
jellyfin.server_version()
|
|
|
|
|
|
def test_bad_auth_raises(monkeypatch):
|
|
monkeypatch.setattr(jellyfin.requests, "request", lambda *a, **k: _resp(401))
|
|
with pytest.raises(JellyfinError):
|
|
jellyfin.scan_all()
|
|
|
|
|
|
class TestVerifyAgainstJellyfin:
|
|
@pytest.fixture
|
|
def file_manager(self, tmp_path, monkeypatch):
|
|
import src.core.config as config_module
|
|
|
|
monkeypatch.setattr(config_module, "GLOBAL_CONFIG_FILE", tmp_path / ".gtag")
|
|
from src.core.file_manager import FileManager
|
|
from src.core.tag_manager import TagManager
|
|
|
|
fm = FileManager(TagManager())
|
|
fm.set_pool_dir(tmp_path / "pool")
|
|
return fm
|
|
|
|
def test_match_by_tmdb_id_and_report_gaps(self, file_manager, tmp_path):
|
|
(tmp_path / "a.mkv").write_bytes(b"x")
|
|
(tmp_path / "b.mkv").write_bytes(b"y")
|
|
file_manager.import_movie(tmp_path / "a.mkv", "Matrix", year=1999, tmdb_id=603)
|
|
file_manager.import_movie(tmp_path / "b.mkv", "Neznámý", year=2020) # no id
|
|
|
|
jf = [
|
|
JellyfinMovie("j1", "Matrix", 1999, 603, None), # matches a by tmdb
|
|
JellyfinMovie("j2", "Cizí film", 2011, 999, None), # jellyfin-only
|
|
]
|
|
result = file_manager.verify_against_jellyfin(jf)
|
|
|
|
assert result["matched"] == 1
|
|
assert result["pool_only"] == ["Neznámý (2020).mkv"]
|
|
assert result["jellyfin_only"] == ["Cizí film"]
|
|
assert result["pool_total"] == 2 and result["jellyfin_total"] == 2
|
|
|
|
def test_match_by_title_year_fallback(self, file_manager, tmp_path):
|
|
(tmp_path / "a.mkv").write_bytes(b"x")
|
|
file_manager.import_movie(tmp_path / "a.mkv", "Kolja", year=1996) # no id
|
|
|
|
jf = [JellyfinMovie("j1", "Kolja", 1996, None, None)]
|
|
result = file_manager.verify_against_jellyfin(jf)
|
|
assert result["matched"] == 1 and result["pool_only"] == []
|