"""Unit tests for the instance state machine.""" import pytest from svcforge_core.domain.states import LEGAL, IllegalTransition, InstanceState, transition def test_requested_to_provisioning_is_legal() -> None: assert transition(InstanceState.REQUESTED, InstanceState.PROVISIONING) is InstanceState.PROVISIONING def test_deleted_to_ready_raises() -> None: with pytest.raises(IllegalTransition): transition(InstanceState.DELETED, InstanceState.READY) def test_failed_to_provisioning_is_legal_retry() -> None: assert transition(InstanceState.FAILED, InstanceState.PROVISIONING) is InstanceState.PROVISIONING @pytest.mark.parametrize("state", list(InstanceState)) def test_every_state_has_a_legal_entry(state: InstanceState) -> None: """A new state with no LEGAL entry must fail the suite, not KeyError at runtime.""" assert state in LEGAL assert isinstance(LEGAL[state], frozenset) @pytest.mark.parametrize("state", list(InstanceState)) def test_every_legal_target_is_an_instance_state(state: InstanceState) -> None: for target in LEGAL[state]: assert isinstance(target, InstanceState) def test_deleted_is_terminal_with_an_empty_frozenset() -> None: assert LEGAL[InstanceState.DELETED] == frozenset() def test_strenum_compares_equal_to_its_value() -> None: # mypy calls this non-overlapping by declared type. That is exactly what is being # tested: StrEnum members ARE their values at runtime, which is why psycopg can # adapt them straight to text and model_validate round-trips them for free. assert (InstanceState.READY == "ready") is True # type: ignore[comparison-overlap]