Improve more validators

remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-04 17:13:30 +02:00
parent e83e4b8beb
commit 4c6f49aaab
4 changed files with 254 additions and 69 deletions

View File

@ -179,8 +179,8 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin,
self.check_permissions(request, "destroy", self.object) self.check_permissions(request, "destroy", self.object)
self.check_permissions(request, "create", new_project) self.check_permissions(request, "create", new_project)
sprint_id = request.DATA.get('milestone', None) milestone_id = request.DATA.get('milestone', None)
if sprint_id is not None and new_project.milestones.filter(pk=sprint_id).count() == 0: if milestone_id is not None and new_project.milestones.filter(pk=milestone_id).count() == 0:
request.DATA['milestone'] = None request.DATA['milestone'] = None
us_id = request.DATA.get('user_story', None) us_id = request.DATA.get('user_story', None)
@ -259,7 +259,7 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin,
raise exc.Blocked(_("Blocked element")) raise exc.Blocked(_("Blocked element"))
tasks = services.create_tasks_in_bulk( tasks = services.create_tasks_in_bulk(
data["bulk_tasks"], milestone_id=data["sprint_id"], user_story_id=data["us_id"], data["bulk_tasks"], milestone_id=data["milestone_id"], user_story_id=data["us_id"],
status_id=data.get("status_id") or project.default_task_status_id, status_id=data.get("status_id") or project.default_task_status_id,
project=project, owner=request.user, callback=self.post_save, precall=self.pre_save) project=project, owner=request.user, callback=self.post_save, precall=self.pre_save)

View File

