Skip to content

Commit

Permalink
feat(delete-worflow): move just not-empty statuses
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-herrero committed Nov 10, 2023
1 parent 88cb2b3 commit 2fa0020
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
5 changes: 1 addition & 4 deletions python/apps/taiga/src/taiga/workflows/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,7 @@ async def delete_workflow(
workflow = await get_workflow_or_404(project_id=project_id, workflow_slug=workflow_slug)
await check_permissions(permissions=DELETE_WORKFLOW, user=request.user, obj=workflow)

await workflows_services.delete_workflow(
workflow=workflow,
target_workflow_slug=query_params.move_to,
)
await workflows_services.delete_workflow(workflow=workflow, target_workflow_slug=query_params.move_to)


################################################
Expand Down
10 changes: 9 additions & 1 deletion python/apps/taiga/src/taiga/workflows/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from uuid import UUID

from asgiref.sync import sync_to_async
from taiga.base.db.models import QuerySet
from taiga.base.db.models import Count, QuerySet
from taiga.base.repositories import neighbors as neighbors_repositories
from taiga.base.repositories.neighbors import Neighbor
from taiga.projects.projects.models import Project, ProjectTemplate
Expand Down Expand Up @@ -187,6 +187,7 @@ class WorkflowStatusFilters(TypedDict, total=False):
workflow_id: UUID
workflow_slug: str
project_id: UUID
is_empty: bool


def _apply_filters_to_workflow_status_queryset(
Expand All @@ -204,6 +205,13 @@ def _apply_filters_to_workflow_status_queryset(
if "project_id" in filter_data:
filter_data["workflow__project_id"] = filter_data.pop("project_id")

if "is_empty" in filter_data:
qs = qs.annotate(num_stories=Count("stories"))
if filter_data.pop("is_empty"):
filter_data["num_stories"] = 0
else:
filter_data["num_stories__gt"] = 0

return qs.filter(**filter_data)


Expand Down
2 changes: 1 addition & 1 deletion python/apps/taiga/src/taiga/workflows/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ async def delete_workflow(workflow: Workflow, target_workflow_slug: str | None =
raise ex.SameMoveToWorkflow("The to-be-deleted workflow and the target-workflow cannot be the same")

statuses_to_move = await workflows_repositories.list_workflow_statuses(
filters={"workflow_id": workflow.id},
filters={"workflow_id": workflow.id, "is_empty": False},
order_by=["order"],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Copyright (c) 2023-present Kaleidos INC

import uuid
from unittest import IsolatedAsyncioTestCase

import pytest
from asgiref.sync import sync_to_async
Expand Down Expand Up @@ -131,18 +132,37 @@ async def test_create_workflow_status():
##########################################################


async def test_list_workflows_statuses_ok() -> None:
workflow = await f.create_workflow()
statuses = await repositories.list_workflow_statuses(filters={"workflow_id": workflow.id})

assert len(statuses) > 0


async def test_list_no_workflows_statuses() -> None:
workflow = await f.create_workflow(statuses=[])
statuses = await repositories.list_workflow_statuses(filters={"workflow_id": workflow.id})

assert len(statuses) == 0
class ListWorkflowStatuses(IsolatedAsyncioTestCase):
async def asyncSetUp(self):
self.empty_workflow = await f.create_workflow(statuses=[])
self.workflow = await f.create_workflow(statuses=[])
self.workflow_status = await f.create_workflow_status(workflow=self.workflow)
await f.create_story(status=self.workflow_status, workflow=self.workflow)
self.empty_workflow_status = await f.create_workflow_status(workflow=self.workflow)

async def test_list_workflows_statuses_ok(self) -> None:
statuses = await repositories.list_workflow_statuses(filters={"workflow_id": self.workflow.id})
assert len(statuses) > 0

async def test_list_no_workflows_statuses(self) -> None:
statuses = await repositories.list_workflow_statuses(filters={"workflow_id": self.empty_workflow.id})
assert len(statuses) == 0

async def test_list_empty_statuses(self) -> None:
statuses = await repositories.list_workflow_statuses(
filters={"workflow_id": self.workflow.id, "is_empty": True}
)
assert self.empty_workflow_status in statuses
assert self.workflow_status not in statuses
assert len(statuses) == 1

async def test_list_not_empty_statuses(self) -> None:
statuses = await repositories.list_workflow_statuses(
filters={"workflow_id": self.workflow.id, "is_empty": False}
)
assert self.workflow_status in statuses
assert self.empty_workflow_status not in statuses
assert len(statuses) == 1


##########################################################
Expand Down
4 changes: 2 additions & 2 deletions python/apps/taiga/tests/unit/taiga/workflows/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ async def test_delete_workflow_with_target_workflow_with_anchor_status_ok():
# asserts
fake_workflows_repo.list_workflow_statuses.assert_has_awaits(
[
call(filters={"workflow_id": deleted_workflow.id}, order_by=["order"]),
call(filters={"workflow_id": deleted_workflow.id, "is_empty": False}, order_by=["order"]),
call(filters={"workflow_id": target_workflow.id}, order_by=["-order"], offset=0, limit=1),
]
)
Expand Down Expand Up @@ -434,7 +434,7 @@ async def test_delete_workflow_with_target_workflow_with_no_anchor_status_ok():
# asserts
fake_workflows_repo.list_workflow_statuses.assert_has_awaits(
[
call(filters={"workflow_id": deleted_workflow.id}, order_by=["order"]),
call(filters={"workflow_id": deleted_workflow.id, "is_empty": False}, order_by=["order"]),
call(filters={"workflow_id": target_workflow.id}, order_by=["-order"], offset=0, limit=1),
]
)
Expand Down

1 comment on commit 2fa0020

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/taiga
   __main__.py71710%17–155
src/taiga/attachments
   admin.py27390%25, 28, 70
   events.py8275%15, 20
   models.py19289%61, 64
   repositories.py49197%62
src/taiga/auth/services
   __init__.py47098%90–>93
src/taiga/base
   mocks.py741280%93–94, 107–118, 143–>exit
src/taiga/base/api
   permissions.py49199%22
   requests.py11380%15, 21–23
src/taiga/base/db
   __init__.py4175%15
   commands.py52520%8–269
   sequences.py45297%91–92
src/taiga/base/db/admin
   forms.py14838%17–25
   utils.py11736%17–23
src/taiga/base/db/models
   fields.py15188%20
src/taiga/base/django
   __init__.py5260%17–19
   settings.py30293%16–17
   urls.py330%8–11
src/taiga/base/i18n
   __init__.py102988%171–>170, 173–>170, 192–193, 203–205, 215, 268, 279, 283
   choices.py34291%80, 87
   commands.py74740%8–108
src/taiga/base/logging
   formatters.py241050%22–>exit, 38, 44–45, 51–60
   middlewares.py23196%20
src/taiga/base/repositories
   neighbors.py39391%43–44, 65
src/taiga/base/sampledata
   commands.py11110%8–40
   constants.py15150%14–51
   demo_data.py2732730%8–529
   factories.py1221220%9–353
   test_data.py2902900%8–634
src/taiga/base/serializers
   fields.py34393%22, 47, 61
src/taiga/base/utils
   commands.py11110%8–30
   datetime.py441860%54, 67, 126–147
   enum.py14192%43
   images.py26387%21–22, 30
   json.py33963%31–>33, 33–>35, 37, 39–44, 46, 50
   pprint.py660%8–17
   slug.py23485%22–25
src/taiga/base/validators/fields
   i18n.py15195%19
   uuid.py14195%19
src/taiga/comments
   admin.py29392%16, 20, 24
   events.py11373%15, 20, 25
   models.py20291%43, 46
   notifications.py6183%16
src/taiga/commons/storage
   commands.py13130%8–40
   models.py16288%38, 41
   services.py9092%17–>16
   tasks.py990%8–19
src/taiga/conf
   __init__.py94395%112, 128–129
   tokens.py17190%34
src/taiga/emails
   commands.py35350%9–68
   sender.py18571%48–50, 54–73
   tasks.py39490%44–45, 53–54
src/taiga/events
   app.py18192%21
   events.py16288%31–32
   logging.py392331%18–>exit, 32–48, 51–60
   manager.py1171190%78–79, 223–233, 239–242
   responses.py33684%33, 37–41
   subscriber.py80495%51, 55, 88, 91, 108–>120
src/taiga/events/actions
   auth.py231144%27–32, 39–45
   event_handlers.py9456%18–20, 28–30
   projects.py553038%36–40, 48–64, 72–80, 88–96
   workspaces.py553038%36–40, 48–64, 72–80, 88–96
src/taiga/events/pubsub/backends
   base.py30198%53
   redis.py66594%41–43, 85–86
src/taiga/exceptions/api
   __init__.py27097%28–>30
   handlers.py27290%27–28
   middlewares.py26287%37, 41
src/taiga/integrations/auth
   services.py39782%50–56
src/taiga/integrations/github
   services.py40098%63–>68
src/taiga/mediafiles
   admin.py20291%24, 27
   models.py26292%84, 87
src/taiga/notifications
   admin.py11285%20, 23
   api.py33195%95
   repositories.py39196%80
   services.py30097%50–>53
src/taiga/permissions
   services.py103198%28, 106–>109
src/taiga/permissions/validators
   fields.py24388%18–19, 45
src/taiga/projects/invitations
   models.py25292%89, 92
   repositories.py84198%135
src/taiga/projects/invitations/api
   validators.py65789%38–40, 65–66, 84–85
src/taiga/projects/invitations/events
   __init__.py33191%37–>exit, 49–>exit, 74–>exit, 102
src/taiga/projects/invitations/services
   __init__.py183199%58–>53, 286
src/taiga/projects/memberships
   models.py16288%51, 54
   repositories.py86297%91, 124
src/taiga/projects/memberships/events
   __init__.py16288%18–24
src/taiga/projects/memberships/services
   __init__.py45195%64–>69, 111
src/taiga/projects/projects
   admin.py531275%33–34, 39–42, 50–51, 56–59, 90, 94
   models.py61886%64, 67, 78, 113, 116, 119–121
   repositories.py115496%125, 126–>129, 155, 254–255
   tasks.py6188%17
src/taiga/projects/projects/services
   __init__.py107592%78, 87, 199, 205–>208, 213, 235
src/taiga/projects/references
   mixins.py13093%25–>28
src/taiga/projects/roles
   api.py35393%46–48
   models.py26386%50, 53, 57
   repositories.py44196%92
src/taiga/projects/roles/services
   __init__.py25194%24, 57–>62
src/taiga/stories/assignments
   models.py15287%42, 45
   repositories.py52197%49
src/taiga/stories/assignments/notifications
   __init__.py18091%25–>27, 44–>46
src/taiga/stories/attachments
   api.py51197%159
   serializers.py11093%20–>28
src/taiga/stories/comments
   api.py59197%188
src/taiga/stories/comments/notifications
   __init__.py12094%19–>21
src/taiga/stories/stories
   admin.py25584%76–81, 85, 89
   models.py25292%73, 76
src/taiga/stories/stories/notifications
   __init__.py25091%27–>29, 49–>51, 72–>74
src/taiga/stories/stories/services
   __init__.py150298%251–>268, 312, 336
src/taiga/tasksqueue
   app.py20286%29–30
   commands.py65650%8–122
   logging.py331740%18–>exit, 29–39, 42–51
   manager.py561377%37, 41, 45, 49, 94, 163, 177, 186, 191, 198, 202, 209, 213
   task.py12192%23
src/taiga/tokens
   admin.py441081%67, 70, 73, 76, 104, 108, 112, 116, 120, 124
   models.py30487%59, 62, 78, 81
src/taiga/users
   admin.py51781%32, 41, 50, 87–95
   commands.py990%8–26
   models.py651086%71, 74, 90, 93, 97, 100, 103, 106, 127, 130
   repositories.py204398%209–>212, 335, 428–429
src/taiga/users/api
   __init__.py66296%216, 304
src/taiga/users/api/validators
   __init__.py42392%39–41
src/taiga/users/services
   __init__.py244795%75, 259, 262–>257, 297–>280, 306–>280, 322–>318, 345–>341, 366, 494–>499, 513–520, 521–>526, 524–525
src/taiga/workflows
   models.py40490%42, 45, 85, 88
src/taiga/workflows/services
   __init__.py156595%54, 233, 329, 373–>403, 380, 466–>475, 482
src/taiga/workspaces/invitations
   models.py24292%84, 87
   permissions.py9182%19
   repositories.py77198%123
src/taiga/workspaces/invitations/api
   validators.py18288%24–25
src/taiga/workspaces/invitations/events
   __init__.py25191%36–>exit, 60–>exit, 71
src/taiga/workspaces/invitations/services
   __init__.py123199%222
src/taiga/workspaces/memberships
   api.py43196%126
   models.py15287%43, 46
   repositories.py63295%72, 105
src/taiga/workspaces/memberships/services
   __init__.py46197%117
src/taiga/workspaces/workspaces
   admin.py571962%25–26, 31–34, 49, 52–57, 61, 65, 73–74, 79–82
   models.py18290%32, 35
   repositories.py127299%232–233
src/taiga/workspaces/workspaces/services
   __init__.py54294%113, 116
TOTAL10331154484% 

Tests Skipped Failures Errors Time
1188 1 💤 0 ❌ 0 🔥 24m 10s ⏱️

Please sign in to comment.