Merge pull request #804 from taigaio/Refactoring-tags-and-colors-in-API
Refactoring tags and colors in APIremotes/origin/issue/4795/notification_even_they_are_disabled
commit
f20a9737a1
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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]
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue