54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.automations.models import (
|
|
AutomationProposal,
|
|
NumericStateTrigger,
|
|
ProposalStatus,
|
|
ServiceAction,
|
|
)
|
|
from app.automations.store import AutomationStore
|
|
|
|
|
|
def proposal() -> AutomationProposal:
|
|
return AutomationProposal(
|
|
alias="Wohnzimmer bei Kälte heizen",
|
|
description="Aktiviert den Heizmodus unter 18 Grad.",
|
|
trigger=NumericStateTrigger(entity_id="sensor.living_room_temperature", below=18.0),
|
|
action=ServiceAction(
|
|
service="climate.set_temperature",
|
|
entity_id="climate.living_room",
|
|
data={"temperature": 21.0},
|
|
),
|
|
)
|
|
|
|
|
|
def test_store_persists_approval_and_exports_yaml(tmp_path: Path) -> None:
|
|
store = AutomationStore(tmp_path)
|
|
created = store.create(proposal())
|
|
approved = store.decide(created.proposal_id, ProposalStatus.APPROVED, 1)
|
|
yaml = AutomationStore(tmp_path).export_yaml(created.proposal_id)
|
|
assert approved.status is ProposalStatus.APPROVED
|
|
assert approved.revision == 2
|
|
assert "platform: numeric_state" in yaml
|
|
assert "service: climate.set_temperature" in yaml
|
|
assert "temperature: 21.0" in yaml
|
|
|
|
|
|
def test_store_requires_approval_and_current_revision(tmp_path: Path) -> None:
|
|
store = AutomationStore(tmp_path)
|
|
created = store.create(proposal())
|
|
with pytest.raises(ValueError, match="freigegebene"):
|
|
store.export_yaml(created.proposal_id)
|
|
with pytest.raises(ValueError, match="Revision"):
|
|
store.decide(created.proposal_id, ProposalStatus.APPROVED, 2)
|
|
|
|
|
|
def test_store_allows_only_one_decision(tmp_path: Path) -> None:
|
|
store = AutomationStore(tmp_path)
|
|
created = store.create(proposal())
|
|
store.decide(created.proposal_id, ProposalStatus.REJECTED, 1)
|
|
with pytest.raises(ValueError, match="bereits entschieden"):
|
|
store.decide(created.proposal_id, ProposalStatus.APPROVED, 2)
|