Files

89 lines
2.4 KiB
Python

# -*- coding: utf-8 -*-
"""Campaign status transitions must follow the approved state machine."""
import pytest
from adclaw.campaigns.models import CampaignSpec
from adclaw.campaigns.state import (
ALLOWED_TRANSITIONS,
EDITABLE_STATUSES,
CampaignStatus,
SyncStatus,
TransitionError,
next_status,
)
@pytest.mark.parametrize(
("current", "action", "expected"),
[
("draft", "submit", "pending_approval"),
("pending_approval", "approve", "approved"),
("pending_approval", "reject", "draft"),
("approved", "sync", "synced"),
("synced", "launch", "live"),
("paused", "launch", "live"),
("live", "pause", "paused"),
("live", "stop", "stopped"),
("paused", "stop", "stopped"),
("synced", "stop", "stopped"),
("stopped", "archive", "archived"),
],
)
def test_allowed_transitions(current, action, expected):
assert next_status(current, action) == expected
@pytest.mark.parametrize(
("current", "action"),
[
("draft", "approve"),
("draft", "launch"),
("approved", "launch"),
("archived", "launch"),
("live", "approve"),
],
)
def test_rejected_transitions(current, action):
with pytest.raises(TransitionError):
next_status(current, action)
def test_draft_cannot_reach_live_directly():
with pytest.raises(TransitionError):
next_status("draft", "launch")
def test_unknown_status_raises():
with pytest.raises(TransitionError):
next_status("bogus", "submit")
def test_editable_statuses():
assert EDITABLE_STATUSES == frozenset({"draft", "pending_approval"})
def test_allowed_transitions_keys_and_targets_are_valid_statuses():
valid_statuses = {status.value for status in CampaignStatus}
for current, actions in ALLOWED_TRANSITIONS.items():
assert current in valid_statuses
for target in actions.values():
assert target in valid_statuses
def test_enum_string_equality():
assert CampaignStatus.DRAFT == "draft"
assert SyncStatus.NOT_SYNCED == "not_synced"
def test_campaign_spec_defaults():
spec = CampaignSpec(id="c1", name="n")
assert spec.status == "draft"
assert spec.origin == "maskanx"
assert spec.sync_status == "not_synced"
assert spec.budget == {}
assert spec.guardrails == {}
assert spec.targeting == {}
assert spec.advanced == {}
assert spec.schedule == {}
assert spec.channels == []