@ -30,7 +30,6 @@ from taiga.projects.tagging.fields import TagsAndTagsColorsField
from taiga.projects.userstories.models import UserStory from taiga.projects.userstories.models import UserStory
from taiga.projects.validators import ProjectExistsValidator from taiga.projects.validators import ProjectExistsValidator
from . import models from . import models
@ -45,23 +44,27 @@ class TaskValidator(WatchersValidator, EditableWatchedResourceSerializer, valida
class TasksBulkValidator(ProjectExistsValidator, validators.Validator): class TasksBulkValidator(ProjectExistsValidator, validators.Validator):
project_id = serializers.IntegerField() project_id = serializers.IntegerField()
sprint_id = serializers.IntegerField() milestone_id = serializers.IntegerField()
status_id = serializers.IntegerField(required=False) status_id = serializers.IntegerField(required=False)
us_id = serializers.IntegerField(required=False) us_id = serializers.IntegerField(required=False)
bulk_tasks = serializers.CharField() bulk_tasks = serializers.CharField()
def validate_sprint_id(self, attrs, source): def validate_milestone_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {
filters["id"] = attrs["sprint_id"] "project__id": attrs["project_id"],
"id": attrs[source]
}
if not Milestone.objects.filter(**filters).exists(): if not Milestone.objects.filter(**filters).exists():
raise ValidationError(_("Invalid sprint id.")) raise ValidationError(_("Invalid milestone id."))
return attrs return attrs
def validate_status_id(self, attrs, source): def validate_status_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {
filters["id"] = attrs["status_id"] "project__id": attrs["project_id"],
"id": attrs[source]
}
if not TaskStatus.objects.filter(**filters).exists(): if not TaskStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid task status id.")) raise ValidationError(_("Invalid task status id."))
@ -71,13 +74,13 @@ class TasksBulkValidator(ProjectExistsValidator, validators.Validator):
def validate_us_id(self, attrs, source): def validate_us_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {"project__id": attrs["project_id"]}
if "sprint_id" in attrs: if "milestone_id" in attrs:
filters["milestone__id"] = attrs["sprint_id"] filters["milestone__id"] = attrs["milestone_id"]
filters["id"] = attrs["us_id"] filters["id"] = attrs["us_id"]
if not UserStory.objects.filter(**filters).exists(): if not UserStory.objects.filter(**filters).exists():
raise ValidationError(_("Invalid sprint id.")) raise ValidationError(_("Invalid user story id."))
return attrs return attrs
@ -96,19 +99,55 @@ class UpdateTasksOrderBulkValidator(ProjectExistsValidator, validators.Validator
milestone_id = serializers.IntegerField(required=False) milestone_id = serializers.IntegerField(required=False)
bulk_tasks = _TaskOrderBulkValidator(many=True) bulk_tasks = _TaskOrderBulkValidator(many=True)
def validate(self, data): def validate_status_id(self, attrs, source):
filters = {"project__id": data["project_id"]} filters = {"project__id": attrs["project_id"]}
if "status_id" in data: filters["id"] = attrs[source]
filters["status__id"] = data["status_id"]
if "us_id" in data:
filters["user_story__id"] = data["us_id"]
if "milestone_id" in data:
filters["milestone__id"] = data["milestone_id"]
filters["id__in"] = [t["task_id"] for t in data["bulk_tasks"]] if not TaskStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid task status id. The status must belong to "
"the same project."))
return attrs
def validate_us_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if "milestone_id" in attrs:
filters["milestone__id"] = attrs["milestone_id"]
filters["id"] = attrs[source]
if not UserStory.objects.filter(**filters).exists():
raise ValidationError(_("Invalid user story id. The user story must belong to "
"the same project."))
return attrs
def validate_milestone_id(self, attrs, source):
filters = {
"project__id": attrs["project_id"],
"id": attrs[source]
}
if not Milestone.objects.filter(**filters).exists():
raise ValidationError(_("Invalid milestone id. The milestone must belong to "
"the same project."))
return attrs
def validate_bulk_tasks(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if "status_id" in attrs:
filters["status__id"] = attrs["status_id"]
if "us_id" in attrs:
filters["user_story__id"] = attrs["us_id"]
if "milestone_id" in attrs:
filters["milestone__id"] = attrs["milestone_id"]
filters["id__in"] = [t["task_id"] for t in attrs[source]]
if models.Task.objects.filter(**filters).count() != len(filters["id__in"]): if models.Task.objects.filter(**filters).count() != len(filters["id__in"]):
raise ValidationError(_("Invalid task ids. All tasks must belong to the same project and, " raise ValidationError(_("Invalid task ids. All tasks must belong to the same project and, "
"if it exists, to the same status, user story and/or milestone.")) "if it exists, to the same status, user story and/or milestone."))
return data return attrs

View File

@ -73,13 +73,14 @@ class UserStoriesBulkValidator(ProjectExistsValidator, validators.Validator):
bulk_stories = serializers.CharField() bulk_stories = serializers.CharField()
def validate_status_id(self, attrs, source): def validate_status_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {
if source in attrs: "project__id": attrs["project_id"],
filters["id"] = attrs[source] "id": attrs[source]
}
if not UserStoryStatus.objects.filter(**filters).exists(): if not UserStoryStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid user story status id. The status must belong to " raise ValidationError(_("Invalid user story status id. The status must belong to "
"the same project.")) "the same project."))
return attrs return attrs
@ -98,24 +99,26 @@ class UpdateUserStoriesOrderBulkValidator(ProjectExistsValidator, validators.Val
bulk_stories = _UserStoryOrderBulkValidator(many=True) bulk_stories = _UserStoryOrderBulkValidator(many=True)
def validate_status_id(self, attrs, source): def validate_status_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {
if source in attrs: "project__id": attrs["project_id"],
filters["id"] = attrs[source] "id": attrs[source]
}
if not UserStoryStatus.objects.filter(**filters).exists(): if not UserStoryStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid user story status id. The status must belong " raise ValidationError(_("Invalid user story status id. The status must belong "
"to the same project.")) "to the same project."))
return attrs return attrs
def validate_milestone_id(self, attrs, source): def validate_milestone_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]} filters = {
if source in attrs: "project__id": attrs["project_id"],
filters["id"] = attrs[source] "id": attrs[source]
}
if not Milestone.objects.filter(**filters).exists(): if not Milestone.objects.filter(**filters).exists():
raise ValidationError(_("Invalid milestone id. The milistone must belong to the " raise ValidationError(_("Invalid milestone id. The milistone must belong to the "
"same project.")) "same project."))
return attrs return attrs

View File

@ -104,7 +104,7 @@ def test_api_create_in_bulk_with_status_milestone_userstory(client):
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"us_id": us.id, "us_id": us.id,
"project_id": us.project.id, "project_id": us.project.id,
"sprint_id": us.milestone.id, "milestone_id": us.milestone.id,
"status_id": us.project.default_task_status.id "status_id": us.project.default_task_status.id
} }
@ -129,7 +129,7 @@ def test_api_create_in_bulk_with_status_milestone(client):
data = { data = {
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"project_id": us.project.id, "project_id": us.project.id,
"sprint_id": us.milestone.id, "milestone_id": us.milestone.id,
"status_id": us.project.default_task_status.id "status_id": us.project.default_task_status.id
} }
@ -158,7 +158,7 @@ def test_api_create_in_bulk_with_invalid_status(client):
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"us_id": us.id, "us_id": us.id,
"project_id": project.id, "project_id": project.id,
"sprint_id": milestone.id, "milestone_id": milestone.id,
"status_id": status.id "status_id": status.id
} }
@ -166,6 +166,7 @@ def test_api_create_in_bulk_with_invalid_status(client):
response = client.json.post(url, json.dumps(data)) response = client.json.post(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
assert "status_id" in response.data
def test_api_create_in_bulk_with_invalid_milestone(client): def test_api_create_in_bulk_with_invalid_milestone(client):
@ -183,7 +184,7 @@ def test_api_create_in_bulk_with_invalid_milestone(client):
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"us_id": us.id, "us_id": us.id,
"project_id": project.id, "project_id": project.id,
"sprint_id": milestone.id, "milestone_id": milestone.id,
"status_id": project.default_task_status.id "status_id": project.default_task_status.id
} }
@ -191,6 +192,7 @@ def test_api_create_in_bulk_with_invalid_milestone(client):
response = client.json.post(url, json.dumps(data)) response = client.json.post(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
assert "milestone_id" in response.data
def test_api_create_in_bulk_with_invalid_userstory_1(client): def test_api_create_in_bulk_with_invalid_userstory_1(client):
@ -208,7 +210,7 @@ def test_api_create_in_bulk_with_invalid_userstory_1(client):
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"us_id": us.id, "us_id": us.id,
"project_id": project.id, "project_id": project.id,
"sprint_id": milestone.id, "milestone_id": milestone.id,
"status_id": project.default_task_status.id "status_id": project.default_task_status.id
} }
@ -216,6 +218,7 @@ def test_api_create_in_bulk_with_invalid_userstory_1(client):
response = client.json.post(url, json.dumps(data)) response = client.json.post(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
assert "us_id" in response.data
def test_api_create_in_bulk_with_invalid_userstory_2(client): def test_api_create_in_bulk_with_invalid_userstory_2(client):
@ -233,7 +236,7 @@ def test_api_create_in_bulk_with_invalid_userstory_2(client):
"bulk_tasks": "Story #1\nStory #2", "bulk_tasks": "Story #1\nStory #2",
"us_id": us.id, "us_id": us.id,
"project_id": us.project.id, "project_id": us.project.id,
"sprint_id": milestone.id, "milestone_id": milestone.id,
"status_id": us.project.default_task_status.id "status_id": us.project.default_task_status.id
} }
@ -241,6 +244,7 @@ def test_api_create_in_bulk_with_invalid_userstory_2(client):
response = client.json.post(url, json.dumps(data)) response = client.json.post(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
assert "us_id" in response.data
def test_api_create_invalid_task(client): def test_api_create_invalid_task(client):
@ -309,14 +313,17 @@ def test_api_update_order_in_bulk_invalid_tasks(client):
client.login(project.owner) client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data)) response = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data)) assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
assert response1.status_code == 400, response1.data response = client.json.post(url2, json.dumps(data))
assert response2.status_code == 400, response2.data assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_status(client):
def test_api_update_order_in_bulk_invalid_tasks_for_status(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)
task1 = f.create_task(project=project) task1 = f.create_task(project=project)
@ -336,14 +343,16 @@ def test_api_update_order_in_bulk_invalid_status(client):
client.login(project.owner) client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data)) response = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data)) assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
assert response1.status_code == 400, response1.data response = client.json.post(url2, json.dumps(data))
assert response2.status_code == 400, response2.data assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_milestone(client): def test_api_update_order_in_bulk_invalid_tasks_for_milestone(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)
mil1 = f.MilestoneFactory.create(project=project) mil1 = f.MilestoneFactory.create(project=project)
@ -364,19 +373,21 @@ def test_api_update_order_in_bulk_invalid_milestone(client):
client.login(project.owner) client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data)) response = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data)) assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
assert response1.status_code == 400, response1.data response = client.json.post(url2, json.dumps(data))
assert response2.status_code == 400, response2.data assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_user_story(client): def test_api_update_order_in_bulk_invalid_tasks_for_user_story(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)
us1 = f.create_userstory(project=project) us1 = f.create_userstory(project=project)
task1 = f.create_task(project=project, user_story=us1) task1 = f.create_task(project=project)
task2 = f.create_task(project=project, user_story=us1) task2 = f.create_task(project=project)
task3 = f.create_task(project=project) task3 = f.create_task(project=project)
url1 = reverse("tasks-bulk-update-taskboard-order") url1 = reverse("tasks-bulk-update-taskboard-order")
@ -392,11 +403,143 @@ def test_api_update_order_in_bulk_invalid_user_story(client):
client.login(project.owner) client.login(project.owner)
response1 = client.json.post(url1, json.dumps(data)) response = client.json.post(url1, json.dumps(data))
response2 = client.json.post(url2, json.dumps(data)) assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
assert response1.status_code == 400, response1.data response = client.json.post(url2, json.dumps(data))
assert response2.status_code == 400, response2.data assert response.status_code == 400, response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_status(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
status = f.TaskStatusFactory.create()
task1 = f.create_task(project=project)
task2 = f.create_task(project=project)
task3 = f.create_task(project=project)
url1 = reverse("tasks-bulk-update-taskboard-order")
url2 = reverse("tasks-bulk-update-us-order")
data = {
"project_id": project.id,
"status_id": status.id,
"bulk_tasks": [{"task_id": task1.id, "order": 1},
{"task_id": task2.id, "order": 2},
{"task_id": task3.id, "order": 3}]
}
client.login(project.owner)
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
assert "bulk_tasks" in response.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_milestone(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
mil1 = f.MilestoneFactory.create()
task1 = f.create_task(project=project)
task2 = f.create_task(project=project)
task3 = f.create_task(project=project)
url1 = reverse("tasks-bulk-update-taskboard-order")
url2 = reverse("tasks-bulk-update-us-order")
data = {
"project_id": project.id,
"milestone_id": mil1.id,
"bulk_tasks": [{"task_id": task1.id, "order": 1},
{"task_id": task2.id, "order": 2},
{"task_id": task3.id, "order": 3}]
}
client.login(project.owner)
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "milestone_id" in response.data
assert "bulk_tasks" in response.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "milestone_id" in response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_user_story_1(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
us1 = f.create_userstory()
task1 = f.create_task(project=project)
task2 = f.create_task(project=project)
task3 = f.create_task(project=project)
url1 = reverse("tasks-bulk-update-taskboard-order")
url2 = reverse("tasks-bulk-update-us-order")
data = {
"project_id": project.id,
"us_id": us1.id,
"bulk_tasks": [{"task_id": task1.id, "order": 1},
{"task_id": task2.id, "order": 2},
{"task_id": task3.id, "order": 3}]
}
client.login(project.owner)
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "us_id" in response.data
assert "bulk_tasks" in response.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "us_id" in response.data
assert "bulk_tasks" in response.data
def test_api_update_order_in_bulk_invalid_user_story_2(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
milestone = f.MilestoneFactory.create(project=project)
us1 = f.create_userstory(project=project)
task1 = f.create_task(project=project)
task2 = f.create_task(project=project)
task3 = f.create_task(project=project)
url1 = reverse("tasks-bulk-update-taskboard-order")
url2 = reverse("tasks-bulk-update-us-order")
data = {
"project_id": project.id,
"us_id": us1.id,
"milestone_id": milestone.id,
"bulk_tasks": [{"task_id": task1.id, "order": 1},
{"task_id": task2.id, "order": 2},
{"task_id": task3.id, "order": 3}]
}
client.login(project.owner)
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "us_id" in response.data
assert "bulk_tasks" in response.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "us_id" in response.data
assert "bulk_tasks" in response.data
def test_get_invalid_csv(client): def test_get_invalid_csv(client):