Merge pull request #804 from taigaio/Refactoring-tags-and-colors-in-API

Refactoring tags and colors in API
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-17 11:52:25 +02:00 committed by GitHub
commit f20a9737a1
8 changed files with 73 additions and 36 deletions

View File

@ -25,12 +25,14 @@ from taiga.projects.mixins.serializers import OwnerExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import AssignedToExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import StatusExtraInfoSerializerMixin
from taiga.projects.notifications.mixins import WatchedResourceSerializer
from taiga.projects.tagging.serializers import TaggedInProjectResourceSerializer
from taiga.projects.votes.mixins.serializers import VoteResourceSerializerMixin
class IssueListSerializer(VoteResourceSerializerMixin, WatchedResourceSerializer,
OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin,
StatusExtraInfoSerializerMixin, serializers.LightSerializer):
StatusExtraInfoSerializerMixin,
TaggedInProjectResourceSerializer, serializers.LightSerializer):
id = Field()
ref = Field()
severity = Field(attr="severity_id")
@ -45,7 +47,6 @@ class IssueListSerializer(VoteResourceSerializerMixin, WatchedResourceSerializer
external_reference = Field()
version = Field()
watchers = Field()
tags = Field()
is_closed = Field()

View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# 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 taiga.base.fields import MethodField
class TaggedInProjectResourceSerializer(serializers.LightSerializer):
tags = MethodField()
def get_tags(self, obj):
if not obj.tags:
return []
project_tag_colors = dict(obj.project.tags_colors)
return [[tag, project_tag_colors.get(tag, None)] for tag in obj.tags]

View File

@ -20,6 +20,7 @@ from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
from taiga.base.exceptions import ValidationError
from . import services
from . import fields
@ -43,14 +44,14 @@ class CreateTagValidator(ProjectTagValidator):
def validate_tag(self, attrs, source):
tag = attrs.get(source, None)
if services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag exists."))
raise ValidationError(_("The tag exists."))
return attrs
def validate_color(self, attrs, source):
color = attrs.get(source, None)
if not re.match('^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$', color):
raise validators.ValidationError(_("The color is not a valid HEX color."))
if color is not None and not re.match('^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$', color):
raise ValidationError(_("The color is not a valid HEX color."))
return attrs
@ -63,21 +64,21 @@ class EditTagTagValidator(ProjectTagValidator):
def validate_from_tag(self, attrs, source):
tag = attrs.get(source, None)
if not services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag doesn't exist."))
raise ValidationError(_("The tag doesn't exist."))
return attrs
def validate_to_tag(self, attrs, source):
tag = attrs.get(source, None)
if services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag exists yet"))
raise ValidationError(_("The tag exists yet"))
return attrs
def validate_color(self, attrs, source):
color = attrs.get(source, None)
if not re.match('^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$', color):
raise validators.ValidationError(_("The color is not a valid HEX color."))
raise ValidationError(_("The color is not a valid HEX color."))
return attrs
@ -88,7 +89,7 @@ class DeleteTagValidator(ProjectTagValidator):
def validate_tag(self, attrs, source):
tag = attrs.get(source, None)
if not services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag doesn't exist."))
raise ValidationError(_("The tag doesn't exist."))
return attrs
@ -101,13 +102,13 @@ class MixTagsValidator(ProjectTagValidator):
tags = attrs.get(source, None)
for tag in tags:
if not services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag doesn't exist."))
raise ValidationError(_("The tag doesn't exist."))
return attrs
def validate_to_tag(self, attrs, source):
tag = attrs.get(source, None)
if not services.tag_exist_for_project_elements(self.project, tag):
raise validators.ValidationError(_("The tag doesn't exist."))
raise ValidationError(_("The tag doesn't exist."))
return attrs

View File

@ -26,13 +26,14 @@ from taiga.projects.mixins.serializers import OwnerExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import AssignedToExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import StatusExtraInfoSerializerMixin
from taiga.projects.notifications.mixins import WatchedResourceSerializer
from taiga.projects.tagging.serializers import TaggedInProjectResourceSerializer
from taiga.projects.votes.mixins.serializers import VoteResourceSerializerMixin
class TaskListSerializer(VoteResourceSerializerMixin, WatchedResourceSerializer,
OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin,
StatusExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin,
serializers.LightSerializer):
TaggedInProjectResourceSerializer, serializers.LightSerializer):
id = Field()
user_story = Field(attr="user_story_id")
@ -52,7 +53,6 @@ class TaskListSerializer(VoteResourceSerializerMixin, WatchedResourceSerializer,
watchers = Field()
is_blocked = Field()
blocked_note = Field()
tags = Field()
is_closed = MethodField()
def get_milestone_slug(self, obj):

View File

@ -22,6 +22,7 @@ from taiga.base.neighbors import NeighborsSerializerMixin
from taiga.mdrender.service import render as mdrender
from taiga.projects.attachments.serializers import BasicAttachmentsInfoSerializerMixin
from taiga.projects.tagging.serializers import TaggedInProjectResourceSerializer
from taiga.projects.mixins.serializers import OwnerExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import AssignedToExtraInfoSerializerMixin
from taiga.projects.mixins.serializers import StatusExtraInfoSerializerMixin
@ -45,6 +46,7 @@ class UserStoryListSerializer(
VoteResourceSerializerMixin, WatchedResourceSerializer,
OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin,
StatusExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin,
TaggedInProjectResourceSerializer,
serializers.LightSerializer):
id = Field()
@ -71,7 +73,6 @@ class UserStoryListSerializer(
watchers = Field()
is_blocked = Field()
blocked_note = Field()
tags = Field()
total_points = MethodField()
comment = MethodField()
origin_issue = OriginIssueSerializer(attr="generated_from_issue")

View File

@ -123,7 +123,7 @@ def test_api_issue_add_new_tags_with_colors(client):
def test_api_create_new_issue_with_tags(client):
project = f.ProjectFactory.create()
project = f.ProjectFactory.create(tags_colors=[["front", "#aaaaaa"], ["ux", "#fabada"]])
status = f.IssueStatusFactory.create(project=project)
project.default_issue_status = status
project.save()
@ -145,16 +145,17 @@ def test_api_create_new_issue_with_tags(client):
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201, response.data
assert ("back" in response.data["tags"] and
"front" in response.data["tags"] and
"ux" in response.data["tags"])
issue_tags_colors = OrderedDict(response.data["tags"])
assert issue_tags_colors["back"] == "#fff8e7"
assert issue_tags_colors["front"] == "#aaaaaa"
assert issue_tags_colors["ux"] == "#fabada"
tags_colors = OrderedDict(project.tags_colors)
assert not tags_colors.keys()
project.refresh_from_db()
tags_colors = OrderedDict(project.tags_colors)
assert "back" in tags_colors and "front" in tags_colors and "ux" in tags_colors
assert tags_colors["back"] == "#fff8e7"
assert tags_colors["ux"] == "#fabada"
assert tags_colors["front"] == "#aaaaaa"

View File

@ -123,7 +123,7 @@ def test_api_task_add_new_tags_with_colors(client):
def test_api_create_new_task_with_tags(client):
project = f.ProjectFactory.create()
project = f.ProjectFactory.create(tags_colors=[["front", "#aaaaaa"], ["ux", "#fabada"]])
status = f.TaskStatusFactory.create(project=project)
project.default_task_status = status
project.save()
@ -135,8 +135,8 @@ def test_api_create_new_task_with_tags(client):
"project": project.id,
"tags": [
["back", "#fff8e7"],
["front", None],
["ux", "#fabada"]
["front", "#bbbbbb"],
["ux", None]
]
}
@ -145,16 +145,17 @@ def test_api_create_new_task_with_tags(client):
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201, response.data
assert ("back" in response.data["tags"] and
"front" in response.data["tags"] and
"ux" in response.data["tags"])
task_tags_colors = OrderedDict(response.data["tags"])
assert task_tags_colors["back"] == "#fff8e7"
assert task_tags_colors["front"] == "#aaaaaa"
assert task_tags_colors["ux"] == "#fabada"
tags_colors = OrderedDict(project.tags_colors)
assert not tags_colors.keys()
project.refresh_from_db()
tags_colors = OrderedDict(project.tags_colors)
assert "back" in tags_colors and "front" in tags_colors and "ux" in tags_colors
assert tags_colors["back"] == "#fff8e7"
assert tags_colors["ux"] == "#fabada"
assert tags_colors["front"] == "#aaaaaa"

View File

@ -123,7 +123,7 @@ def test_api_user_story_add_new_tags_with_colors(client):
def test_api_create_new_user_story_with_tags(client):
project = f.ProjectFactory.create()
project = f.ProjectFactory.create(tags_colors=[["front", "#aaaaaa"], ["ux", "#fabada"]])
status = f.UserStoryStatusFactory.create(project=project)
project.default_userstory_status = status
project.save()
@ -135,8 +135,8 @@ def test_api_create_new_user_story_with_tags(client):
"project": project.id,
"tags": [
["back", "#fff8e7"],
["front", None],
["ux", "#fabada"]
["front", "#bbbbbb"],
["ux", None]
]
}
@ -145,16 +145,17 @@ def test_api_create_new_user_story_with_tags(client):
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201, response.data
assert ("back" in response.data["tags"] and
"front" in response.data["tags"] and
"ux" in response.data["tags"])
us_tags_colors = OrderedDict(response.data["tags"])
assert us_tags_colors["back"] == "#fff8e7"
assert us_tags_colors["front"] == "#aaaaaa"
assert us_tags_colors["ux"] == "#fabada"
tags_colors = OrderedDict(project.tags_colors)
assert not tags_colors.keys()
project.refresh_from_db()
tags_colors = OrderedDict(project.tags_colors)
assert "back" in tags_colors and "front" in tags_colors and "ux" in tags_colors
assert tags_colors["back"] == "#fff8e7"
assert tags_colors["ux"] == "#fabada"
assert tags_colors["front"] == "#aaaaaa"