Fix bulk_update_orders for user stories

remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-02 13:27:56 +02:00
parent 73599c41ff
commit d1f7158125
2 changed files with 109 additions and 14 deletions

View File

@ -36,15 +36,6 @@ from . import models
import json import json
class UserStoryExistsValidator:
def validate_us_id(self, attrs, source):
value = attrs[source]
if not models.UserStory.objects.filter(pk=value).exists():
msg = _("There's no user story with that id")
raise ValidationError(msg)
return attrs
class RolePointsField(serializers.WritableField): class RolePointsField(serializers.WritableField):
def to_native(self, obj): def to_native(self, obj):
return {str(o.role.id): o.points.id for o in obj.all()} return {str(o.role.id): o.points.id for o in obj.all()}
@ -76,7 +67,7 @@ class UserStoriesBulkValidator(ProjectExistsValidator, UserStoryStatusExistsVali
# Order bulk validators # Order bulk validators
class _UserStoryOrderBulkValidator(UserStoryExistsValidator, validators.Validator): class _UserStoryOrderBulkValidator(validators.Validator):
us_id = serializers.IntegerField() us_id = serializers.IntegerField()
order = serializers.IntegerField() order = serializers.IntegerField()
@ -88,10 +79,25 @@ class UpdateUserStoriesOrderBulkValidator(ProjectExistsValidator, UserStoryStatu
milestone_id = serializers.IntegerField(required=False) milestone_id = serializers.IntegerField(required=False)
bulk_stories = _UserStoryOrderBulkValidator(many=True) bulk_stories = _UserStoryOrderBulkValidator(many=True)
def validate(self, data):
filters = {"project__id": data["project_id"]}
if "status_id" in data:
filters["status__id"] = data["status_id"]
if "milestone_id" in data:
filters["milestone__id"] = data["milestone_id"]
filters["id__in"] = [us["us_id"] for us in data["bulk_stories"]]
if models.UserStory.objects.filter(**filters).count() != len(filters["id__in"]):
raise ValidationError(_("Invalid user story ids. All stories must belong to the same project and, "
"if it exists, to the same status and milestone."))
return data
# Milestone bulk validators # Milestone bulk validators
class _UserStoryMilestoneBulkValidator(UserStoryExistsValidator, validators.Validator): class _UserStoryMilestoneBulkValidator(validators.Validator):
us_id = serializers.IntegerField() us_id = serializers.IntegerField()
@ -108,9 +114,9 @@ class UpdateMilestoneBulkValidator(ProjectExistsValidator, MilestoneExistsValida
project = get_object_or_404(Project, pk=data["project_id"]) project = get_object_or_404(Project, pk=data["project_id"])
if project.user_stories.filter(id__in=user_story_ids).count() != len(user_story_ids): if project.user_stories.filter(id__in=user_story_ids).count() != len(user_story_ids):
raise ValidationError("all the user stories must be from the same project") raise ValidationError(_("All the user stories must be from the same project"))
if project.milestones.filter(id=data["milestone_id"]).count() != 1: if project.milestones.filter(id=data["milestone_id"]).count() != 1:
raise ValidationError("the milestone isn't valid for the project") raise ValidationError(_("The milestone isn't valid for the project"))
return data return data

View File

@ -180,6 +180,96 @@ def test_api_update_orders_in_bulk(client):
assert response3.status_code == 200, response3.data assert response3.status_code == 200, response3.data
def test_api_update_orders_in_bulk_invalid_userstories(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
us1 = f.create_userstory(project=project)
us2 = f.create_userstory(project=project)
us3 = f.create_userstory()
url1 = reverse("userstories-bulk-update-backlog-order")
url2 = reverse("userstories-bulk-update-kanban-order")
url3 = reverse("userstories-bulk-update-sprint-order")
data = {
"project_id": project.id,
"bulk_stories": [{"us_id": us1.id, "order": 1},
{"us_id": us2.id, "order": 2},
{"us_id": us3.id, "order": 3}]
}
client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data))
response3 = client.json.post(url3, json.dumps(data))
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
def test_api_update_orders_in_bulk_invalid_status(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
us1 = f.create_userstory(project=project)
us2 = f.create_userstory(project=project, status=us1.status)
us3 = f.create_userstory(project=project)
url1 = reverse("userstories-bulk-update-backlog-order")
url2 = reverse("userstories-bulk-update-kanban-order")
url3 = reverse("userstories-bulk-update-sprint-order")
data = {
"project_id": project.id,
"status_id": us1.status.id,
"bulk_stories": [{"us_id": us1.id, "order": 1},
{"us_id": us2.id, "order": 2},
{"us_id": us3.id, "order": 3}]
}
client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data))
response3 = client.json.post(url3, json.dumps(data))
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
def test_api_update_orders_in_bulk_invalid_milestione(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
mil1 = f.MilestoneFactory.create(project=project)
us1 = f.create_userstory(project=project, milestone=mil1)
us2 = f.create_userstory(project=project, milestone=mil1)
us3 = f.create_userstory(project=project)
url1 = reverse("userstories-bulk-update-backlog-order")
url2 = reverse("userstories-bulk-update-kanban-order")
url3 = reverse("userstories-bulk-update-sprint-order")
data = {
"project_id": project.id,
"milestone_id": mil1.id,
"bulk_stories": [{"us_id": us1.id, "order": 1},
{"us_id": us2.id, "order": 2},
{"us_id": us3.id, "order": 3}]
}
client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data))
response3 = client.json.post(url3, json.dumps(data))
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
def test_api_update_milestone_in_bulk(client): def test_api_update_milestone_in_bulk(client):
project = f.create_project() project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True) f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
@ -208,7 +298,6 @@ def test_api_update_milestone_in_bulk_invalid_milestone(client):
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True) f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
us1 = f.create_userstory(project=project) us1 = f.create_userstory(project=project)
us2 = f.create_userstory(project=project) us2 = f.create_userstory(project=project)
f.MilestoneFactory.create(project=project)
m2 = f.MilestoneFactory.create() m2 = f.MilestoneFactory.create()
url = reverse("userstories-bulk-update-milestone") url = reverse("userstories-bulk-update-milestone")