Allow approval after draft revisions
This commit is contained in:
parent
829a0361d4
commit
ca045c02d7
2 changed files with 32 additions and 2 deletions
|
|
@ -648,9 +648,9 @@ class BookStateService:
|
|||
)
|
||||
if not validation["valid"]:
|
||||
raise ValueError("book state is not approval-valid: " + "; ".join(validation["errors"]))
|
||||
parent_id = _value(locked, "parent_id")
|
||||
current_id = _value(work, "current_book_state_id")
|
||||
if parent_id != current_id:
|
||||
approved_base_id = self._approved_base_id(locked)
|
||||
if approved_base_id != current_id:
|
||||
raise ValueError("book state parent is stale relative to the work's approved state")
|
||||
if force and not notes.strip():
|
||||
raise ValueError("forced approval requires notes")
|
||||
|
|
@ -684,6 +684,18 @@ class BookStateService:
|
|||
self._write_artifacts(locked)
|
||||
return locked
|
||||
|
||||
@staticmethod
|
||||
def _approved_base_id(state: BookStateVersion) -> Any:
|
||||
ancestor_id = state.parent_id
|
||||
while ancestor_id:
|
||||
ancestor = BookStateVersion.objects.select_for_update().only(
|
||||
"id", "parent_id", "status"
|
||||
).get(pk=ancestor_id)
|
||||
if ancestor.status == BookStateStatus.APPROVED:
|
||||
return ancestor.id
|
||||
ancestor_id = ancestor.parent_id
|
||||
return None
|
||||
|
||||
@transaction.atomic
|
||||
def reject(
|
||||
self, state: BookStateVersion, *, actor: str = "", notes: str = ""
|
||||
|
|
|
|||
|
|
@ -230,6 +230,24 @@ def test_approval_requires_all_reviews_and_rejects_stale_parent(work: Work) -> N
|
|||
service.approve(child)
|
||||
|
||||
|
||||
def test_approval_allows_review_revisions_before_first_approved_state(work: Work) -> None:
|
||||
service = BookStateService(FakeReviewRouter())
|
||||
first = service.create(work=work, content=book_content(1))
|
||||
second_content = deepcopy(first.content)
|
||||
second_content["open_questions"] = ["What must the pilot verify?"]
|
||||
second = service.revise(first, content=second_content)
|
||||
third_content = deepcopy(second.content)
|
||||
third_content["open_questions"] = ["What evidence resolves the review finding?"]
|
||||
third = service.revise(second, content=third_content)
|
||||
make_review_ready(third)
|
||||
|
||||
approved = service.approve(third, actor="editor")
|
||||
|
||||
work.refresh_from_db()
|
||||
assert approved.status == BookStateStatus.APPROVED
|
||||
assert work.current_book_state == approved
|
||||
|
||||
|
||||
def test_review_routes_structure_and_continuity_to_distinct_capabilities(work: Work) -> None:
|
||||
router = FakeReviewRouter()
|
||||
service = BookStateService(router)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue