Files
rippy/src/rippy/test_einrichtung.py
T
HitonabiandClaude Opus 5 678fe276f9
Ampel / ampel (push) Successful in 1m18s
feat(windows): Arbeitsordner im Setup, Beta-Key auf Knopfdruck
Zwei Wuensche des Commanders vom 28.08.2026.

## 1. „kannst du noch einbauen das man den arbeitsordner usw. in den
##     Einstellungen setzen kann und direkt im setup?"

In den Einstellungen ging es seit 35370fd (freies Pfadfeld plus die Laufwerke
als Ein-Klick-Wahl). Im SETUP wurde bisher nur nach Programmordner und Ablage
gefragt — der Arbeitsordner tauchte erst auf, wenn schon installiert war.

Das ist die falsche Reihenfolge: Der Roh-Rip einer 4K-UHD ist bis zu 100 GB
gross. Wer erst NACH der ersten vollen Platte erfaehrt, wo die liegen, hat es
zu spaet erfahren — genau so lief am 25.07.2026 die VM-Platte voll.

Neu ist auch ein Waechter, der alle drei Arten von halb angeschlossenem Feld
faengt (kein Eingabefeld, keine Vorbelegung, wird beim Installieren nicht
mitgeschickt). Der dritte Fall ist der gemeinste: Man waehlt etwas, es
passiert nichts, und niemand sagt warum.

## 2. „der könnte theoretisch auch automatisch ausgelesen werden, ich glaube
##     das web rippy kann das"

Er hatte recht. `makemkv_key.refresh_loop()` laeuft seit jeher taeglich mit
(main.py, Startereignis). GEMESSEN am 28.08.2026: Forum antwortet in 3,3 s,
gueltiger Key mit 62 Zeichen, und in seinen Einstellungen lag bereits einer.

Es war nur nichts davon zu sehen. Kein Knopf, keine Meldung, keine Zeitangabe
— im Feld stand ein Key, und ob der von Hand kam oder von selbst, wusste
niemand. Eine Automatik, die man nicht sehen kann, ist fuer den Benutzer
keine.

Dazu kam eine echte Luecke: Die Schleife startet 60 Sekunden nach dem Server.
Wer gleich nach dem Einrichten eine Blu-ray einlegt, rippt ohne Key — MakeMKV
faellt in den 30-Tage-Testmodus. Das Setup holt ihn jetzt selbst.

Der geholte Key wandert NICHT ueber die Leitung zurueck: Er steht in den
Einstellungen, und ein zweiter Weg zu demselben Wert ist ein zweiter Weg, ihn
zu verlieren.

Rechtlich unveraendert: oeffentliche Beta-LIZENZ der Software, KEIN
Disc-Schluessel. Rippy liefert und verteilt keine Disc-Schluessel.

803 Tests gruen, ruff sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 11:53:12 +02:00

