feat: add restricted media handoff bridge #50
1 changed files with 70 additions and 1 deletions
|
|
@ -43,7 +43,76 @@ def test_health_exposes_current_version():
|
|||
with TestClient(app.app) as client:
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["version"] == app.VERSION == "2.3.5"
|
||||
assert response.json()["version"] == app.VERSION == "2.3.6"
|
||||
|
||||
|
||||
def test_media_handoff_proxies_strict_category_contract(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
class FakeResponse:
|
||||
status_code = 200
|
||||
|
||||
def json(self):
|
||||
return {"ok": True, "jobId": "test-job-1234", "state": "registered"}
|
||||
|
||||
class FakeClient:
|
||||
def __init__(self, **kwargs):
|
||||
captured["client"] = kwargs
|
||||
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
||||
async def __aexit__(self, *_args):
|
||||
return None
|
||||
|
||||
async def post(self, url, json, headers):
|
||||
captured.update(url=url, json=json, headers=headers)
|
||||
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"}})
|
||||
response = client.post(
|
||||
"/media/handoff",
|
||||
headers={"Authorization": "Bearer test-token"},
|
||||
json={
|
||||
"action": "start",
|
||||
"category": "serien4k",
|
||||
"directory": "/usenet/complete/serien4k/Show.S01E01",
|
||||
"release": "Show.S01E01-GRP",
|
||||
"cleanName": "Show S01E01",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["state"] == "registered"
|
||||
assert captured["url"] == "http://n8n:5678/webhook/media-handoff"
|
||||
assert captured["json"]["category"] == "serien4k"
|
||||
|
||||
|
||||
def test_media_handoff_rejects_untrusted_caller_before_proxy(monkeypatch):
|
||||
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",
|
||||
json={"action": "status", "jobId": "test-job-1234"},
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_media_handoff_rejects_wrong_category_path(monkeypatch):
|
||||
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": "video4k",
|
||||
"directory": "/usenet/complete/serien4k/Wrong",
|
||||
"release": "Wrong",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 422
|
||||
|
||||
|
||||
def test_paperless_import_queues_pdf_through_butler(monkeypatch):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue