Improve userstories.validators

remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-03 17:46:53 +02:00
parent 3656acd7f3
commit bc69ecd886
2 changed files with 133 additions and 57 deletions

View File

@ -20,16 +20,17 @@ from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
from taiga.base.api.utils import get_object_or_404
from taiga.base.exceptions import ValidationError
from taiga.base.fields import PgArrayField
from taiga.base.fields import PickledObjectField
from taiga.projects.milestones.validators import MilestoneExistsValidator
from taiga.projects.models import Project
from taiga.projects.milestones.models import Milestone
from taiga.projects.models import UserStoryStatus
from taiga.projects.notifications.mixins import EditableWatchedResourceSerializer
from taiga.projects.notifications.validators import WatchersValidator
from taiga.projects.tagging.fields import TagsAndTagsColorsField
from taiga.projects.validators import ProjectExistsValidator, UserStoryStatusExistsValidator
from taiga.projects.userstories.models import UserStory
from taiga.projects.validators import ProjectExistsValidator
from taiga.projects.validators import UserStoryStatusExistsValidator
from . import models
@ -67,12 +68,22 @@ class UserStoryValidator(WatchersValidator, EditableWatchedResourceSerializer, v
read_only_fields = ('id', 'ref', 'created_date', 'modified_date', 'owner')
class UserStoriesBulkValidator(ProjectExistsValidator, UserStoryStatusExistsValidator,
validators.Validator):
class UserStoriesBulkValidator(ProjectExistsValidator, validators.Validator):
project_id = serializers.IntegerField()
status_id = serializers.IntegerField(required=False)
bulk_stories = serializers.CharField()
def validate_status_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if source in attrs:
filters["id"] = attrs[source]
if not UserStoryStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid user story status id. The status must belong to "
"the same project."))
return attrs
# Order bulk validators
@ -88,20 +99,42 @@ class UpdateUserStoriesOrderBulkValidator(ProjectExistsValidator, UserStoryStatu
milestone_id = serializers.IntegerField(required=False)
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"]
def validate_status_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if source in attrs:
filters["id"] = attrs[source]
filters["id__in"] = [us["us_id"] for us in data["bulk_stories"]]
if not UserStoryStatus.objects.filter(**filters).exists():
raise ValidationError(_("Invalid user story status id. The status must belong "
"to the same project."))
return attrs
def validate_milestone_id(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if source in attrs:
filters["id"] = attrs[source]
if not Milestone.objects.filter(**filters).exists():
raise ValidationError(_("Invalid milestone id. The milistone must belong to the "
"same project."))
return attrs
def validate_bulk_stories(self, attrs, source):
filters = {"project__id": attrs["project_id"]}
if "status_id" in attrs:
filters["status__id"] = attrs["status_id"]
if "milestone_id" in attrs:
filters["milestone__id"] = attrs["milestone_id"]
filters["id__in"] = [us["us_id"] for us in attrs[source]]
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."))
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
return attrs
# Milestone bulk validators
@ -111,22 +144,27 @@ class _UserStoryMilestoneBulkValidator(validators.Validator):
order = serializers.IntegerField()
class UpdateMilestoneBulkValidator(ProjectExistsValidator, MilestoneExistsValidator, validators.Validator):
class UpdateMilestoneBulkValidator(ProjectExistsValidator, validators.Validator):
project_id = serializers.IntegerField()
milestone_id = serializers.IntegerField()
bulk_stories = _UserStoryMilestoneBulkValidator(many=True)
def validate(self, data):
"""
All the userstories and the milestone are from the same project
"""
user_story_ids = [us["us_id"] for us in data["bulk_stories"]]
project = get_object_or_404(Project, pk=data["project_id"])
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(_("The milestone isn't valid for the project"))
return attrs
if project.user_stories.filter(id__in=user_story_ids).count() != len(user_story_ids):
def validate_bulk_stories(self, attrs, source):
filters = {
"project__id": attrs["project_id"],
"id__in": [us["us_id"] for us in attrs[source]]
}
if UserStory.objects.filter(**filters).count() != len(filters["id__in"]):
raise ValidationError(_("All the user stories must be from the same project"))
if project.milestones.filter(id=data["milestone_id"]).count() != 1:
raise ValidationError(_("The milestone isn't valid for the project"))
return data
return attrs

View File

@ -157,6 +157,24 @@ def test_api_create_in_bulk_with_status(client):
assert response.data[0]["status"] == project.default_us_status.id
def test_api_create_in_bulk_with_invalid_status(client):
project = f.create_project()
status = f.UserStoryStatusFactory.create()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
url = reverse("userstories-bulk-create")
data = {
"bulk_stories": "Story #1\nStory #2",
"project_id": project.id,
"status_id": status.id
}
client.login(project.owner)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
def test_api_update_orders_in_bulk(client):
project = f.create_project()
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
@ -175,13 +193,14 @@ def test_api_update_orders_in_bulk(client):
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))
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 200, response.data
assert response1.status_code == 200, response1.data
assert response2.status_code == 200, response2.data
assert response3.status_code == 200, response3.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 200, response.data
response = client.json.post(url3, json.dumps(data))
assert response.status_code == 200, response.data
def test_api_update_orders_in_bulk_invalid_userstories(client):
@ -204,19 +223,24 @@ def test_api_update_orders_in_bulk_invalid_userstories(client):
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))
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "bulk_stories" in response.data
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "bulk_stories" in response.data
response = client.json.post(url3, json.dumps(data))
assert response.status_code == 400, response.data
assert "bulk_stories" in response.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)
status = f.UserStoryStatusFactory.create()
us1 = f.create_userstory(project=project, status=status)
us2 = f.create_userstory(project=project, status=us1.status)
us3 = f.create_userstory(project=project)
@ -226,7 +250,7 @@ def test_api_update_orders_in_bulk_invalid_status(client):
data = {
"project_id": project.id,
"status_id": us1.status.id,
"status_id": status.id,
"bulk_stories": [{"us_id": us1.id, "order": 1},
{"us_id": us2.id, "order": 2},
{"us_id": us3.id, "order": 3}]
@ -234,19 +258,26 @@ def test_api_update_orders_in_bulk_invalid_status(client):
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))
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
assert "bulk_stories" in response.data
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
assert "bulk_stories" in response.data
response = client.json.post(url3, json.dumps(data))
assert response.status_code == 400, response.data
assert "status_id" in response.data
assert "bulk_stories" in response.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)
mil1 = f.MilestoneFactory.create()
us1 = f.create_userstory(project=project, milestone=mil1)
us2 = f.create_userstory(project=project, milestone=mil1)
us3 = f.create_userstory(project=project)
@ -265,13 +296,20 @@ def test_api_update_orders_in_bulk_invalid_milestione(client):
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))
response = client.json.post(url1, json.dumps(data))
assert response.status_code == 400, response.data
assert "milestone_id" in response.data
assert "bulk_stories" in response.data
assert response1.status_code == 400, response1.data
assert response2.status_code == 400, response2.data
assert response3.status_code == 400, response3.data
response = client.json.post(url2, json.dumps(data))
assert response.status_code == 400, response.data
assert "milestone_id" in response.data
assert "bulk_stories" in response.data
response = client.json.post(url3, json.dumps(data))
assert response.status_code == 400, response.data
assert "milestone_id" in response.data
assert "bulk_stories" in response.data
def test_api_update_milestone_in_bulk(client):
@ -322,7 +360,7 @@ def test_api_update_milestone_in_bulk_invalid_milestone(client):
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400
assert len(response.data["non_field_errors"]) == 1
assert "milestone_id" in response.data
def test_api_update_milestone_in_bulk_invalid_userstories(client):
@ -344,7 +382,7 @@ def test_api_update_milestone_in_bulk_invalid_userstories(client):
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400
assert len(response.data["non_field_errors"]) == 1
assert "bulk_stories" in response.data
def test_update_userstory_points(client):