Skip to content

Commit

Permalink
TP2000-1084 Archive empty, previously queued workbaskets on attempt t…
Browse files Browse the repository at this point in the history
…o delete (#1107)

* Prevent non-empty workbaskets from being archived

* Archive previously queued workbaskets rather than attempt to delete

* Amend workbasket archive transition

* Mock envelope creation task
  • Loading branch information
dalecannon authored Nov 30, 2023
1 parent c5fe135 commit 8d1332c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
5 changes: 5 additions & 0 deletions workbaskets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,15 @@ def approved(self):
def __str__(self):
return f"({self.pk}) [{self.status}]"

def archive_workbasket_condition_is_empty(self) -> bool:
"""Django FSM condition: workbasket must be empty (no tracked models and no transactions) to transition to ARCHIVED status."""
return not self.tracked_models.exists() and not self.transactions.exists()

@transition(
field=status,
source=WorkflowStatus.EDITING,
target=WorkflowStatus.ARCHIVED,
conditions=[archive_workbasket_condition_is_empty],
custom={"label": "Archive"},
)
def archive(self):
Expand Down
12 changes: 12 additions & 0 deletions workbaskets/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ def test_workbasket_transition_methods(method, source, target):
assert wb.status == getattr(WorkflowStatus, target)


def test_workbasket_transition_archive_not_empty():
"""Tests that a non-empty workbasket cannot be transitioned to ARCHIVED
status."""
workbasket = factories.WorkBasketFactory.create(status=WorkflowStatus.EDITING)
footnote = factories.FootnoteFactory.create(
transaction=workbasket.new_transaction(),
)
with pytest.raises(TransitionNotAllowed):
workbasket.archive()
assert workbasket.status == WorkflowStatus.EDITING


def test_queue(valid_user, unapproved_checked_transaction):
"""Test that approve transitions workbasket from EDITING to QUEUED, setting
approver and shifting transaction from DRAFT to REVISION partition."""
Expand Down
37 changes: 37 additions & 0 deletions workbaskets/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from unittest.mock import mock_open
from unittest.mock import patch

import factory
import pytest
from bs4 import BeautifulSoup
from django.contrib.auth.models import Permission
Expand Down Expand Up @@ -1824,6 +1825,42 @@ def test_application_access_after_workbasket_delete(
assert not page.select("header nav a.workbasket-link")


def test_workbasket_delete_previously_queued_workbasket(
valid_user_client,
valid_user,
):
"""Tests that an empty, previously queued workbasket transitions to ARCHIVED
status when a user attempts to delete the workbasket."""

valid_user.user_permissions.add(
Permission.objects.get(codename="delete_workbasket"),
)

with patch(
"publishing.tasks.create_xml_envelope_file.apply_async",
return_value=MagicMock(id=factory.Faker("uuid4")),
):
packaged_workbasket = factories.QueuedPackagedWorkBasketFactory.create()
packaged_workbasket.abandon()

workbasket = packaged_workbasket.workbasket
workbasket.transactions.all().delete()

url = reverse(
"workbaskets:workbasket-ui-delete",
kwargs={"pk": workbasket.pk},
)
response = valid_user_client.post(url, {})
assert response.status_code == 302
assert response.url == reverse(
"workbaskets:workbasket-ui-delete-done",
kwargs={"deleted_pk": workbasket.pk},
)

workbasket.refresh_from_db()
assert workbasket.status == WorkflowStatus.ARCHIVED


def test_workbasket_compare_200(valid_user_client, session_workbasket):
url = reverse("workbaskets:workbasket-check-ui-compare")
response = valid_user_client.get(url)
Expand Down
7 changes: 6 additions & 1 deletion workbaskets/views/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from measures.models import Measure
from notifications.models import Notification
from notifications.models import NotificationTypeChoices
from publishing.models import PackagedWorkBasket
from quotas.models import QuotaOrderNumber
from regulations.models import Regulation
from workbaskets import forms
Expand Down Expand Up @@ -1039,7 +1040,11 @@ def post(self, request, *args, **kwargs):
return self.form_invalid(form)

def form_valid(self, form):
self.object.delete()
if not PackagedWorkBasket.objects.filter(workbasket=self.object).exists():
self.object.delete()
else:
self.object.archive()
self.object.save()
return redirect(self.get_success_url())


Expand Down

0 comments on commit 8d1332c

Please sign in to comment.