50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
import pytest
|
|
from app.pipeline.state_machine import (
|
|
next_state_on_approve, next_state_on_reject, can_transition, STEPS, USER_GATES,
|
|
)
|
|
|
|
|
|
def test_steps_sequence():
|
|
assert STEPS == ["cover", "video", "thumb", "meta", "review", "publish"]
|
|
|
|
|
|
def test_user_gates_excludes_review():
|
|
assert "review" not in USER_GATES
|
|
assert "publish" in USER_GATES
|
|
assert "cover" in USER_GATES
|
|
|
|
|
|
def test_approve_progression():
|
|
assert next_state_on_approve("cover_pending") == "video_pending"
|
|
assert next_state_on_approve("video_pending") == "thumb_pending"
|
|
assert next_state_on_approve("thumb_pending") == "meta_pending"
|
|
assert next_state_on_approve("meta_pending") == "ai_review"
|
|
assert next_state_on_approve("publish_pending") == "publishing"
|
|
|
|
|
|
def test_approve_invalid_state_raises():
|
|
with pytest.raises(ValueError):
|
|
next_state_on_approve("ai_review") # 자동 전이 — approve 호출 자체가 무효
|
|
|
|
|
|
def test_reject_keeps_same_state():
|
|
# 반려는 같은 *_pending 상태를 유지(재생성 트리거)
|
|
assert next_state_on_reject("cover_pending") == "cover_pending"
|
|
assert next_state_on_reject("publish_pending") == "publish_pending"
|
|
|
|
|
|
def test_can_transition_blocks_terminal_states():
|
|
assert not can_transition("published", "cover_pending")
|
|
assert not can_transition("cancelled", "cover_pending")
|
|
assert not can_transition("failed", "cover_pending")
|
|
|
|
|
|
def test_can_transition_allows_cancel_from_anywhere():
|
|
assert can_transition("cover_pending", "cancelled")
|
|
assert can_transition("publishing", "cancelled")
|
|
|
|
|
|
def test_can_transition_allows_failed_from_pending():
|
|
assert can_transition("video_pending", "failed")
|
|
assert can_transition("publishing", "failed")
|