Removing the bulk update order for epics and doing that processing on the update

remotes/origin/issue/4795/notification_even_they_are_disabled
Alejandro Alonso 2016-08-02 13:13:33 +02:00 committed by David Barragán Merino
parent 46f6fa71e6
commit 4d4f8a44a1
4 changed files with 61 additions and 36 deletions

View File

@ -25,6 +25,7 @@ from taiga.base import exceptions as exc
from taiga.base.decorators import list_route, detail_route from taiga.base.decorators import list_route, detail_route
from taiga.base.api import ModelCrudViewSet, ModelListViewSet from taiga.base.api import ModelCrudViewSet, ModelListViewSet
from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api.mixins import BlockedByProjectMixin
from taiga.base.utils import json
from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.history.mixins import HistoryResourceMixin
from taiga.projects.models import Project, EpicStatus 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: if obj.status and obj.status.project != obj.project:
raise exc.WrongArguments(_("You don't have permissions to set this status to this epic.")) 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): def pre_save(self, obj):
if not obj.id: if not obj.id:
obj.owner = self.request.user obj.owner = self.request.user
else:
self._old_epics_order_key = self._epics_order_key(self.get_object())
super().pre_save(obj) 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): def update(self, request, *args, **kwargs):
self.object = self.get_object_or_none() self.object = self.get_object_or_none()
project_id = request.DATA.get('project', None) project_id = request.DATA.get('project', None)
@ -188,28 +226,6 @@ class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin,
return response.BadRequest(validator.errors) 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"]) @detail_route(methods=["POST"])
def bulk_create_related_userstories(self, request, **kwargs): def bulk_create_related_userstories(self, request, **kwargs):
validator = validators.CrateRelatedUserStoriesBulkValidator(data=request.DATA) validator = validators.CrateRelatedUserStoriesBulkValidator(data=request.DATA)

View File

@ -34,7 +34,6 @@ class EpicPermission(TaigaResourcePermission):
filters_data_perms = AllowAny() filters_data_perms = AllowAny()
csv_perms = AllowAny() csv_perms = AllowAny()
bulk_create_perms = HasProjectPerm('add_epic') 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')) bulk_create_userstories_perms = HasProjectPerm('modify_epic') & (HasProjectPerm('add_us_to_project') | HasProjectPerm('add_us'))
upvote_perms = IsAuthenticated() & HasProjectPerm('view_epics') upvote_perms = IsAuthenticated() & HasProjectPerm('view_epics')
downvote_perms = IsAuthenticated() & HasProjectPerm('view_epics') downvote_perms = IsAuthenticated() & HasProjectPerm('view_epics')

View File

@ -58,15 +58,3 @@ class EpicsBulkValidator(ProjectExistsValidator, EpicExistsValidator,
class CrateRelatedUserStoriesBulkValidator(ProjectExistsValidator, EpicExistsValidator, class CrateRelatedUserStoriesBulkValidator(ProjectExistsValidator, EpicExistsValidator,
validators.Validator): validators.Validator):
userstories = serializers.CharField() 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)

View File

@ -68,6 +68,29 @@ def test_custom_fields_csv_generation():
assert row[17] == "val1" 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): def test_bulk_create_related_userstories(client):
user = f.UserFactory.create() user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user) project = f.ProjectFactory.create(owner=user)
@ -81,6 +104,5 @@ def test_bulk_create_related_userstories(client):
} }
client.login(user) client.login(user)
response = client.json.post(url, json.dumps(data)) response = client.json.post(url, json.dumps(data))
print(response.data)
assert response.status_code == 200 assert response.status_code == 200
assert response.data['user_stories_counts'] == {'opened': 2, 'closed': 0} assert response.data['user_stories_counts'] == {'opened': 2, 'closed': 0}