Fix bulk_update_orders for user stories
parent
73599c41ff
commit
d1f7158125
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue