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)