Compare commits
No commits in common. "453de2b0378d9d9bf6b2d735813a2c13d7a5ccc0" and "f24809a22aa786c48f3b7c1d5ead3d954b2974fd" have entirely different histories.
453de2b037
...
f24809a22a
2 changed files with 1 additions and 98 deletions
6
app.py
6
app.py
|
|
@ -4121,11 +4121,7 @@ async def media_handoff(payload: MediaHandoffPayload, request: Request):
|
||||||
_audit("/media/handoff", "POST", 403, f"caller={caller} action={payload.action}")
|
_audit("/media/handoff", "POST", 403, f"caller={caller} action={payload.action}")
|
||||||
raise HTTPException(403, "Media handoff caller is not allowed")
|
raise HTTPException(403, "Media handoff caller is not allowed")
|
||||||
|
|
||||||
# 16.09.2026: serienen/videoen ergaenzt. Die englischen Arr-Instanzen
|
allowed_categories = {"serien4k", "serien", "video4k", "video"}
|
||||||
# sonarrEN (Port 8991, Root /data/FHD/serienen) und radarrEN (Port 7880,
|
|
||||||
# Root /data/FHD/videoen) nutzen eigene SAB-Kategorien. Ohne sie brach der
|
|
||||||
# Handoff mit 422 ab und Releases blieben in /usenet/complete liegen.
|
|
||||||
allowed_categories = {"serien4k", "serien", "serienen", "video4k", "video", "videoen"}
|
|
||||||
if payload.action == "start":
|
if payload.action == "start":
|
||||||
if payload.category not in allowed_categories:
|
if payload.category not in allowed_categories:
|
||||||
raise HTTPException(422, "Unsupported media category")
|
raise HTTPException(422, "Unsupported media category")
|
||||||
|
|
|
||||||
|
|
@ -117,99 +117,6 @@ def test_media_handoff_rejects_wrong_category_path(monkeypatch):
|
||||||
assert response.status_code == 422
|
assert response.status_code == 422
|
||||||
|
|
||||||
|
|
||||||
def test_media_handoff_accepts_english_arr_categories(monkeypatch):
|
|
||||||
"""serienen/videoen muessen durchgehen (sonarrEN 8991 / radarrEN 7880).
|
|
||||||
|
|
||||||
16.09.2026: fehlten in allowed_categories -> HTTP 422 -> movetdarr.sh
|
|
||||||
brach mit "n8n-Handoff konnte nicht registriert werden" ab und liess
|
|
||||||
Mutiny.2026 x2 tagelang in /usenet/complete/videoen liegen.
|
|
||||||
"""
|
|
||||||
seen = []
|
|
||||||
|
|
||||||
class FakeResponse:
|
|
||||||
status_code = 200
|
|
||||||
|
|
||||||
def json(self):
|
|
||||||
return {"ok": True, "jobId": "test-job-5678", "state": "registered"}
|
|
||||||
|
|
||||||
class FakeClient:
|
|
||||||
def __init__(self, **_kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, *_args):
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def post(self, url, json, headers):
|
|
||||||
seen.append(json)
|
|
||||||
return FakeResponse()
|
|
||||||
|
|
||||||
monkeypatch.setattr(app.httpx, "AsyncClient", FakeClient)
|
|
||||||
with TestClient(app.app) as client:
|
|
||||||
monkeypatch.setattr(app, "SERVICES", {"n8n": {"url": "http://n8n:5678", "auth": "n8n"}})
|
|
||||||
for category in ("serienen", "videoen"):
|
|
||||||
response = client.post(
|
|
||||||
"/media/handoff",
|
|
||||||
headers={"Authorization": "Bearer test-token"},
|
|
||||||
json={
|
|
||||||
"action": "start",
|
|
||||||
"category": category,
|
|
||||||
"directory": f"/usenet/complete/{category}/Release.2026",
|
|
||||||
"release": "Release.2026-GRP",
|
|
||||||
"cleanName": "Release 2026",
|
|
||||||
"expectedFiles": 1,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
assert response.status_code == 200, (category, response.text)
|
|
||||||
assert response.json()["state"] == "registered", category
|
|
||||||
|
|
||||||
assert [item["category"] for item in seen] == ["serienen", "videoen"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_media_handoff_still_rejects_unknown_category(monkeypatch):
|
|
||||||
"""Fail-closed bleibt: eine frei erfundene Kategorie wird nicht geproxyt."""
|
|
||||||
monkeypatch.setattr(
|
|
||||||
app.httpx,
|
|
||||||
"AsyncClient",
|
|
||||||
lambda **_kwargs: (_ for _ in ()).throw(AssertionError("must not proxy")),
|
|
||||||
)
|
|
||||||
with TestClient(app.app) as client:
|
|
||||||
response = client.post(
|
|
||||||
"/media/handoff",
|
|
||||||
headers={"Authorization": "Bearer test-token"},
|
|
||||||
json={
|
|
||||||
"action": "start",
|
|
||||||
"category": "hoerbuecher",
|
|
||||||
"directory": "/usenet/complete/hoerbuecher/Buch",
|
|
||||||
"release": "Buch",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
assert response.status_code == 422
|
|
||||||
|
|
||||||
|
|
||||||
def test_media_handoff_english_category_path_must_match(monkeypatch):
|
|
||||||
"""Pfadpruefung gilt auch fuer die neuen Kategorien."""
|
|
||||||
monkeypatch.setattr(
|
|
||||||
app.httpx,
|
|
||||||
"AsyncClient",
|
|
||||||
lambda **_kwargs: (_ for _ in ()).throw(AssertionError("must not proxy")),
|
|
||||||
)
|
|
||||||
with TestClient(app.app) as client:
|
|
||||||
response = client.post(
|
|
||||||
"/media/handoff",
|
|
||||||
headers={"Authorization": "Bearer test-token"},
|
|
||||||
json={
|
|
||||||
"action": "start",
|
|
||||||
"category": "videoen",
|
|
||||||
"directory": "/usenet/complete/video4k/Wrong",
|
|
||||||
"release": "Wrong",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
assert response.status_code == 422
|
|
||||||
|
|
||||||
|
|
||||||
def test_paperless_import_queues_pdf_through_butler(monkeypatch):
|
def test_paperless_import_queues_pdf_through_butler(monkeypatch):
|
||||||
captured = {}
|
captured = {}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue