Fix test and RelatedUserStoyr API nested endpoint

remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-22 13:05:44 +02:00
parent 1cb9248912
commit 8d0c9ee1c1
8 changed files with 71 additions and 25 deletions

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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
#####################################################

View File

@ -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',)

View File

@ -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)