Fixing tags actions with epics
parent
f8a1c8f4a3
commit
9a06a8df94
|
@ -24,7 +24,7 @@ def tag_exist_for_project_elements(project, tag):
|
|||
|
||||
|
||||
def create_tags(project, new_tags_colors):
|
||||
project.tags_colors += [[k, v] for k,v in new_tags_colors.items()]
|
||||
project.tags_colors += [[k, v] for k, v in new_tags_colors.items()]
|
||||
project.save(update_fields=["tags_colors"])
|
||||
|
||||
|
||||
|
@ -33,41 +33,8 @@ def create_tag(project, tag, color):
|
|||
project.save(update_fields=["tags_colors"])
|
||||
|
||||
|
||||
def edit_tag(project, from_tag, to_tag=None, color=None):
|
||||
tags_colors = dict(project.tags_colors)
|
||||
|
||||
if color is not None:
|
||||
tags_colors = dict(project.tags_colors)
|
||||
tags_colors[from_tag] = color
|
||||
|
||||
if to_tag is not None:
|
||||
color = dict(project.tags_colors)[from_tag]
|
||||
sql = """
|
||||
UPDATE userstories_userstory
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE tasks_task
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE issues_issue
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
"""
|
||||
sql = sql.format(project_id=project.id, from_tag=from_tag, to_tag=to_tag)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(sql)
|
||||
|
||||
tags_colors[to_tag] = tags_colors.pop(from_tag)
|
||||
|
||||
|
||||
project.tags_colors = list(tags_colors.items())
|
||||
project.save(update_fields=["tags_colors"])
|
||||
|
||||
|
||||
def rename_tag(project, from_tag, to_tag, color=None):
|
||||
color = color or dict(project.tags_colors)[from_tag]
|
||||
def edit_tag(project, from_tag, to_tag, color):
|
||||
print("edit_tag", project, from_tag, to_tag, color)
|
||||
sql = """
|
||||
UPDATE userstories_userstory
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
|
@ -80,6 +47,45 @@ def rename_tag(project, from_tag, to_tag, color=None):
|
|||
UPDATE issues_issue
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE epics_epic
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
"""
|
||||
sql = sql.format(project_id=project.id, from_tag=from_tag, to_tag=to_tag)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(sql)
|
||||
|
||||
tags_colors = dict(project.tags_colors)
|
||||
tags_colors.pop(from_tag)
|
||||
tags_colors[to_tag] = color
|
||||
project.tags_colors = list(tags_colors.items())
|
||||
project.save(update_fields=["tags_colors"])
|
||||
|
||||
|
||||
def rename_tag(project, from_tag, to_tag, **kwargs):
|
||||
# Kwargs can have a color parameter
|
||||
update_color = "color" in kwargs
|
||||
if update_color:
|
||||
color = kwargs.get("color")
|
||||
else:
|
||||
color = dict(project.tags_colors)[from_tag]
|
||||
sql = """
|
||||
UPDATE userstories_userstory
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE tasks_task
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE issues_issue
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE epics_epic
|
||||
SET tags = array_distinct(array_replace(tags, '{from_tag}', '{to_tag}'))
|
||||
WHERE project_id = {project_id};
|
||||
"""
|
||||
sql = sql.format(project_id=project.id, from_tag=from_tag, to_tag=to_tag, color=color)
|
||||
cursor = connection.cursor()
|
||||
|
@ -105,6 +111,10 @@ def delete_tag(project, tag):
|
|||
UPDATE issues_issue
|
||||
SET tags = array_remove(tags, '{tag}')
|
||||
WHERE project_id = {project_id};
|
||||
|
||||
UPDATE epics_epic
|
||||
SET tags = array_remove(tags, '{tag}')
|
||||
WHERE project_id = {project_id};
|
||||
"""
|
||||
sql = sql.format(project_id=project.id, tag=tag)
|
||||
cursor = connection.cursor()
|
||||
|
@ -119,4 +129,4 @@ def delete_tag(project, tag):
|
|||
def mix_tags(project, from_tags, to_tag):
|
||||
color = dict(project.tags_colors)[to_tag]
|
||||
for from_tag in from_tags:
|
||||
rename_tag(project, from_tag, to_tag, color)
|
||||
rename_tag(project, from_tag, to_tag, color=color)
|
||||
|
|
|
@ -82,6 +82,15 @@ class EditTagTagValidator(ProjectTagValidator):
|
|||
|
||||
return attrs
|
||||
|
||||
def validate(self, data):
|
||||
if "to_tag" not in data:
|
||||
data["to_tag"] = data.get("from_tag")
|
||||
|
||||
if "color" not in data:
|
||||
data["color"] = dict(self.project.tags_colors).get(data.get("from_tag"))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class DeleteTagValidator(ProjectTagValidator):
|
||||
tag = serializers.CharField()
|
||||
|
|
|
@ -670,6 +670,26 @@ def create_userstory(**kwargs):
|
|||
return UserStoryFactory(**defaults)
|
||||
|
||||
|
||||
def create_epic(**kwargs):
|
||||
"Create an epic along with its dependencies"
|
||||
|
||||
owner = kwargs.pop("owner", None)
|
||||
if not owner:
|
||||
owner = UserFactory.create()
|
||||
|
||||
project = kwargs.pop("project", None)
|
||||
if project is None:
|
||||
project = ProjectFactory.create(owner=owner)
|
||||
|
||||
defaults = {
|
||||
"project": project,
|
||||
"owner": owner,
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
|
||||
return EpicFactory(**defaults)
|
||||
|
||||
|
||||
def create_project(**kwargs):
|
||||
"Create a project along with its dependencies"
|
||||
defaults = {}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
# -*- 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>
|
||||
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me>
|
||||
# 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 unittest import mock
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.base.utils import json
|
||||
|
||||
from .. import factories as f
|
||||
|
||||
import pytest
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_api_epic_add_new_tags_with_error(client):
|
||||
project = f.ProjectFactory.create()
|
||||
epic = f.create_epic(project=project, status__project=project)
|
||||
f.MembershipFactory.create(project=project, user=epic.owner, is_admin=True)
|
||||
url = reverse("epics-detail", kwargs={"pk": epic.pk})
|
||||
data = {
|
||||
"tags": [],
|
||||
"version": epic.version
|
||||
}
|
||||
|
||||
client.login(epic.owner)
|
||||
|
||||
data["tags"] = [1]
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 400, response.data
|
||||
assert "tags" in response.data
|
||||
|
||||
data["tags"] = [["back"]]
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 400, response.data
|
||||
assert "tags" in response.data
|
||||
|
||||
data["tags"] = [["back", "#cccc"]]
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 400, response.data
|
||||
assert "tags" in response.data
|
||||
|
||||
data["tags"] = [[1, "#ccc"]]
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 400, response.data
|
||||
assert "tags" in response.data
|
||||
|
||||
|
||||
def test_api_epic_add_new_tags_without_colors(client):
|
||||
project = f.ProjectFactory.create()
|
||||
epic = f.create_epic(project=project, status__project=project)
|
||||
f.MembershipFactory.create(project=project, user=epic.owner, is_admin=True)
|
||||
url = reverse("epics-detail", kwargs={"pk": epic.pk})
|
||||
data = {
|
||||
"tags": [
|
||||
["back", None],
|
||||
["front", None],
|
||||
["ux", None]
|
||||
],
|
||||
"version": epic.version
|
||||
}
|
||||
|
||||
client.login(epic.owner)
|
||||
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
|
||||
assert response.status_code == 200, response.data
|
||||
|
||||
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
|
||||
|
||||
|
||||
def test_api_epic_add_new_tags_with_colors(client):
|
||||
project = f.ProjectFactory.create()
|
||||
epic = f.create_epic(project=project, status__project=project)
|
||||
f.MembershipFactory.create(project=project, user=epic.owner, is_admin=True)
|
||||
url = reverse("epics-detail", kwargs={"pk": epic.pk})
|
||||
data = {
|
||||
"tags": [
|
||||
["back", "#fff8e7"],
|
||||
["front", None],
|
||||
["ux", "#fabada"]
|
||||
],
|
||||
"version": epic.version
|
||||
}
|
||||
|
||||
client.login(epic.owner)
|
||||
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert response.status_code == 200, response.data
|
||||
|
||||
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"
|
||||
|
||||
|
||||
def test_api_create_new_epic_with_tags(client):
|
||||
project = f.ProjectFactory.create(tags_colors=[["front", "#aaaaaa"], ["ux", "#fabada"]])
|
||||
status = f.EpicStatusFactory.create(project=project)
|
||||
project.default_epic_status = status
|
||||
project.save()
|
||||
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
|
||||
url = reverse("epics-list")
|
||||
|
||||
data = {
|
||||
"subject": "Test user story",
|
||||
"project": project.id,
|
||||
"tags": [
|
||||
["back", "#fff8e7"],
|
||||
["front", None],
|
||||
["ux", "#fabada"]
|
||||
]
|
||||
}
|
||||
|
||||
client.login(project.owner)
|
||||
|
||||
response = client.json.post(url, json.dumps(data))
|
||||
assert response.status_code == 201, response.data
|
||||
|
||||
epic_tags_colors = OrderedDict(response.data["tags"])
|
||||
|
||||
assert epic_tags_colors["back"] == "#fff8e7"
|
||||
assert epic_tags_colors["front"] == "#aaaaaa"
|
||||
assert epic_tags_colors["ux"] == "#fabada"
|
||||
|
||||
tags_colors = OrderedDict(project.tags_colors)
|
||||
|
||||
project.refresh_from_db()
|
||||
|
||||
tags_colors = OrderedDict(project.tags_colors)
|
||||
assert tags_colors["back"] == "#fff8e7"
|
||||
assert tags_colors["ux"] == "#fabada"
|
||||
assert tags_colors["front"] == "#aaaaaa"
|
|
@ -31,6 +31,7 @@ from taiga.projects.models import Project
|
|||
from taiga.projects.userstories.models import UserStory
|
||||
from taiga.projects.tasks.models import Task
|
||||
from taiga.projects.issues.models import Issue
|
||||
from taiga.projects.epics.models import Epic
|
||||
from taiga.projects.choices import BLOCKED_BY_DELETING
|
||||
|
||||
from .. import factories as f
|
||||
|
@ -1918,6 +1919,7 @@ def test_edit_tag_only_name(client, settings):
|
|||
user_story = f.UserStoryFactory.create(project=project, tags=["tag"])
|
||||
task = f.TaskFactory.create(project=project, tags=["tag"])
|
||||
issue = f.IssueFactory.create(project=project, tags=["tag"])
|
||||
epic = f.EpicFactory.create(project=project, tags=["tag"])
|
||||
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
membership = f.MembershipFactory.create(project=project, user=user, role=role, is_admin=True)
|
||||
|
@ -1940,6 +1942,8 @@ def test_edit_tag_only_name(client, settings):
|
|||
assert task.tags == ["renamed_tag"]
|
||||
issue = Issue.objects.get(id=issue.pk)
|
||||
assert issue.tags == ["renamed_tag"]
|
||||
epic = Epic.objects.get(id=epic.pk)
|
||||
assert epic.tags == ["renamed_tag"]
|
||||
|
||||
|
||||
def test_edit_tag_only_color(client, settings):
|
||||
|
@ -1948,6 +1952,7 @@ def test_edit_tag_only_color(client, settings):
|
|||
user_story = f.UserStoryFactory.create(project=project, tags=["tag"])
|
||||
task = f.TaskFactory.create(project=project, tags=["tag"])
|
||||
issue = f.IssueFactory.create(project=project, tags=["tag"])
|
||||
epic = f.EpicFactory.create(project=project, tags=["tag"])
|
||||
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
membership = f.MembershipFactory.create(project=project, user=user, role=role, is_admin=True)
|
||||
|
@ -1969,6 +1974,8 @@ def test_edit_tag_only_color(client, settings):
|
|||
assert task.tags == ["tag"]
|
||||
issue = Issue.objects.get(id=issue.pk)
|
||||
assert issue.tags == ["tag"]
|
||||
epic = Epic.objects.get(id=epic.pk)
|
||||
assert epic.tags == ["tag"]
|
||||
|
||||
|
||||
def test_edit_tag(client, settings):
|
||||
|
@ -1977,6 +1984,7 @@ def test_edit_tag(client, settings):
|
|||
user_story = f.UserStoryFactory.create(project=project, tags=["tag"])
|
||||
task = f.TaskFactory.create(project=project, tags=["tag"])
|
||||
issue = f.IssueFactory.create(project=project, tags=["tag"])
|
||||
epic = f.EpicFactory.create(project=project, tags=["tag"])
|
||||
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
membership = f.MembershipFactory.create(project=project, user=user, role=role, is_admin=True)
|
||||
|
@ -1999,6 +2007,8 @@ def test_edit_tag(client, settings):
|
|||
assert task.tags == ["renamed_tag"]
|
||||
issue = Issue.objects.get(id=issue.pk)
|
||||
assert issue.tags == ["renamed_tag"]
|
||||
epic = Epic.objects.get(id=epic.pk)
|
||||
assert epic.tags == ["renamed_tag"]
|
||||
|
||||
|
||||
def test_delete_tag(client, settings):
|
||||
|
@ -2007,6 +2017,7 @@ def test_delete_tag(client, settings):
|
|||
user_story = f.UserStoryFactory.create(project=project, tags=["tag"])
|
||||
task = f.TaskFactory.create(project=project, tags=["tag"])
|
||||
issue = f.IssueFactory.create(project=project, tags=["tag"])
|
||||
epic = f.EpicFactory.create(project=project, tags=["tag"])
|
||||
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
membership = f.MembershipFactory.create(project=project, user=user, role=role, is_admin=True)
|
||||
|
@ -2027,6 +2038,8 @@ def test_delete_tag(client, settings):
|
|||
assert task.tags == []
|
||||
issue = Issue.objects.get(id=issue.pk)
|
||||
assert issue.tags == []
|
||||
epic = Epic.objects.get(id=epic.pk)
|
||||
assert epic.tags == []
|
||||
|
||||
|
||||
def test_mix_tags(client, settings):
|
||||
|
@ -2035,6 +2048,7 @@ def test_mix_tags(client, settings):
|
|||
user_story = f.UserStoryFactory.create(project=project, tags=["tag1", "tag3"])
|
||||
task = f.TaskFactory.create(project=project, tags=["tag2", "tag3"])
|
||||
issue = f.IssueFactory.create(project=project, tags=["tag1", "tag2", "tag3"])
|
||||
epic = f.EpicFactory.create(project=project, tags=["tag1", "tag2", "tag3"])
|
||||
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
membership = f.MembershipFactory.create(project=project, user=user, role=role, is_admin=True)
|
||||
|
@ -2056,6 +2070,8 @@ def test_mix_tags(client, settings):
|
|||
assert set(task.tags) == set(["tag2", "tag3"])
|
||||
issue = Issue.objects.get(id=issue.pk)
|
||||
assert set(issue.tags) == set(["tag2", "tag3"])
|
||||
epic = Epic.objects.get(id=epic.pk)
|
||||
assert set(epic.tags) == set(["tag2", "tag3"])
|
||||
|
||||
|
||||
def test_color_tags_project_fired_on_element_create():
|
||||
|
|
Loading…
Reference in New Issue