Fix test and RelatedUserStoyr API nested endpoint
parent
1cb9248912
commit
8d0c9ee1c1
|
@ -211,14 +211,14 @@ class UpdateModelMixin:
|
|||
Set any attributes on the object that are implicit in the request.
|
||||
"""
|
||||
# pk and/or slug attributes are implicit in the URL.
|
||||
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||
lookup = self.kwargs.get(lookup_url_kwarg, None)
|
||||
##lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||
##lookup = self.kwargs.get(lookup_url_kwarg, None)
|
||||
pk = self.kwargs.get(self.pk_url_kwarg, None)
|
||||
slug = self.kwargs.get(self.slug_url_kwarg, None)
|
||||
slug_field = slug and self.slug_field or None
|
||||
|
||||
if lookup:
|
||||
setattr(obj, self.lookup_field, lookup)
|
||||
##if lookup:
|
||||
## setattr(obj, self.lookup_field, lookup)
|
||||
|
||||
if pk:
|
||||
setattr(obj, 'pk', pk)
|
||||
|
@ -253,6 +253,27 @@ class DestroyModelMixin:
|
|||
return response.NoContent()
|
||||
|
||||
|
||||
class NestedViewSetMixin(object):
|
||||
def get_queryset(self):
|
||||
return self._filter_queryset_by_parents_lookups(super().get_queryset())
|
||||
|
||||
def _filter_queryset_by_parents_lookups(self, queryset):
|
||||
parents_query_dict = self._get_parents_query_dict()
|
||||
if parents_query_dict:
|
||||
return queryset.filter(**parents_query_dict)
|
||||
else:
|
||||
return queryset
|
||||
|
||||
def _get_parents_query_dict(self):
|
||||
result = {}
|
||||
for kwarg_name in self.kwargs:
|
||||
query_value = self.kwargs.get(kwarg_name)
|
||||
result[kwarg_name] = query_value
|
||||
return result
|
||||
|
||||
|
||||
## TODO: Move blocked mixind out of the base module because is related to project
|
||||
|
||||
class BlockeableModelMixin:
|
||||
def is_blocked(self, obj):
|
||||
raise NotImplementedError("is_blocked must be overridden")
|
||||
|
|
|
@ -132,13 +132,13 @@ def update_attr_in_bulk_for_ids(values, attr, model):
|
|||
"""
|
||||
values = [str((id, order)) for id, order in values.items()]
|
||||
sql = """
|
||||
UPDATE {tbl}
|
||||
SET {attr}=update_values.column2
|
||||
UPDATE "{tbl}"
|
||||
SET "{attr}"=update_values.column2
|
||||
FROM (
|
||||
VALUES
|
||||
{values}
|
||||
) AS update_values
|
||||
WHERE {tbl}.id=update_values.column1;
|
||||
WHERE "{tbl}"."id"=update_values.column1;
|
||||
""".format(tbl=model._meta.db_table,
|
||||
values=', '.join(values),
|
||||
attr=attr)
|
||||
|
|
|
@ -78,7 +78,6 @@ def user_has_perm(user, perm, obj=None, cache="user"):
|
|||
in cache
|
||||
"""
|
||||
project = _get_object_project(obj)
|
||||
|
||||
if not project:
|
||||
return False
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ class EpicRelatedUserStoryViewSet(NestedViewSetMixin, BlockedByProjectMixin, Mod
|
|||
validator_class = validators.EpicRelatedUserStoryValidator
|
||||
model = models.RelatedUserStory
|
||||
permission_classes = (permissions.EpicRelatedUserStoryPermission,)
|
||||
lookup_field = "user_story_id"
|
||||
lookup_field = "user_story"
|
||||
|
||||
"""
|
||||
Updating the order attribute can affect the ordering of another userstories in the epic
|
||||
|
@ -259,7 +259,7 @@ class EpicRelatedUserStoryViewSet(NestedViewSetMixin, BlockedByProjectMixin, Mod
|
|||
extra_orders = json.loads(self.request.META.get("HTTP_SET_ORDERS", "{}"))
|
||||
data = [{"us_id": obj.id, "order": getattr(obj, "order")}]
|
||||
for id, order in extra_orders.items():
|
||||
data.append({"epic_id": int(id), "order": order})
|
||||
data.append({"us_id": int(id), "order": order})
|
||||
|
||||
return services.update_epic_related_userstories_order_in_bulk(data, epic=obj.epic)
|
||||
|
||||
|
@ -268,8 +268,8 @@ class EpicRelatedUserStoryViewSet(NestedViewSetMixin, BlockedByProjectMixin, Mod
|
|||
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))
|
||||
self._old_order_key,
|
||||
self._order_key(obj))
|
||||
self.headers["Taiga-Info-Order-Updated"] = json.dumps(orders_updated)
|
||||
|
||||
super().post_save(obj, created)
|
||||
|
|
|
@ -81,5 +81,6 @@ class EpicNeighborsSerializer(NeighborsSerializerMixin, EpicSerializer):
|
|||
|
||||
|
||||
class EpicRelatedUserStorySerializer(serializers.LightSerializer):
|
||||
epic = Field(attr="epic_id")
|
||||
user_story = Field(attr="user_story_id")
|
||||
order = Field()
|
||||
|
|
|
@ -26,9 +26,9 @@ from django.db import connection
|
|||
from django.utils.translation import ugettext as _
|
||||
|
||||
from taiga.base.utils import db, text
|
||||
from taiga.projects.services import apply_order_updates
|
||||
from taiga.projects.epics.apps import connect_epics_signals
|
||||
from taiga.projects.epics.apps import disconnect_epics_signals
|
||||
from taiga.projects.services import apply_order_updates
|
||||
from taiga.projects.userstories.apps import connect_userstories_signals
|
||||
from taiga.projects.userstories.apps import disconnect_userstories_signals
|
||||
from taiga.projects.userstories.services import get_userstories_from_bulk
|
||||
|
@ -127,6 +127,34 @@ def create_related_userstories_in_bulk(bulk_data, epic, **additional_fields):
|
|||
return userstories
|
||||
|
||||
|
||||
def update_epic_related_userstories_order_in_bulk(bulk_data: list, epic: object):
|
||||
"""
|
||||
Updates the order of the related userstories of an specific epic.
|
||||
`bulk_data` should be a list of dicts with the following format:
|
||||
`epic` is the epic with related stories.
|
||||
|
||||
[{'us_id': <value>, 'order': <value>}, ...]
|
||||
"""
|
||||
related_user_stories = epic.relateduserstory_set.all()
|
||||
rus_orders = {rus.id: rus.order for rus in related_user_stories}
|
||||
|
||||
rus_conversion = {rus.user_story_id: rus.id for rus in related_user_stories}
|
||||
new_rus_orders = {rus_conversion[e["us_id"]]: e["order"] for e in bulk_data
|
||||
if e["us_id"] in rus_conversion}
|
||||
|
||||
apply_order_updates(rus_orders, new_rus_orders)
|
||||
|
||||
if rus_orders:
|
||||
related_user_story_ids = rus_orders.keys()
|
||||
events.emit_event_for_ids(ids=related_user_story_ids,
|
||||
content_type="epics.relateduserstory",
|
||||
projectid=epic.project_id)
|
||||
|
||||
db.update_attr_in_bulk_for_ids(rus_orders, "order", models.RelatedUserStory)
|
||||
|
||||
return rus_orders
|
||||
|
||||
|
||||
#####################################################
|
||||
# CSV
|
||||
#####################################################
|
||||
|
|
|
@ -63,4 +63,4 @@ class CrateRelatedUserStoriesBulkValidator(ProjectExistsValidator, EpicExistsVal
|
|||
class EpicRelatedUserStoryValidator(validators.ModelValidator):
|
||||
class Meta:
|
||||
model = models.RelatedUserStory
|
||||
read_only_fields = ('id', 'epic', 'user_story')
|
||||
read_only_fields = ('id',)
|
||||
|
|
|
@ -119,13 +119,13 @@ def test_set_related_userstory(client):
|
|||
url = reverse('epics-related-userstories-list', args=[epic.pk])
|
||||
|
||||
data = {
|
||||
"user_story": us.id
|
||||
"user_story": us.id,
|
||||
"epic": epic.pk
|
||||
}
|
||||
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': 1, 'closed': 0}
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
def test_set_related_userstory_existing(client):
|
||||
|
@ -136,18 +136,15 @@ def test_set_related_userstory_existing(client):
|
|||
f.MembershipFactory.create(project=epic.project, user=user, is_admin=True)
|
||||
f.MembershipFactory.create(project=us.project, user=user, is_admin=True)
|
||||
|
||||
url = reverse('epics-related-userstories-list', args=[epic.pk])
|
||||
|
||||
url = reverse('epics-related-userstories-detail', args=[epic.pk, us.pk])
|
||||
data = {
|
||||
"user_story": us.id,
|
||||
"order": 77
|
||||
}
|
||||
client.login(user)
|
||||
response = client.json.post(url, json.dumps(data))
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 200
|
||||
assert response.data['user_stories_counts'] == {'opened': 1, 'closed': 0}
|
||||
|
||||
related_us = models.RelatedUserStory.objects.get(id=related_us.id)
|
||||
related_us.refresh_from_db()
|
||||
assert related_us.order == 77
|
||||
|
||||
|
||||
|
@ -158,7 +155,7 @@ def test_unset_related_userstory(client):
|
|||
related_us = f.RelatedUserStory.create(epic=epic, user_story=us, order=55)
|
||||
f.MembershipFactory.create(project=epic.project, user=user, is_admin=True)
|
||||
|
||||
url = reverse('epics-related-userstories-detail', args=[epic.pk, us.pk])
|
||||
url = reverse('epics-related-userstories-detail', args=[epic.pk, us.id])
|
||||
|
||||
client.login(user)
|
||||
response = client.delete(url)
|
||||
|
|
Loading…
Reference in New Issue