Add WLED plugin and backend tests

This commit is contained in:
2026-05-21 21:34:58 +02:00
parent 43242fd913
commit 195880078a
2 changed files with 562 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ from backend.services.pico import parse_pico_line
from backend.services.plugins import PluginContext, PluginManager
from plugins.clipboard_tools import ClipboardToolsPlugin
from plugins.http_requests import HTTPRequestsPlugin
from plugins.wled import WLEDPlugin
class DummyWs:
@@ -225,6 +226,151 @@ def test_http_request_plugin_posts_templated_json(tmp_path: Path):
assert json.loads(received["body"]) == {"button": "4", "event": "down"}
def test_wled_plugin_sends_power_brightness_and_color_payloads(tmp_path: Path):
received = []
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", "0"))
received.append({"path": self.path, "body": json.loads(self.rfile.read(length).decode("utf-8"))})
self.send_response(200)
self.end_headers()
self.wfile.write(b'{"success":true}')
def log_message(self, *_args):
return None
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
db = Database(tmp_path / "streamdeck.sqlite")
plugin = WLEDPlugin()
base_config = {"device_ip": f"127.0.0.1:{server.server_port}"}
plugin.execute_action(PluginContext(DummyApp(db)), "power", base_config | {"state": "toggle"}, None)
plugin.execute_action(PluginContext(DummyApp(db)), "brightness", base_config | {"brightness": 50}, None)
plugin.execute_action(
PluginContext(DummyApp(db)),
"color",
base_config | {"segment_id": 2, "color": "#0f8", "brightness": 25},
None,
)
finally:
server.shutdown()
thread.join(timeout=5)
assert [item["path"] for item in received] == ["/json/state", "/json/state", "/json/state"]
assert received[0]["body"] == {"on": "t"}
assert received[1]["body"] == {"bri": 128}
assert received[2]["body"] == {"seg": [{"id": 2, "col": ["00FF88"], "bri": 64}]}
def test_wled_plugin_pixel_range_scales_color_for_range_brightness(tmp_path: Path):
received = {}
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", "0"))
received["body"] = json.loads(self.rfile.read(length).decode("utf-8"))
self.send_response(200)
self.end_headers()
self.wfile.write(b"{}")
def log_message(self, *_args):
return None
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
db = Database(tmp_path / "streamdeck.sqlite")
WLEDPlugin().execute_action(
PluginContext(DummyApp(db)),
"pixel_range",
{
"device_ip": f"127.0.0.1:{server.server_port}",
"segment_id": 1,
"start_pixel": 10,
"stop_pixel": 18,
"color": "#336699",
"brightness": 50,
},
None,
)
finally:
server.shutdown()
thread.join(timeout=5)
assert received["body"] == {"seg": [{"id": 1, "i": [10, 18, "1A334D"]}]}
def test_wled_mega_update_combines_effect_color_range_and_extra_json(tmp_path: Path):
received = []
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/json/eff":
body = json.dumps(["Solid", "Blink", "Rainbow"]).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(body)
return
self.send_response(404)
self.end_headers()
def do_POST(self):
length = int(self.headers.get("Content-Length", "0"))
received.append(json.loads(self.rfile.read(length).decode("utf-8")))
self.send_response(200)
self.end_headers()
self.wfile.write(b"{}")
def log_message(self, *_args):
return None
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
db = Database(tmp_path / "streamdeck.sqlite")
WLEDPlugin().execute_action(
PluginContext(DummyApp(db)),
"mega_update",
{
"device_ip": f"http://127.0.0.1:{server.server_port}",
"power": "on",
"global_brightness": 80,
"segment_id": 0,
"color": "#112233",
"segment_brightness": 40,
"effect": "Rainbow",
"speed": 120,
"intensity": 200,
"pixel_start": 0,
"pixel_stop": 8,
"pixel_color": "#ff0000",
"pixel_brightness": 25,
"extra_json": '{"transition":4}',
},
None,
)
finally:
server.shutdown()
thread.join(timeout=5)
assert received == [
{"on": True, "bri": 204},
{
"on": True,
"bri": 204,
"seg": [{"id": 0, "col": ["112233"], "bri": 102, "fx": 2, "sx": 120, "ix": 200, "i": [0, 8, "400000"]}],
"transition": 4,
}
]
def test_clipboard_plugin_copy_renders_event_tokens(tmp_path: Path):
db = Database(tmp_path / "streamdeck.sqlite")
plugin = ClipboardToolsPlugin()