Phase 2: Docker and OIDC auth

This commit is contained in:
2026-05-04 13:50:53 +02:00
parent 47baee854b
commit 4226628d5a
71 changed files with 9722 additions and 1347 deletions
+129 -1
View File
@@ -3,7 +3,12 @@
import pytest
import tempfile
from pathlib import Path
from media_library_viewer_api.services.media_index import MediaIndex
from typing import Any
from media_library_viewer_api.services.media_index import (
MediaIndex,
MediaIndexBuildCancelled,
build_media_index,
)
@pytest.fixture
@@ -242,3 +247,126 @@ class TestMediaIndexMetadata:
index.set_metadata("build_duration_seconds", "12.5")
status = index.status()
assert status.build_duration_seconds == 12.5
class TestMediaIndexBuildPaths:
def test_build_media_index_patches_remote_media_root(self, tmp_path):
class FakeClient:
def items(self, **kwargs):
return {
"Items": [
{
"Id": "m1",
"Name": "Movie One",
"Type": "Movie",
"Path": "/media/movies/Movie One/file.mkv",
}
],
"TotalRecordCount": 1,
}
index = MediaIndex(tmp_path / "index.sqlite")
count = build_media_index(
FakeClient(),
"user1",
[{"Id": "lib1", "Name": "Movies"}],
index,
media_root="/srv/media",
fallback_prefix="",
)
assert count == 1
rows, total = index.query(library_ids=["lib1"], media_types=["Movie"])
assert total == 1
assert rows[0]["path"] == "/srv/media/movies/Movie One/file.mkv"
def test_build_media_index_reports_progress(self, tmp_path):
class FakeClient:
def __init__(self):
self.calls = []
def items(self, **kwargs):
self.calls.append(kwargs.get("start_index", 0))
if kwargs.get("start_index", 0) == 0:
return {
"Items": [
{"Id": "m1", "Name": "Movie One", "Type": "Movie", "Path": "/media/a.mkv"}
],
"TotalRecordCount": 2,
}
return {
"Items": [
{"Id": "m2", "Name": "Movie Two", "Type": "Movie", "Path": "/media/b.mkv"}
],
"TotalRecordCount": 2,
}
events: list[dict[str, Any]] = []
index = MediaIndex(tmp_path / "index.sqlite")
count = build_media_index(
FakeClient(),
"user1",
[{"Id": "lib1", "Name": "Movies"}],
index,
page_size=1,
progress_callback=events.append,
)
assert count == 2
assert events[0]["stage"] == "starting"
assert events[0]["progress"] is None
assert any(event["stage"] == "building" for event in events)
building_event = next(event for event in events if event["stage"] == "building")
assert building_event["library"] == "Movies"
assert building_event["library_progress"] in (0.5, 1.0)
assert "elapsed_seconds" in building_event
assert "eta_seconds" in building_event
assert events[-1]["stage"] == "completed"
assert events[-1]["progress"] == 1.0
assert events[-1]["library_progress"] == 1.0
def test_build_media_index_can_be_cancelled(self, tmp_path):
class FakeClient:
def __init__(self):
self.calls = []
def items(self, **kwargs):
self.calls.append(kwargs.get("start_index", 0))
if kwargs.get("start_index", 0) == 0:
return {
"Items": [
{"Id": "m1", "Name": "Movie One", "Type": "Movie", "Path": "/media/a.mkv"}
],
"TotalRecordCount": 2,
}
return {
"Items": [
{"Id": "m2", "Name": "Movie Two", "Type": "Movie", "Path": "/media/b.mkv"}
],
"TotalRecordCount": 2,
}
events: list[dict[str, Any]] = []
cancel_after_building = [False]
def progress_callback(state: dict[str, Any]) -> None:
events.append(state)
if state["stage"] == "building":
cancel_after_building[0] = True
def should_cancel() -> bool:
return cancel_after_building[0]
index = MediaIndex(tmp_path / "index.sqlite")
client = FakeClient()
with pytest.raises(MediaIndexBuildCancelled):
build_media_index(
client,
"user1",
[{"Id": "lib1", "Name": "Movies"}],
index,
page_size=1,
progress_callback=progress_callback,
should_cancel=should_cancel,
)
assert any(event["stage"] == "building" for event in events)
assert events[-1]["stage"] == "building"
assert client.calls == [0]