Fixing serializers validation for duplicated names in priorities, severities and issue types

remotes/origin/logger
Alejandro Alonso 2016-02-04 20:23:03 +01:00 committed by Jesús Espino
parent 77379d98ed
commit 6cf3c5727e
4 changed files with 94 additions and 96 deletions

View File

@ -21,12 +21,12 @@ from taiga.base.api import serializers
from taiga.base.utils import json from taiga.base.utils import json
from taiga.projects.notifications.mixins import WatchedResourceModelSerializer from taiga.projects.notifications.mixins import WatchedResourceModelSerializer
from taiga.projects.notifications.validators import WatchersValidator from taiga.projects.notifications.validators import WatchersValidator
from taiga.projects.mixins.serializers import ValidateDuplicatedNameInProjectMixin
from ..userstories.serializers import UserStoryListSerializer from ..userstories.serializers import UserStoryListSerializer
from . import models from . import models
class MilestoneSerializer(WatchersValidator, WatchedResourceModelSerializer, serializers.ModelSerializer): class MilestoneSerializer(WatchersValidator, WatchedResourceModelSerializer, ValidateDuplicatedNameInProjectMixin):
user_stories = UserStoryListSerializer(many=True, required=False, read_only=True) user_stories = UserStoryListSerializer(many=True, required=False, read_only=True)
total_points = serializers.SerializerMethodField("get_total_points") total_points = serializers.SerializerMethodField("get_total_points")
closed_points = serializers.SerializerMethodField("get_closed_points") closed_points = serializers.SerializerMethodField("get_closed_points")
@ -40,20 +40,3 @@ class MilestoneSerializer(WatchersValidator, WatchedResourceModelSerializer, ser
def get_closed_points(self, obj): def get_closed_points(self, obj):
return sum(obj.closed_points.values()) return sum(obj.closed_points.values())
def validate_name(self, attrs, source):
"""
Check the milestone name is not duplicated in the project on creation
"""
qs = None
# If the milestone exists:
if self.object and attrs.get("name", None):
qs = models.Milestone.objects.filter(project=self.object.project, name=attrs[source]).exclude(pk=self.object.pk)
if not self.object and attrs.get("project", None) and attrs.get("name", None):
qs = models.Milestone.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs

View File

@ -0,0 +1,40 @@
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from taiga.base.api import serializers
from django.utils.translation import ugettext as _
class ValidateDuplicatedNameInProjectMixin(serializers.ModelSerializer):
def validate_name(self, attrs, source):
"""
Check the points name is not duplicated in the project on creation
"""
model = self.opts.model
qs = None
# If the object exists:
if self.object and attrs.get(source, None):
qs = model.objects.filter(project=self.object.project, name=attrs[source]).exclude(id=self.object.id)
if not self.object and attrs.get("project", None) and attrs.get(source, None):
qs = model.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs

View File

@ -34,6 +34,7 @@ from taiga.users.validators import RoleExistsValidator
from taiga.permissions.service import get_user_project_permissions from taiga.permissions.service import get_user_project_permissions
from taiga.permissions.service import is_project_owner from taiga.permissions.service import is_project_owner
from taiga.projects.mixins.serializers import ValidateDuplicatedNameInProjectMixin
from . import models from . import models
from . import services from . import services
@ -49,53 +50,17 @@ from .likes.mixins.serializers import FanResourceSerializerMixin
## Custom values for selectors ## Custom values for selectors
###################################################### ######################################################
class PointsSerializer(serializers.ModelSerializer): class PointsSerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.Points model = models.Points
i18n_fields = ("name",) i18n_fields = ("name",)
def validate_name(self, attrs, source):
"""
Check the points name is not duplicated in the project on creation
"""
qs = None
# If the user story status exists:
if self.object and attrs.get("name", None):
qs = models.Points.objects.filter(project=self.object.project, name=attrs[source])
if not self.object and attrs.get("project", None) and attrs.get("name", None): class UserStoryStatusSerializer(ValidateDuplicatedNameInProjectMixin):
qs = models.Points.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
class UserStoryStatusSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.UserStoryStatus model = models.UserStoryStatus
i18n_fields = ("name",) i18n_fields = ("name",)
def validate_name(self, attrs, source):
"""
Check the status name is not duplicated in the project on creation
"""
qs = None
# If the user story status exists:
if self.object and attrs.get("name", None):
qs = models.UserStoryStatus.objects.filter(project=self.object.project,
name=attrs[source])
if not self.object and attrs.get("project", None) and attrs.get("name", None):
qs = models.UserStoryStatus.objects.filter(project=attrs["project"],
name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
class BasicUserStoryStatusSerializer(serializers.ModelSerializer): class BasicUserStoryStatusSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -104,28 +69,11 @@ class BasicUserStoryStatusSerializer(serializers.ModelSerializer):
fields = ("name", "color") fields = ("name", "color")
class TaskStatusSerializer(serializers.ModelSerializer): class TaskStatusSerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.TaskStatus model = models.TaskStatus
i18n_fields = ("name",) i18n_fields = ("name",)
def validate_name(self, attrs, source):
"""
Check the task name is not duplicated in the project on creation
"""
qs = None
# If the user story status exists:
if self.object and attrs.get("name", None):
qs = models.TaskStatus.objects.filter(project=self.object.project, name=attrs[source])
if not self.object and attrs.get("project", None) and attrs.get("name", None):
qs = models.TaskStatus.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
class BasicTaskStatusSerializerSerializer(serializers.ModelSerializer): class BasicTaskStatusSerializerSerializer(serializers.ModelSerializer):
@ -135,40 +83,23 @@ class BasicTaskStatusSerializerSerializer(serializers.ModelSerializer):
fields = ("name", "color") fields = ("name", "color")
class SeveritySerializer(serializers.ModelSerializer): class SeveritySerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.Severity model = models.Severity
i18n_fields = ("name",) i18n_fields = ("name",)
class PrioritySerializer(serializers.ModelSerializer): class PrioritySerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.Priority model = models.Priority
i18n_fields = ("name",) i18n_fields = ("name",)
class IssueStatusSerializer(serializers.ModelSerializer): class IssueStatusSerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.IssueStatus model = models.IssueStatus
i18n_fields = ("name",) i18n_fields = ("name",)
def validate_name(self, attrs, source):
"""
Check the issue name is not duplicated in the project on creation
"""
qs = None
# If the user story status exists:
if self.object and attrs.get("name", None):
qs = models.IssueStatus.objects.filter(project=self.object.project, name=attrs[source])
if not self.object and attrs.get("project", None) and attrs.get("name", None):
qs = models.IssueStatus.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
class BasicIssueStatusSerializer(serializers.ModelSerializer): class BasicIssueStatusSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -177,7 +108,7 @@ class BasicIssueStatusSerializer(serializers.ModelSerializer):
fields = ("name", "color") fields = ("name", "color")
class IssueTypeSerializer(serializers.ModelSerializer): class IssueTypeSerializer(ValidateDuplicatedNameInProjectMixin):
class Meta: class Meta:
model = models.IssueType model = models.IssueType
i18n_fields = ("name",) i18n_fields = ("name",)

View File

@ -0,0 +1,44 @@
import pytest
from .. import factories as f
from django.db import models
from taiga.projects.mixins.serializers import ValidateDuplicatedNameInProjectMixin
from taiga.projects.models import Project
pytestmark = pytest.mark.django_db(transaction=True)
import factory
class TestingProjectModel(models.Model):
pass
class TestingModelWithNameAttribute(models.Model):
name = models.CharField(max_length=255, null=False, blank=False)
project = models.ForeignKey(TestingProjectModel, null=False, blank=False)
class TestingSerializer(ValidateDuplicatedNameInProjectMixin):
class Meta:
model = TestingModelWithNameAttribute
def test_duplicated_name_validation():
project = TestingProjectModel.objects.create()
instance_1 = TestingModelWithNameAttribute.objects.create(name="1", project=project)
instance_2 = TestingModelWithNameAttribute.objects.create(name="2", project=project)
# No duplicated_name
serializer = TestingSerializer(data={"name": "3", "project": project.id})
assert serializer.is_valid()
# Create duplicated_name
serializer = TestingSerializer(data={"name": "1", "project": project.id})
assert not serializer.is_valid()
# Update name to existing one
serializer = TestingSerializer(data={"id": instance_2.id, "name": "1","project": project.id})
assert not serializer.is_valid()