fix(tests): fix veto bug preventing disputed state, add manager notification and dispute-resolution routing
This commit is contained in:
@@ -401,9 +401,32 @@ def test_dual_validation_red_rejects():
|
||||
|
||||
|
||||
def test_dual_validation_blue_rejects():
|
||||
"""Red already approved; Blue then rejects — a genuine conflict, not a veto."""
|
||||
e = _entity("in_review")
|
||||
e.validate_red("approved", by=uuid.uuid4())
|
||||
e.validate_blue("rejected", by=uuid.uuid4())
|
||||
assert e.state == TestState.disputed
|
||||
assert any(ev.name == "dual_validation_disputed" for ev in e.events)
|
||||
|
||||
|
||||
def test_dual_validation_blue_approved_then_red_rejects():
|
||||
"""Blue already approved; Red then rejects — also a genuine conflict."""
|
||||
e = _entity("in_review")
|
||||
e.validate_blue("approved", by=uuid.uuid4())
|
||||
e.validate_red("rejected", by=uuid.uuid4())
|
||||
assert e.state == TestState.disputed
|
||||
|
||||
|
||||
def test_dual_validation_both_rejected_from_disputed():
|
||||
"""A disputed test where the approving lead flips to reject (via the
|
||||
plain validate call, not resolve_dispute_reject) still lands on the
|
||||
generic terminal 'rejected' state — both leads now agree it's bad."""
|
||||
e = _entity(
|
||||
"disputed",
|
||||
red_validation_status="approved",
|
||||
blue_validation_status="rejected",
|
||||
)
|
||||
e.validate_red("rejected", by=uuid.uuid4())
|
||||
assert e.state == TestState.rejected
|
||||
|
||||
|
||||
@@ -561,3 +584,52 @@ def test_is_terminal():
|
||||
assert _entity("validated").is_terminal is True
|
||||
assert _entity("rejected").is_terminal is False
|
||||
assert _entity("draft").is_terminal is False
|
||||
|
||||
|
||||
# ── 13. resolve_dispute_reject ──────────────────────────────────────
|
||||
|
||||
|
||||
def test_resolve_dispute_reject_to_red():
|
||||
e = _entity(
|
||||
"disputed",
|
||||
red_validation_status="approved",
|
||||
red_validated_by=uuid.uuid4(),
|
||||
red_validated_at=datetime.utcnow(),
|
||||
blue_validation_status="rejected",
|
||||
blue_validated_by=uuid.uuid4(),
|
||||
blue_validated_at=datetime.utcnow(),
|
||||
red_paused_seconds=50,
|
||||
)
|
||||
e.resolve_dispute_reject("red")
|
||||
assert e.state == TestState.red_executing
|
||||
assert e.red_validation_status is None
|
||||
assert e.red_validated_by is None
|
||||
assert e.blue_validation_status is None
|
||||
assert e.blue_validated_by is None
|
||||
assert e.red_started_at is not None
|
||||
assert e.red_paused_seconds == 0
|
||||
assert any(ev.name == "dispute_resolved_to_rework" and ev.payload["target"] == "red" for ev in e.events)
|
||||
|
||||
|
||||
def test_resolve_dispute_reject_to_blue():
|
||||
e = _entity(
|
||||
"disputed",
|
||||
blue_validation_status="approved",
|
||||
blue_validated_by=uuid.uuid4(),
|
||||
red_validation_status="rejected",
|
||||
red_validated_by=uuid.uuid4(),
|
||||
blue_paused_seconds=20,
|
||||
)
|
||||
e.resolve_dispute_reject("blue")
|
||||
assert e.state == TestState.blue_evaluating
|
||||
assert e.red_validation_status is None
|
||||
assert e.blue_validation_status is None
|
||||
assert e.blue_started_at is not None
|
||||
assert e.blue_paused_seconds == 0
|
||||
assert any(ev.name == "dispute_resolved_to_rework" and ev.payload["target"] == "blue" for ev in e.events)
|
||||
|
||||
|
||||
def test_resolve_dispute_reject_wrong_state():
|
||||
e = _entity("in_review")
|
||||
with pytest.raises(InvalidStateTransition):
|
||||
e.resolve_dispute_reject("red")
|
||||
|
||||
Reference in New Issue
Block a user