282 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Der Einrichtungs-Assistent — die Pruefungen, ohne etwas zu installieren.
## Warum es diese Tests gibt
Commander am 28.08.2026: *„Dann haette ich beim Setup' auch erwartet das nen
echtes setup passiert — wo will ich das hinspeichern, nen pre requirement
check usw. Da kommt garnichts Rippy geht einfach auf."*
Er hatte recht: Ein Doppelklick installierte stillschweigend und oeffnete das
Fenster. Der Nutzer wurde nichts gefragt und erfuhr nichts.
Alle Pruefungen sind eingespritzt — kein Fenster, keine Installation, kein
WebView2. Sonst waere „kein Laufwerk" nur auf einem Rechner ohne Laufwerk
pruefbar, und genau dort sieht es niemand.
"""
import os
from rippy import einrichtung as e
def _p(zustand, name="X"):
return {"name": name, "zustand": zustand, "text": "", "abhilfe": ""}
# ── Was blockiert und was nicht ─────────────────────────────────────────
def test_ohne_fehler_darf_installiert_werden():
assert e.darf_installieren([_p(e.OK), _p(e.WARNUNG)]) is True
def test_ein_fehler_blockiert():
assert e.darf_installieren([_p(e.OK), _p(e.FEHLER)]) is False
def test_eine_warnung_blockiert_NICHT():
"""Eine Warnung, die den Knopf sperrt, ist eine Bevormundung. Rippy ohne
optisches Laufwerk ist ein vorgesehener Betriebsfall — eine reine
Komprimier-Maschine."""
assert e.darf_installieren([_p(e.WARNUNG), _p(e.WARNUNG)]) is True
# ── Die einzelnen Pruefungen ────────────────────────────────────────────
def test_windows_10_und_11_gehen():
assert e.pruefe_windows(22631)["zustand"] == e.OK
assert e.pruefe_windows(19045)["zustand"] == e.OK
def test_zu_altes_windows_ist_ein_fehler():
befund = e.pruefe_windows(7601) # Windows 7
assert befund["zustand"] == e.FEHLER
assert befund["abhilfe"], "ein Befund ohne Abhilfe laesst den Nutzer ratlos"
def test_fehlendes_webview_ist_nur_eine_warnung():
"""Ohne WebView2 faellt Rippy auf den Browser zurueck. Das ist weniger
schoen, aber es LAEUFT — ein Fehler waere hier eine Luege."""
befund = e.pruefe_webview(version="")
assert befund["zustand"] == e.WARNUNG
assert "Browser" in befund["abhilfe"]
def test_vorhandenes_webview_ist_ok():
assert e.pruefe_webview(version="151.0.4129.107")["zustand"] == e.OK
def test_zu_wenig_platz_ist_ein_fehler():
befund = e.pruefe_platz("C:\\egal", frei_mb=100)
assert befund["zustand"] == e.FEHLER
assert "500" in befund["text"]
def test_genug_platz_ist_ok():
assert e.pruefe_platz("C:\\egal", frei_mb=5000)["zustand"] == e.OK
def test_fehlendes_schreibrecht_ist_ein_fehler():
"""`os.access(..., W_OK)` luegt unter Windows — es beantwortet die Frage
anhand des Nur-Lesen-Flags, nicht anhand der Zugriffsrechte. Deshalb wird
wirklich geschrieben."""
befund = e.pruefe_schreibrecht("C:\\Programme\\Rippy",
probe=(False, "Zugriff verweigert"))
assert befund["zustand"] == e.FEHLER
assert "Benutzer" in befund["abhilfe"]
def test_schreibprobe_am_echten_ordner(tmp_path):
befund = e.pruefe_schreibrecht(str(tmp_path))
assert befund["zustand"] == e.OK
# Und die Probe darf nichts hinterlassen.
assert list(tmp_path.iterdir()) == []
# ── Administrator und Netzlaufwerke ─────────────────────────────────────
def test_normal_gestartet_ist_der_richtige_zustand():
"""Rippy braucht KEINE Administratorrechte — Vorgabeordner unter
%LOCALAPPDATA%, Autostart unter HKCU."""
befund = e.pruefe_administrator(erhoeht=False)
assert befund["zustand"] == e.OK
def test_als_administrator_wird_vor_den_fehlenden_netzlaufwerken_gewarnt():
"""DER Befund des Commanders (28.08.2026): „Wenn man das Tool als Admin
startet, kann man im explorer kein netzlaufwerk waehlen."
Ein erhoehter Prozess bekommt ein anderes Zugriffstoken; eingebundene
Netzlaufwerke haengen am Token der Sitzung. Windows-Verhalten, kein
Rippy-Fehler — aber Rippy hat ihn hineinlaufen lassen."""
befund = e.pruefe_administrator(erhoeht=True, laufwerke=["X:", "Y:", "Z:"])
assert befund["zustand"] == e.WARNUNG
assert "X:" in befund["abhilfe"]
assert "UNC" in befund["abhilfe"] or "Server" in befund["abhilfe"]
def test_fehlendes_laufwerk_wird_beim_namen_genannt():
"""„Schreibrechte fehlen" war richtig im Wortlaut und unbrauchbar als
Auskunft: Das Laufwerk war fuer den erhoehten Prozess gar nicht da."""
# `laufwerk_da=False` eingespritzt: Die Frage "existiert Q:" laesst sich
# auf dem Linux-Runner der Ampel gar nicht beantworten. Ohne den
# Einspritzpunkt waere dieser Zweig nur auf einem Windows-Rechner mit
# genau diesem fehlenden Laufwerk pruefbar -- also nirgends.
befund = e.pruefe_schreibrecht(
"Q:" + chr(92) + "Rippy", probe=(False, "Pfad nicht gefunden"),
erhoeht=True, laufwerk_da=False)
assert befund["zustand"] == e.FEHLER
assert "Q:" in befund["text"]
assert "nicht vorhanden" in befund["text"]
assert "Administrator" in befund["abhilfe"]
def test_programme_ordner_erklaert_den_teufelskreis():
"""Program Files verlangt Administrator, Administrator versteckt die
Netzlaufwerke — und Rippy braucht beides nicht."""
befund = e.pruefe_schreibrecht(
"C:" + chr(92) + "Program Files (x86)" + chr(92) + "Rippy",
probe=(False, "Zugriff verweigert"))
assert befund["zustand"] == e.FEHLER
assert "Administratorrechte" in befund["abhilfe"]
assert "Vorgabeordner" in befund["abhilfe"]
def test_programme_wird_erkannt():
B = chr(92)
assert e._unter_programme("C:" + B + "Program Files" + B + "Rippy") is True
assert e._unter_programme("C:" + B + "Program Files (x86)" + B + "R") is True
assert e._unter_programme("C:" + B + "Users" + B + "X" + B + "Rippy") is False
def test_belegter_port_ist_nur_eine_warnung():
"""Sehr oft ist es ein bereits laufendes Rippy — und dann ist eine
Neuinstallation genau richtig."""
befund = e.pruefe_port(7788, belegt=True)
assert befund["zustand"] == e.WARNUNG
assert "Rippy" in befund["abhilfe"]
def test_freier_port_ist_ok():
assert e.pruefe_port(7788, belegt=False)["zustand"] == e.OK
def test_kein_laufwerk_ist_nur_eine_warnung():
"""install.sh sagt seit Langem: ohne Laufwerk „laeuft trotzdem durch, dann
ist das eine reine KOMPRIMIER-Maschine"."""
befund = e.pruefe_laufwerk(laufwerke=[])
assert befund["zustand"] == e.WARNUNG
assert "komprimieren" in befund["abhilfe"]
def test_gefundenes_laufwerk_wird_genannt():
befund = e.pruefe_laufwerk(laufwerke=["\\\\.\\G:"])
assert befund["zustand"] == e.OK
assert "G:" in befund["text"]
# ── Die Werkzeuge ───────────────────────────────────────────────────────
def _bestand(makemkv, handbrake):
return {
"makemkv": {"titel": "MakeMKV", "da": makemkv, "version": "1.18.4",
"pflicht": True},
"handbrake": {"titel": "HandBrakeCLI", "da": handbrake,
"version": "1.11.2", "pflicht": False},
}
def test_fehlendes_makemkv_ist_eine_warnung_mit_ausweg():
befunde = {b["name"]: b for b in e.pruefe_werkzeuge(_bestand(False, True))}
assert befunde["MakeMKV"]["zustand"] == e.WARNUNG
assert "makemkv.com" in befunde["MakeMKV"]["abhilfe"]
def test_fehlendes_handbrake_ist_kein_problem():
"""Es liegt im Paket — das Setup legt es beim Installieren daneben."""
befunde = {b["name"]: b for b in e.pruefe_werkzeuge(_bestand(True, False))}
assert befunde["HandBrakeCLI"]["zustand"] == e.OK
assert "mitgeliefert" in befunde["HandBrakeCLI"]["text"]
def test_vorhandene_werkzeuge_zeigen_ihre_version():
befunde = {b["name"]: b for b in e.pruefe_werkzeuge(_bestand(True, True))}
assert befunde["MakeMKV"]["text"] == "1.18.4"
# ── Die Zusammenfassung ─────────────────────────────────────────────────
def test_zusammenfassung_nennt_die_fehler_beim_namen():
text = e.zusammenfassung([_p(e.FEHLER, "Speicherplatz"), _p(e.OK, "Port")])
assert "nicht möglich" in text
assert "Speicherplatz" in text
def test_zusammenfassung_nennt_die_hinweise():
text = e.zusammenfassung([_p(e.WARNUNG, "MakeMKV"), _p(e.OK, "Port")])
assert "MakeMKV" in text
assert "nicht möglich" not in text
def test_alles_gruen_sagt_es_auch_so():
assert e.zusammenfassung([_p(e.OK), _p(e.OK)]) == "Alles bereit."
def test_jede_pruefung_hat_dieselbe_form():
"""Ein fehlendes Feld waere in der Oberflaeche ein `undefined`."""
for befund in ([e.pruefe_windows(22631), e.pruefe_webview(version=""),
e.pruefe_administrator(erhoeht=True, laufwerke=["X:"]),
e.pruefe_administrator(erhoeht=False),
e.pruefe_laufwerk(laufwerke=[]),
e.pruefe_platz("C:\\x", frei_mb=9999),
e.pruefe_port(7788, belegt=False)]
+ e.pruefe_werkzeuge(_bestand(False, False))):
assert set(befund) == {"name", "zustand", "text", "abhilfe"}, befund
assert befund["zustand"] in (e.OK, e.WARNUNG, e.FEHLER)
if befund["zustand"] != e.OK:
assert befund["abhilfe"], (
"%s sagt nicht, was zu tun ist" % befund["name"])
# ── Die Vorgaben ────────────────────────────────────────────────────────
def test_vorgaben_sind_vollstaendig():
if os.name != "nt":
import pytest
pytest.skip("Registry-Vorgaben gibt es nur unter Windows")
v = e.vorgaben()
assert set(v) == {"ziel", "ablage", "arbeit", "port", "autostart",
"verknuepfungen", "werkzeuge_holen"}
assert v["port"] == 7788
assert v["ziel"] and v["ablage"] and v["arbeit"]
for feld in ("ablage", "arbeit"):
assert "/app/" not in v[feld], "Container-Pfad in einer Windows-Vorgabe"
def test_netzwerkpfad_als_administrator_wird_erklaert():
"""Der zweite Teil des Befunds: Auch Netz-ANMELDUNGEN haengen am Token
der Sitzung. Ein erhoehter Prozess kennt die Zugangsdaten zur Freigabe
nicht und bekommt 'Zugriff verweigert' -- dieselbe Meldung wie bei einem
echten Rechteproblem."""
B = chr(92)
befund = e.pruefe_schreibrecht(
B + B + "NAS" + B + "Filme", probe=(False, "Zugriff verweigert"),
erhoeht=True)
assert befund["zustand"] == e.FEHLER
assert "ohne Administrator" in befund["abhilfe"]
def test_netzwerkpfad_ohne_administrator_bekommt_die_normale_meldung():
B = chr(92)
befund = e.pruefe_schreibrecht(
B + B + "NAS" + B + "Filme", probe=(False, "Netzwerkpfad nicht gefunden"),
erhoeht=False)
assert befund["zustand"] == e.FEHLER
assert "Administrator" not in befund["abhilfe"] or "keine" in befund["abhilfe"]
def test_ein_vorhandenes_laufwerk_ist_kein_laufwerks_problem():
"""Sonst waere JEDER Schreibfehler auf C: ein 'Laufwerk fehlt'."""
B = chr(92)
assert e.laufwerk_fehlt("C:" + B + "Programme", vorhanden=True) is False
assert e.laufwerk_fehlt("Q:" + B + "Rippy", vorhanden=False) is True
def test_unc_und_posix_sind_keine_laufwerksbuchstaben():
B = chr(92)
assert e.laufwerk_fehlt(B + B + "NAS" + B + "Filme") is False
assert e.laufwerk_fehlt("/srv/rippy") is False