Durchsicht: Robustheit bei Neuinstallationen
- auth.py: .env auch in schreibgeschütztem Ordner aktualisieren (Server-Login) - Controller: ohne Spotify-Login warten statt abstürzen; Playlist darf fehlen; nicht abspielbare Wünsche überspringen statt hängen zu bleiben - install-server.sh: alle SSH-Ports freigeben (kein Aussperren), curl und python3-systemd (fail2ban) installieren - install-player.sh: Bluetooth per rfkill entsperren und Dienst starten Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""Tests für Schutzmaßnahmen: nicht abspielbare Wünsche, .env in schreibgeschütztem Ordner."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
from auth import env_lesen, env_setzen # noqa: E402
|
||||
from controller import Controller, Playlist # noqa: E402
|
||||
from server_client import Wunsch # noqa: E402
|
||||
from spotify_client import SpotifyFehler # noqa: E402
|
||||
|
||||
TITEL = [f"spotify:track:{i:022d}" for i in range(5)]
|
||||
WUNSCH = "spotify:track:" + "W" * 22
|
||||
|
||||
|
||||
class FakeSpotify:
|
||||
def __init__(self, wunsch_status="ok"):
|
||||
self.wunsch_status = wunsch_status
|
||||
|
||||
def playlist_titel(self, playlist_id):
|
||||
return list(TITEL)
|
||||
|
||||
def titel(self, uri):
|
||||
if uri == WUNSCH and self.wunsch_status == "404":
|
||||
raise SpotifyFehler(404, "nicht gefunden")
|
||||
if uri == WUNSCH and self.wunsch_status == "503":
|
||||
raise SpotifyFehler(503, "kurz weg")
|
||||
return {"uri": uri, "name": "x", "artists": [{"name": "y"}],
|
||||
"is_playable": not (uri == WUNSCH and self.wunsch_status == "gesperrt")}
|
||||
|
||||
|
||||
class FakeServer:
|
||||
def __init__(self):
|
||||
self.gespielt = []
|
||||
|
||||
def naechster_wunsch(self):
|
||||
return Wunsch(id=7, uri=WUNSCH)
|
||||
|
||||
def wunsch_gespielt(self, wunsch):
|
||||
self.gespielt.append(wunsch.id)
|
||||
|
||||
|
||||
def controller(sp, server):
|
||||
c = Controller(sp=sp, playlist=Playlist(sp, "liste"), server=server, n=1, geraetename="Audiofy", bt_mac=None)
|
||||
return c
|
||||
|
||||
|
||||
def test_abspielbarer_wunsch_wird_gespielt():
|
||||
server = FakeServer()
|
||||
assert controller(FakeSpotify("ok"), server).naechster_eintrag().quelle == "wish"
|
||||
assert server.gespielt == []
|
||||
|
||||
|
||||
def test_gesperrter_wunsch_wird_uebersprungen():
|
||||
for status in ("gesperrt", "404"):
|
||||
server = FakeServer()
|
||||
eintrag = controller(FakeSpotify(status), server).naechster_eintrag()
|
||||
assert eintrag.quelle == "playlist" and eintrag.uri in TITEL
|
||||
assert server.gespielt == [7], status # aus der Warteschlange genommen
|
||||
|
||||
|
||||
def test_voruebergehender_fehler_verwirft_wunsch_nicht():
|
||||
server = FakeServer()
|
||||
controller(FakeSpotify("503"), server).naechster_eintrag()
|
||||
assert server.gespielt == []
|
||||
|
||||
|
||||
def test_env_in_schreibgeschuetztem_ordner(tmp_path):
|
||||
"""Wie auf dem Server: Ordner gehört root, nur die .env dem Dienst-Benutzer."""
|
||||
env = tmp_path / ".env"
|
||||
env.write_text("SPOTIFY_CLIENT_ID=abc\n")
|
||||
os.chmod(env, 0o600)
|
||||
os.chmod(tmp_path, 0o500)
|
||||
try:
|
||||
env_setzen(env, "SPOTIFY_REFRESH_TOKEN", "neu")
|
||||
assert env_lesen(env) == {"SPOTIFY_CLIENT_ID": "abc", "SPOTIFY_REFRESH_TOKEN": "neu"}
|
||||
assert oct(env.stat().st_mode & 0o777) == "0o600"
|
||||
finally:
|
||||
os.chmod(tmp_path, 0o700)
|
||||
Reference in New Issue
Block a user