60 lines
2.2 KiB
Python
60 lines
2.2 KiB
Python
from pathlib import Path
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.automations.store import AutomationStore
|
|
from app.main import app
|
|
|
|
|
|
def _payload() -> dict[str, object]:
|
|
return {
|
|
"alias": "Licht bei Dunkelheit",
|
|
"description": "Schaltet das Flurlicht unter dem Helligkeitsgrenzwert ein.",
|
|
"trigger": {"entity_id": "sensor.hall_illuminance", "below": 10},
|
|
"action": {
|
|
"service": "light.turn_on",
|
|
"entity_id": "light.hall",
|
|
"data": {"brightness_pct": 40},
|
|
},
|
|
}
|
|
|
|
|
|
def test_proposal_requires_explicit_approval_before_yaml(tmp_path: Path) -> None:
|
|
with TestClient(app) as client:
|
|
app.state.automation_store = AutomationStore(tmp_path)
|
|
created = client.post("/v1/automations/proposals", json=_payload())
|
|
proposal_id = created.json()["proposal_id"]
|
|
blocked = client.get(f"/v1/automations/proposals/{proposal_id}/yaml")
|
|
approved = client.post(
|
|
f"/v1/automations/proposals/{proposal_id}/approve",
|
|
json={"expected_revision": 1},
|
|
)
|
|
exported = client.get(f"/v1/automations/proposals/{proposal_id}/yaml")
|
|
assert created.status_code == 201
|
|
assert created.json()["status"] == "draft"
|
|
assert blocked.status_code == 409
|
|
assert approved.json()["status"] == "approved"
|
|
assert "service: light.turn_on" in exported.text
|
|
|
|
|
|
def test_proposal_rejects_unsafe_service_domain(tmp_path: Path) -> None:
|
|
payload = _payload()
|
|
payload["action"] = {
|
|
"service": "shell_command.run",
|
|
"entity_id": "light.hall",
|
|
"data": {},
|
|
}
|
|
with TestClient(app) as client:
|
|
app.state.automation_store = AutomationStore(tmp_path)
|
|
response = client.post("/v1/automations/proposals", json=payload)
|
|
assert response.status_code == 422
|
|
|
|
|
|
def test_proposal_requires_numeric_threshold(tmp_path: Path) -> None:
|
|
payload = _payload()
|
|
payload["trigger"] = {"entity_id": "sensor.hall_illuminance"}
|
|
with TestClient(app) as client:
|
|
app.state.automation_store = AutomationStore(tmp_path)
|
|
response = client.post("/v1/automations/proposals", json=payload)
|
|
assert response.status_code == 422
|