Files
rippy/docker/worker/test_notify.py
T
Hitonabi e032a9df1c feat(backend): Media-Server-Aufbereitung, echte Webhooks, SMB-Klartext, UHD-Arbeitsverzeichnis, MakeMKV-Key via UI
- jobs.meta (Migration in beiden db.py): Disc-Metadaten wandern in den Job —
  Quelle fuer Job-Detail-Popup (GET /jobs/{id}/detail), Ordner-Benennung, NFO.
- medien.py (Worker, mit Tests): Zielordner 'Titel (Jahr)' statt Job-UUID;
  movie.nfo/tvshow.nfo (Kodi-Schema, kodi.wiki/view/NFO_files) + poster.jpg
  fuer jellyfin/emby/kodi; plex nur Benennung; Kollision -> Job-ID-Suffix.
- notify.py (identisch in API+Worker, mit Tests): Webhook bei Job-Ende —
  Discord ({content}, discord.com/developers), Slack ({text},
  api.slack.com/messaging/webhooks), ntfy (Rohtext + ?title=, docs.ntfy.sh),
  generisches JSON. Vorher war das Setting ein Placebo: nichts sendete je.
  POST /notifications/test beweist die Anbindung sofort.
- mounts.py: NT_STATUS-Fehler -> handelbarer Klartext (ACCESS_DENIED ohne
  Credentials = Gast-Abfrage verweigert), Timeout-Meldung, mount-Hinweis
  bei error(13). Mit Tests.
- tasks.py: Platz-Check per Disc-Groesse (ioctl BLKGETSIZE64) VOR dem Rip;
  Arbeitsverzeichnis workDir (unter /app/media, z.B. NAS) statt fix
  /app/temp/raw — 4K-UHD-Rohdaten (bis 100 GB) sprengen sonst die VM-Platte;
  MakeMKV-Key aus UI-Settings (~/.MakeMKV/settings.conf, Format wie
  entrypoint.sh) gilt ab dem naechsten Rip ohne Rebuild.
- caps.py: Werkzeug-Versionen (MakeMKV aus ENV MAKEMKV_VERSION im Image,
  makemkvcon hat keinen --version-Schalter lt. usage.txt; HandBrakeCLI
  --version lt. handbrake.fr/docs) + Key-Quelle; workers.info-Spalte.
- /browse liefert jetzt auch DATEIEN (Name + Groesse) — der 'leere'
  bluray-Ordner war voll, der Browser zeigte nur Unterordner.
- GET /system/info: Versionen, Plattenplatz, Key-/Webhook-Status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:55:22 +02:00

39 lines
1.4 KiB
Python

"""Tests für die Webhook-Benachrichtigungen (Typ-Erkennung + Payload-Bau)."""
from notify import baue_payload, erkenne_webhook_typ
def test_discord_wird_an_url_erkannt():
assert erkenne_webhook_typ("https://discord.com/api/webhooks/1/abc") == "discord"
assert erkenne_webhook_typ("https://discordapp.com/api/webhooks/1/abc") == "discord"
def test_slack_und_ntfy_und_generisch():
assert erkenne_webhook_typ("https://hooks.slack.com/services/T/B/x") == "slack"
assert erkenne_webhook_typ("https://ntfy.sh/mein-thema") == "ntfy"
assert erkenne_webhook_typ("https://ha.local/api/webhook/rippy") == "generisch"
def test_discord_payload_nutzt_content():
typ, payload = baue_payload("https://discord.com/api/webhooks/1/a", "Titel", "Text")
assert typ == "discord"
assert payload == {"content": "**Titel**\nText"}
def test_slack_payload_nutzt_text():
typ, payload = baue_payload("https://hooks.slack.com/services/x", "Titel", "Text")
assert typ == "slack"
assert payload == {"text": "*Titel*\nText"}
def test_ntfy_sendet_rohtext():
typ, payload = baue_payload("https://ntfy.sh/thema", "Titel", "Text")
assert typ == "ntfy"
assert payload is None # Roh-Text-Body, kein JSON
def test_generischer_payload_traegt_level():
typ, payload = baue_payload("https://example.org/hook", "Titel", "Text", "error")
assert typ == "generisch"
assert payload == {"title": "Titel", "message": "Text", "level": "error"}