From 4d4f8a44a12f11addf690d2fc60fe62d8f9ea5c1 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 2 Aug 2016 13:13:33 +0200 Subject: [PATCH] Removing the bulk update order for epics and doing that processing on the update --- taiga/projects/epics/api.py | 60 ++++++++++++++++++----------- taiga/projects/epics/permissions.py | 1 - taiga/projects/epics/validators.py | 12 ------ tests/integration/test_epics.py | 24 +++++++++++- 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/taiga/projects/epics/api.py b/taiga/projects/epics/api.py index 5eba3406..f76d8c81 100644 --- a/taiga/projects/epics/api.py +++ b/taiga/projects/epics/api.py @@ -25,6 +25,7 @@ from taiga.base import exceptions as exc from taiga.base.decorators import list_route, detail_route from taiga.base.api import ModelCrudViewSet, ModelListViewSet from taiga.base.api.mixins import BlockedByProjectMixin +from taiga.base.utils import json from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.models import Project, EpicStatus @@ -89,11 +90,48 @@ class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, if obj.status and obj.status.project != obj.project: raise exc.WrongArguments(_("You don't have permissions to set this status to this epic.")) + """ + Updating the epic order attribute can affect the ordering of another epics + This method generate a key for the epic and can be used to be compared before and after + saving + If there is any difference it means an extra ordering update must be done + """ + def _epics_order_key(self, obj): + return "{}-{}".format(obj.project_id, obj.epics_order) + def pre_save(self, obj): if not obj.id: obj.owner = self.request.user + else: + self._old_epics_order_key = self._epics_order_key(self.get_object()) + super().pre_save(obj) + def _reorder_if_needed(self, obj, old_order_key, order_key, order_attr, project): + # Executes the extra ordering if there is a difference in the ordering keys + if old_order_key != order_key: + extra_orders = json.loads(self.request.META.get("HTTP_SET_ORDERS", "{}")) + data = [{"epic_id": obj.id, "order": getattr(obj, order_attr)}] + for id, order in extra_orders.items(): + data.append({"epic_id": int(id), "order": order}) + + return services.update_epics_order_in_bulk(data, + field=order_attr, + project=project) + return {} + + def post_save(self, obj, created=False): + if not created: + # Let's reorder the related stuff after edit the element + orders_updated = self._reorder_if_needed(obj, + self._old_epics_order_key, + self._epics_order_key(obj), + "epics_order", + obj.project) + self.headers["Taiga-Info-Order-Updated"] = json.dumps(orders_updated) + + super().post_save(obj, created) + def update(self, request, *args, **kwargs): self.object = self.get_object_or_none() project_id = request.DATA.get('project', None) @@ -188,28 +226,6 @@ class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, return response.BadRequest(validator.errors) - def _bulk_update_order(self, order_field, request, **kwargs): - validator = validators.UpdateEpicsOrderBulkValidator(data=request.DATA) - if not validator.is_valid(): - return response.BadRequest(validator.errors) - - data = validator.data - project = get_object_or_404(Project, pk=data["project_id"]) - - self.check_permissions(request, "bulk_update_order", project) - if project.blocked_code is not None: - raise exc.Blocked(_("Blocked element")) - - ret = services.update_epics_order_in_bulk(data["bulk_epics"], - project=project, - field=order_field) - - return response.Ok(ret) - - @list_route(methods=["POST"]) - def bulk_update_epics_order(self, request, **kwargs): - return self._bulk_update_order("epics_order", request, **kwargs) - @detail_route(methods=["POST"]) def bulk_create_related_userstories(self, request, **kwargs): validator = validators.CrateRelatedUserStoriesBulkValidator(data=request.DATA) diff --git a/taiga/projects/epics/permissions.py b/taiga/projects/epics/permissions.py index 489aeae2..b009cfc2 100644 --- a/taiga/projects/epics/permissions.py +++ b/taiga/projects/epics/permissions.py @@ -34,7 +34,6 @@ class EpicPermission(TaigaResourcePermission): filters_data_perms = AllowAny() csv_perms = AllowAny() bulk_create_perms = HasProjectPerm('add_epic') - bulk_update_order_perms = HasProjectPerm('modify_epic') bulk_create_userstories_perms = HasProjectPerm('modify_epic') & (HasProjectPerm('add_us_to_project') | HasProjectPerm('add_us')) upvote_perms = IsAuthenticated() & HasProjectPerm('view_epics') downvote_perms = IsAuthenticated() & HasProjectPerm('view_epics') diff --git a/taiga/projects/epics/validators.py b/taiga/projects/epics/validators.py index 6652928c..450fefd6 100644 --- a/taiga/projects/epics/validators.py +++ b/taiga/projects/epics/validators.py @@ -58,15 +58,3 @@ class EpicsBulkValidator(ProjectExistsValidator, EpicExistsValidator, class CrateRelatedUserStoriesBulkValidator(ProjectExistsValidator, EpicExistsValidator, validators.Validator): userstories = serializers.CharField() - - -# Order bulk validators - -class _EpicOrderBulkValidator(EpicExistsValidator, validators.Validator): - epic_id = serializers.IntegerField() - order = serializers.IntegerField() - - -class UpdateEpicsOrderBulkValidator(ProjectExistsValidator, validators.Validator): - project_id = serializers.IntegerField() - bulk_epics = _EpicOrderBulkValidator(many=True) diff --git a/tests/integration/test_epics.py b/tests/integration/test_epics.py index d8e09999..b766fbf1 100644 --- a/tests/integration/test_epics.py +++ b/tests/integration/test_epics.py @@ -68,6 +68,29 @@ def test_custom_fields_csv_generation(): assert row[17] == "val1" +def test_update_epic_order(client): + user = f.UserFactory.create() + project = f.ProjectFactory.create(owner=user) + epic_1 = f.EpicFactory.create(project=project, epics_order=1, status=project.default_us_status) + epic_2 = f.EpicFactory.create(project=project, epics_order=2, status=project.default_us_status) + epic_3 = f.EpicFactory.create(project=project, epics_order=3, status=project.default_us_status) + f.MembershipFactory.create(project=project, user=user, is_admin=True) + + url = reverse('epics-detail', kwargs={"pk": epic_1.pk}) + data = { + "epics_order": 2, + "version": epic_1.version + } + + client.login(user) + response = client.json.patch(url, json.dumps(data)) + assert json.loads(response.get("taiga-info-order-updated")) == { + str(epic_1.id): 2, + str(epic_2.id): 3, + str(epic_3.id): 4 + } + + def test_bulk_create_related_userstories(client): user = f.UserFactory.create() project = f.ProjectFactory.create(owner=user) @@ -81,6 +104,5 @@ def test_bulk_create_related_userstories(client): } client.login(user) response = client.json.post(url, json.dumps(data)) - print(response.data) assert response.status_code == 200 assert response.data['user_stories_counts'] == {'opened': 2, 'closed': 0}