tests/installer/test_hue_halo_light.py
Rama main · réplica de lectura del repositorio original.
"""Hue : l'installeur installe halo-light et apparie le bridge en https (le http est redirige)."""
import json
import stat
from types import SimpleNamespace
import pytest
from installer.core.catalog import load_catalog, resolve_placeholders
from installer.core.steps import mcps
@pytest.fixture(scope="module")
def hue():
return next(m for m in load_catalog() if m.id == "hue")
def test_catalogue_pointe_sur_halo_light(hue):
assert hue.name == "halo-light"
assert hue.repo == "git@github.com:amineutron/halo-light.git"
assert hue.dest.endswith("/mcp-servers/halo-light")
def test_serveur_est_un_executable_absolu_du_venv(hue):
"""modules/mcp.py n'accepte un binaire que sous forme de chemin absolu."""
server = resolve_placeholders(hue.server, {"lyra": "/opt/lyra", "dest": "/x", "bridge_ip": "192.0.2.7"})
assert server["command"] == "/opt/lyra/.venv/bin/halo-light"
assert server["command"].startswith("/")
assert server["args"] == ["serve"]
assert server["env"] == {"HUE_BRIDGE_IP": "192.0.2.7"}
def test_verification_sur_le_port_https(hue):
assert hue.check == {"type": "tcp", "host": "{bridge_ip}", "port": 443}
def test_url_de_pairing_en_https():
assert mcps.pairing_url("192.0.2.7") == "https://192.0.2.7/api"
# --------------------------------------------------------- config halo-light
def test_config_halo_light_ecrite_en_0600(tmp_path):
path = mcps.write_halo_light_config("192.0.2.7", "USER", "CK", environ={"XDG_CONFIG_HOME": str(tmp_path)})
assert path == tmp_path / "halo-light" / "config.json"
assert json.loads(path.read_text()) == {
"bridge_ip": "192.0.2.7", "app_key": "USER", "beat": {"username": "USER", "clientkey": "CK"},
}
assert stat.S_IMODE(path.stat().st_mode) == 0o600
assert stat.S_IMODE(path.parent.stat().st_mode) == 0o700
def test_config_halo_light_fusionne_sans_ecraser_la_zone(tmp_path):
env = {"XDG_CONFIG_HOME": str(tmp_path)}
path = tmp_path / "halo-light" / "config.json"
path.parent.mkdir(mode=0o700)
path.write_text(json.dumps({"beat": {"area_id": "AREA"}, "ca_cert": "/x.pem"}))
mcps.write_halo_light_config("192.0.2.7", "USER", "CK", environ=env)
data = json.loads(path.read_text())
assert data["beat"] == {"area_id": "AREA", "username": "USER", "clientkey": "CK"}
assert data["ca_cert"] == "/x.pem"
def test_config_halo_light_suit_halo_light_config(tmp_path):
target = tmp_path / "ailleurs" / "c.json"
path = mcps.write_halo_light_config("192.0.2.7", "U", "C", environ={"HALO_LIGHT_CONFIG": str(target)})
assert path == target and target.exists()
# ------------------------------------------------------------------- pairing
class _Broker:
def confirm(self, *_args, **_kwargs):
return True
def _ctx():
state = SimpleNamespace(device_config={"hue": {"bridge_ip": "192.0.2.7"}}, secrets={})
return SimpleNamespace(state=state, broker=_Broker(), emit=lambda *_a, **_k: None, step_id="hue")
class _Response:
def __init__(self, payload):
self._payload = payload
def json(self):
return self._payload
def test_pairing_utilise_https_sans_verifier_le_certificat_prive(monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
calls = []
def fake_post(url, **kwargs):
calls.append((url, kwargs))
return _Response([{"success": {"username": "USER", "clientkey": "CK"}}])
monkeypatch.setattr(mcps.requests, "post", fake_post)
ctx = _ctx()
mcps._hue_pairing(ctx, SimpleNamespace(id="hue"))
url, kwargs = calls[0]
assert url == "https://192.0.2.7/api"
assert kwargs["verify"] is False
assert kwargs["json"]["generateclientkey"] is True
assert ctx.state.secrets["hue"] == {"username": "USER", "clientkey": "CK"}
written = json.loads((tmp_path / "halo-light" / "config.json").read_text())
assert written["app_key"] == "USER" and written["bridge_ip"] == "192.0.2.7"