US #55: Custom fields - Create empty CustomAttributesValues when added USs, Tasks and Issues

remotes/origin/enhancement/email-actions
David Barragán Merino 2015-02-19 12:56:07 +01:00
parent 3369fa41f0
commit e8078aaaa5
18 changed files with 238 additions and 567 deletions

View File

@ -19,10 +19,12 @@
from .viewsets import ModelListViewSet from .viewsets import ModelListViewSet
from .viewsets import ModelCrudViewSet from .viewsets import ModelCrudViewSet
from .viewsets import ModelUpdateRetrieveViewSet
from .viewsets import GenericViewSet from .viewsets import GenericViewSet
from .viewsets import ReadOnlyListViewSet from .viewsets import ReadOnlyListViewSet
__all__ = ["ModelCrudViewSet", __all__ = ["ModelCrudViewSet",
"ModelListViewSet", "ModelListViewSet",
"ModelUpdateRetrieveViewSet",
"GenericViewSet", "GenericViewSet",
"ReadOnlyListViewSet"] "ReadOnlyListViewSet"]

View File

@ -168,3 +168,8 @@ class ModelListViewSet(pagination.HeadersPaginationMixin,
mixins.ListModelMixin, mixins.ListModelMixin,
GenericViewSet): GenericViewSet):
pass pass
class ModelUpdateRetrieveViewSet(mixins.UpdateModelMixin,
mixins.RetrieveModelMixin,
GenericViewSet):
pass

View File

@ -22,6 +22,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers from rest_framework import serializers

View File

@ -20,6 +20,7 @@ from unidecode import unidecode
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from taiga.projects.history.services import make_key_from_model_object from taiga.projects.history.services import make_key_from_model_object
from taiga.projects.references import sequences as seq from taiga.projects.references import sequences as seq
@ -108,13 +109,19 @@ def store_custom_attributes(project, data, field, serializer):
result.append(_store_custom_attribute(project, custom_attribute_data, field, serializer)) result.append(_store_custom_attribute(project, custom_attribute_data, field, serializer))
return result return result
def store_custom_attributes_values(obj, data_values, obj_field, serializer_class): def store_custom_attributes_values(obj, data_values, obj_field, serializer_class):
data = { data = {
obj_field: obj.id, obj_field: obj.id,
"attributes_values": data_values, "attributes_values": data_values,
} }
serializer = serializer_class(data=data) try:
custom_attributes_values = obj.custom_attributes_values
serializer = serializer_class(custom_attributes_values, data=data)
except ObjectDoesNotExist:
serializer = serializer_class(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
return serializer return serializer

View File

@ -17,7 +17,7 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from taiga.base.api import ModelCrudViewSet from taiga.base.api import ModelCrudViewSet
from taiga.base.api.viewsets import ModelViewSet from taiga.base.api import ModelUpdateRetrieveViewSet
from taiga.base import exceptions as exc from taiga.base import exceptions as exc
from taiga.base import filters from taiga.base import filters
from taiga.base import response from taiga.base import response
@ -73,16 +73,7 @@ class IssueCustomAttributeViewSet(ModelCrudViewSet, BulkUpdateOrderMixin):
# Custom Attributes Values ViewSets # Custom Attributes Values ViewSets
####################################################### #######################################################
class BaseCustomAttributesValuesViewSet(OCCResourceMixin, HistoryResourceMixin, ModelViewSet): class BaseCustomAttributesValuesViewSet(OCCResourceMixin, HistoryResourceMixin, ModelUpdateRetrieveViewSet):
def list(self, request, *args, **kwargs):
return response.NotFound()
def post_delete(self, obj):
# NOTE: When destroy a custom attributes values object, the
# content_object change after and not before
self.persist_history_snapshot(obj, delete=True)
super().pre_delete(obj)
def get_object_for_snapshot(self, obj): def get_object_for_snapshot(self, obj):
return getattr(obj, self.content_object) return getattr(obj, self.content_object)

View File

@ -9,8 +9,8 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('tasks', '0005_auto_20150114_0954'), ('tasks', '0005_auto_20150114_0954'),
('userstories', '0009_remove_userstory_is_archived'),
('issues', '0004_auto_20150114_0954'), ('issues', '0004_auto_20150114_0954'),
('userstories', '0009_remove_userstory_is_archived'),
('custom_attributes', '0001_initial'), ('custom_attributes', '0001_initial'),
] ]
@ -18,14 +18,14 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='IssueCustomAttributesValues', name='IssueCustomAttributesValues',
fields=[ fields=[
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)), ('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID', auto_created=True)),
('version', models.IntegerField(default=1, verbose_name='version')), ('version', models.IntegerField(default=1, verbose_name='version')),
('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes values')), ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')),
('issue', models.OneToOneField(related_name='custom_attributes_values', to='issues.Issue', verbose_name='issue')), ('issue', models.OneToOneField(verbose_name='issue', to='issues.Issue', related_name='custom_attributes_values')),
], ],
options={ options={
'ordering': ['id'],
'verbose_name_plural': 'issue custom attributes values', 'verbose_name_plural': 'issue custom attributes values',
'ordering': ['id'],
'verbose_name': 'issue ustom attributes values', 'verbose_name': 'issue ustom attributes values',
'abstract': False, 'abstract': False,
}, },
@ -34,14 +34,14 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='TaskCustomAttributesValues', name='TaskCustomAttributesValues',
fields=[ fields=[
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)), ('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID', auto_created=True)),
('version', models.IntegerField(default=1, verbose_name='version')), ('version', models.IntegerField(default=1, verbose_name='version')),
('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes values')), ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')),
('task', models.OneToOneField(related_name='custom_attributes_values', to='tasks.Task', verbose_name='task')), ('task', models.OneToOneField(verbose_name='task', to='tasks.Task', related_name='custom_attributes_values')),
], ],
options={ options={
'ordering': ['id'],
'verbose_name_plural': 'task custom attributes values', 'verbose_name_plural': 'task custom attributes values',
'ordering': ['id'],
'verbose_name': 'task ustom attributes values', 'verbose_name': 'task ustom attributes values',
'abstract': False, 'abstract': False,
}, },
@ -50,14 +50,14 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='UserStoryCustomAttributesValues', name='UserStoryCustomAttributesValues',
fields=[ fields=[
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)), ('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID', auto_created=True)),
('version', models.IntegerField(default=1, verbose_name='version')), ('version', models.IntegerField(default=1, verbose_name='version')),
('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes values')), ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')),
('user_story', models.OneToOneField(related_name='custom_attributes_values', to='userstories.UserStory', verbose_name='user story')), ('user_story', models.OneToOneField(verbose_name='user story', to='userstories.UserStory', related_name='custom_attributes_values')),
], ],
options={ options={
'ordering': ['id'],
'verbose_name_plural': 'user story custom attributes values', 'verbose_name_plural': 'user story custom attributes values',
'ordering': ['id'],
'verbose_name': 'user story ustom attributes values', 'verbose_name': 'user story ustom attributes values',
'abstract': False, 'abstract': False,
}, },

View File

@ -25,7 +25,8 @@ class Migration(migrations.Migration):
WHERE "key" <> ALL ("keys_to_delete")), WHERE "key" <> ALL ("keys_to_delete")),
'{}')::json $function$; '{}')::json $function$;
""", """,
reverse_sql="""DROP FUNCTION IF EXISTS "json_object_delete_keys";""" reverse_sql="""DROP FUNCTION IF EXISTS "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" text[])
CASCADE;"""
), ),
# Function: Romeve a key in the json field of *_custom_attributes_values.values # Function: Romeve a key in the json field of *_custom_attributes_values.values
@ -50,39 +51,46 @@ class Migration(migrations.Migration):
LANGUAGE plpgsql; LANGUAGE plpgsql;
""", """,
reverse_sql="""DROP FUNCTION IF EXISTS "clean_key_in_custom_attributes_values";""" reverse_sql="""DROP FUNCTION IF EXISTS "clean_key_in_custom_attributes_values"()
CASCADE;"""
), ),
# Trigger: Clean userstorycustomattributes values before remove a userstorycustomattribute # Trigger: Clean userstorycustomattributes values before remove a userstorycustomattribute
migrations.RunSQL( migrations.RunSQL(
""" """
CREATE TRIGGER "update_userstorycustomvalues_afeter_remove_userstorycustomattribute" CREATE TRIGGER "update_userstorycustomvalues_after_remove_userstorycustomattribute"
BEFORE DELETE ON custom_attributes_userstorycustomattribute BEFORE DELETE ON custom_attributes_userstorycustomattribute
FOR EACH ROW FOR EACH ROW
EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_userstorycustomattributesvalues'); EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_userstorycustomattributesvalues');
""", """,
reverse_sql="""DROP TRIGGER "update_userstorycustomvalues_afeter_remove_userstorycustomattribute";""" reverse_sql="""DROP TRIGGER IF EXISTS "update_userstorycustomvalues_after_remove_userstorycustomattribute"
ON custom_attributes_userstorycustomattribute
CASCADE;"""
), ),
# Trigger: Clean taskcustomattributes values before remove a taskcustomattribute # Trigger: Clean taskcustomattributes values before remove a taskcustomattribute
migrations.RunSQL( migrations.RunSQL(
""" """
CREATE TRIGGER "update_taskcustomvalues_afeter_remove_taskcustomattribute" CREATE TRIGGER "update_taskcustomvalues_after_remove_taskcustomattribute"
BEFORE DELETE ON custom_attributes_taskcustomattribute BEFORE DELETE ON custom_attributes_taskcustomattribute
FOR EACH ROW FOR EACH ROW
EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_taskcustomattributesvalues'); EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_taskcustomattributesvalues');
""", """,
reverse_sql="""DROP TRIGGER "update_taskcustomvalues_afeter_remove_taskcustomattribute";""" reverse_sql="""DROP TRIGGER IF EXISTS "update_taskcustomvalues_after_remove_taskcustomattribute"
ON custom_attributes_taskcustomattribute
CASCADE;"""
), ),
# Trigger: Clean issuecustomattributes values before remove a issuecustomattribute # Trigger: Clean issuecustomattributes values before remove a issuecustomattribute
migrations.RunSQL( migrations.RunSQL(
""" """
CREATE TRIGGER "update_issuecustomvalues_afeter_remove_issuecustomattribute" CREATE TRIGGER "update_issuecustomvalues_after_remove_issuecustomattribute"
BEFORE DELETE ON custom_attributes_issuecustomattribute BEFORE DELETE ON custom_attributes_issuecustomattribute
FOR EACH ROW FOR EACH ROW
EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_issuecustomattributesvalues'); EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_issuecustomattributesvalues');
""", """,
reverse_sql="""DROP TRIGGER "update_issuecustomvalues_afeter_remove_issuecustomattribute";""" reverse_sql="""DROP TRIGGER IF EXISTS "update_issuecustomvalues_after_remove_issuecustomattribute"
ON custom_attributes_issuecustomattribute
CASCADE;"""
) )
] ]

View File

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
def create_empty_user_story_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "UserStoryCustomAttributesValues")
obj_model = apps.get_model("userstories", "UserStory")
db_alias = schema_editor.connection.alias
data = []
for user_story in obj_model.objects.using(db_alias).all().select_related("custom_attributes_values"):
if not hasattr(user_story, "custom_attributes_values"):
data.append(cav_model(user_story=user_story,attributes_values={}))
cav_model.objects.using(db_alias).bulk_create(data)
def delete_empty_user_story_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "UserStoryCustomAttributesValues")
db_alias = schema_editor.connection.alias
cav_model.objects.using(db_alias).extra(where=["attributes_values::text <> '{}'::text"]).delete()
def create_empty_task_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "TaskCustomAttributesValues")
obj_model = apps.get_model("tasks", "Task")
db_alias = schema_editor.connection.alias
data = []
for task in obj_model.objects.using(db_alias).all().select_related("custom_attributes_values"):
if not hasattr(task, "custom_attributes_values"):
data.append(cav_model(task=task,attributes_values={}))
cav_model.objects.using(db_alias).bulk_create(data)
def delete_empty_task_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "TaskCustomAttributesValues")
db_alias = schema_editor.connection.alias
cav_model.objects.using(db_alias).extra(where=["attributes_values::text <> '{}'::text"]).delete()
def create_empty_issues_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "IssueCustomAttributesValues")
obj_model = apps.get_model("issues", "Issue")
db_alias = schema_editor.connection.alias
data = []
for issue in obj_model.objects.using(db_alias).all().select_related("custom_attributes_values"):
if not hasattr(issue, "custom_attributes_values"):
data.append(cav_model(issue=issue,attributes_values={}))
cav_model.objects.using(db_alias).bulk_create(data)
def delete_empty_issue_custom_attrributes_values(apps, schema_editor):
cav_model = apps.get_model("custom_attributes", "IssueCustomAttributesValues")
db_alias = schema_editor.connection.alias
cav_model.objects.using(db_alias).extra(where=["attributes_values::text <> '{}'::text"]).delete()
class Migration(migrations.Migration):
dependencies = [
('custom_attributes', '0003_triggers_on_delete_customattribute'),
]
operations = [
migrations.RunPython(create_empty_user_story_custom_attrributes_values,
reverse_code=delete_empty_user_story_custom_attrributes_values,
atomic=True),
migrations.RunPython(create_empty_task_custom_attrributes_values,
reverse_code=delete_empty_task_custom_attrributes_values,
atomic=True),
migrations.RunPython(create_empty_issues_custom_attrributes_values,
reverse_code=delete_empty_issue_custom_attrributes_values,
atomic=True),
]

View File

@ -66,24 +66,18 @@ class UserStoryCustomAttributesValuesPermission(TaigaResourcePermission):
enought_perms = IsProjectOwner() | IsSuperUser() enought_perms = IsProjectOwner() | IsSuperUser()
global_perms = None global_perms = None
retrieve_perms = HasProjectPerm('view_us') retrieve_perms = HasProjectPerm('view_us')
create_perms = HasProjectPerm('add_us')
update_perms = HasProjectPerm('modify_us') update_perms = HasProjectPerm('modify_us')
destroy_perms = HasProjectPerm('delete_us')
class TaskCustomAttributesValuesPermission(TaigaResourcePermission): class TaskCustomAttributesValuesPermission(TaigaResourcePermission):
enought_perms = IsProjectOwner() | IsSuperUser() enought_perms = IsProjectOwner() | IsSuperUser()
global_perms = None global_perms = None
retrieve_perms = HasProjectPerm('view_tasks') retrieve_perms = HasProjectPerm('view_tasks')
create_perms = HasProjectPerm('add_task')
update_perms = HasProjectPerm('modify_task') update_perms = HasProjectPerm('modify_task')
destroy_perms = HasProjectPerm('delete_task')
class IssueCustomAttributesValuesPermission(TaigaResourcePermission): class IssueCustomAttributesValuesPermission(TaigaResourcePermission):
enought_perms = IsProjectOwner() | IsSuperUser() enought_perms = IsProjectOwner() | IsSuperUser()
global_perms = None global_perms = None
retrieve_perms = HasProjectPerm('view_issues') retrieve_perms = HasProjectPerm('view_issues')
create_perms = HasProjectPerm('add_issue')
update_perms = HasProjectPerm('modify_issue') update_perms = HasProjectPerm('modify_issue')
destroy_perms = HasProjectPerm('delete_issue')

View File

@ -0,0 +1,35 @@
# Copyright (C) 2015 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2015 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
# 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 . import models
def create_custom_attribute_value_when_create_user_story(sender, instance, created, **kwargs):
if created:
models.UserStoryCustomAttributesValues.objects.get_or_create(user_story=instance,
defaults={"attributes_values":{}})
def create_custom_attribute_value_when_create_task(sender, instance, created, **kwargs):
if created:
models.TaskCustomAttributesValues.objects.get_or_create(task=instance,
defaults={"attributes_values":{}})
def create_custom_attribute_value_when_create_issue(sender, instance, created, **kwargs):
if created:
models.IssueCustomAttributesValues.objects.get_or_create(issue=instance,
defaults={"attributes_values":{}})

View File

@ -19,6 +19,7 @@ from django.apps import apps
from django.db.models import signals from django.db.models import signals
from taiga.projects import signals as generic_handlers from taiga.projects import signals as generic_handlers
from taiga.projects.custom_attributes import signals as custom_attributes_handlers
from . import signals as handlers from . import signals as handlers
@ -39,3 +40,8 @@ class IssuesAppConfig(AppConfig):
sender=apps.get_model("issues", "Issue")) sender=apps.get_model("issues", "Issue"))
signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item,
sender=apps.get_model("issues", "Issue")) sender=apps.get_model("issues", "Issue"))
# Custom Attributes
signals.post_save.connect(custom_attributes_handlers.create_custom_attribute_value_when_create_issue,
sender=apps.get_model("issues", "Issue"),
dispatch_uid="create_custom_attribute_value_when_create_issue")

View File

@ -270,11 +270,13 @@ class Command(BaseCommand):
project=project)), project=project)),
tags=self.sd.words(1, 10).split(" ")) tags=self.sd.words(1, 10).split(" "))
custom_attributes_values = {str(ca.id): self.sd.paragraph() for ca in project.issuecustomattributes.all() bug.save()
custom_attributes_values = {str(ca.id): self.sd.words(1, 12) for ca in project.issuecustomattributes.all()
if self.sd.boolean()} if self.sd.boolean()}
if custom_attributes_values: if custom_attributes_values:
IssueCustomAttributesValues.objects.create(issue=bug, bug.custom_attributes_values.attributes_values = custom_attributes_values
attributes_values=custom_attributes_values) bug.custom_attributes_values.save()
for i in range(self.sd.int(*NUM_ATTACHMENTS)): for i in range(self.sd.int(*NUM_ATTACHMENTS)):
attachment = self.create_attachment(bug, i+1) attachment = self.create_attachment(bug, i+1)
@ -319,11 +321,11 @@ class Command(BaseCommand):
task.save() task.save()
custom_attributes_values = {str(ca.id): self.sd.paragraph() for ca in project.taskcustomattributes.all() custom_attributes_values = {str(ca.id): self.sd.words(1, 12) for ca in project.taskcustomattributes.all()
if self.sd.boolean()} if self.sd.boolean()}
if custom_attributes_values: if custom_attributes_values:
TaskCustomAttributesValues.objects.create(task=task, task.custom_attributes_values.attributes_values = custom_attributes_values
attributes_values=custom_attributes_values) task.custom_attributes_values.save()
for i in range(self.sd.int(*NUM_ATTACHMENTS)): for i in range(self.sd.int(*NUM_ATTACHMENTS)):
attachment = self.create_attachment(task, i+1) attachment = self.create_attachment(task, i+1)
@ -362,11 +364,13 @@ class Command(BaseCommand):
role_points.save() role_points.save()
custom_attributes_values = {str(ca.id): self.sd.paragraph() for ca in project.userstorycustomattributes.all() us.save()
custom_attributes_values = {str(ca.id): self.sd.words(1, 12) for ca in project.userstorycustomattributes.all()
if self.sd.boolean()} if self.sd.boolean()}
if custom_attributes_values: if custom_attributes_values:
UserStoryCustomAttributesValues.objects.create(user_story=us, us.custom_attributes_values.attributes_values = custom_attributes_values
attributes_values=custom_attributes_values) us.custom_attributes_values.save()
for i in range(self.sd.int(*NUM_ATTACHMENTS)): for i in range(self.sd.int(*NUM_ATTACHMENTS)):

View File

@ -19,6 +19,7 @@ from django.apps import apps
from django.db.models import signals from django.db.models import signals
from taiga.projects import signals as generic_handlers from taiga.projects import signals as generic_handlers
from taiga.projects.custom_attributes import signals as custom_attributes_handlers
from . import signals as handlers from . import signals as handlers
@ -44,3 +45,8 @@ class TasksAppConfig(AppConfig):
sender=apps.get_model("tasks", "Task")) sender=apps.get_model("tasks", "Task"))
signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item,
sender=apps.get_model("tasks", "Task")) sender=apps.get_model("tasks", "Task"))
# Custom Attributes
signals.post_save.connect(custom_attributes_handlers.create_custom_attribute_value_when_create_task,
sender=apps.get_model("tasks", "Task"),
dispatch_uid="create_custom_attribute_value_when_create_task")

View File

@ -19,6 +19,7 @@ from django.apps import apps
from django.db.models import signals from django.db.models import signals
from taiga.projects import signals as generic_handlers from taiga.projects import signals as generic_handlers
from taiga.projects.custom_attributes import signals as custom_attributes_handlers
from . import signals as handlers from . import signals as handlers
@ -52,3 +53,8 @@ class UserStoriesAppConfig(AppConfig):
sender=apps.get_model("userstories", "UserStory")) sender=apps.get_model("userstories", "UserStory"))
signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item,
sender=apps.get_model("userstories", "UserStory")) sender=apps.get_model("userstories", "UserStory"))
# Custom Attributes
signals.post_save.connect(custom_attributes_handlers.create_custom_attribute_value_when_create_user_story,
sender=apps.get_model("userstories", "UserStory"),
dispatch_uid="create_custom_attribute_value_when_create_user_story")

View File

@ -95,23 +95,6 @@ def data():
m.private_issue_ca1 = f.IssueCustomAttributeFactory(project=m.private_project1) m.private_issue_ca1 = f.IssueCustomAttributeFactory(project=m.private_project1)
m.private_issue_ca2 = f.IssueCustomAttributeFactory(project=m.private_project2) m.private_issue_ca2 = f.IssueCustomAttributeFactory(project=m.private_project2)
#m.public_issue = f.IssueFactory(project=m.public_project, owner=m.project_owner)
#m.private_issue1 = f.IssueFactory(project=m.private_project1, owner=m.project_owner)
#m.private_issue2 = f.IssueFactory(project=m.private_project2, owner=m.project_owner)
#m.public_issue_cav = f.IssueCustomAttributesValuesFactory(project=m.public_project,
# issue=f.IssueFactory(project=m.public_project,
# owner=m.project_owner),
# attributes_values={str(m.public_issue_ca.id):"test"})
#m.private_issue_cav1 = f.IssueCustomAttributesValuesFactory(project=m.private_project1,
# issue=f.IssueFactory(project=m.private_project1,
# owner=m.project_owner),
# attributes_values={str(m.private_issue_ca1.id):"test"})
#m.private_issue_cav2 = f.IssueCustomAttributesValuesFactory(project=m.private_project2,
# issue=f.IssueFactory(project=m.private_project2,
# owner=m.project_owner),
# attributes_values={str(m.private_issue_ca2.id):"test"})
return m return m
@ -302,127 +285,3 @@ def test_issue_custom_attribute_action_bulk_update_order(client, data):
}) })
results = helper_test_http_method(client, 'post', url, post_data, users) results = helper_test_http_method(client, 'post', url, post_data, users)
assert results == [401, 403, 403, 403, 204] assert results == [401, 403, 403, 403, 204]
#########################################################
# Issue Custom Attributes Values
#########################################################
#def test_issue_custom_attributes_values_retrieve(client, data):
# public_url = reverse('issue-custom-attributes-values-detail', args=[data.public_issue_cav.issue.id])
# private1_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav1.issue.id])
# private2_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav2.issue.id])
# users = [
# None,
# data.registered_user,
# data.project_member_without_perms,
# data.project_member_with_perms,
# data.project_owner
# ]
#
# results = helper_test_http_method(client, 'get', public_url, None, users)
# assert results == [200, 200, 200, 200, 200]
# results = helper_test_http_method(client, 'get', private1_url, None, users)
# assert results == [200, 200, 200, 200, 200]
# results = helper_test_http_method(client, 'get', private2_url, None, users)
# assert results == [401, 403, 403, 200, 200]
#
#
#def test_issue_custom_attributes_values_update(client, data):
# public_url = reverse('issue-custom-attributes-values-detail', args=[data.public_issue_cav.issue.id])
# private1_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav1.issue.id])
# private2_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav2.issue.id])
#
# users = [
# None,
# data.registered_user,
# data.project_member_without_perms,
# data.project_member_with_perms,
# data.project_owner
# ]
#
# issue_cav_data = serializers.IssueCustomAttributesValuesSerializer(data.public_issue_cav).data
# issue_cav_data["values"] = '{{"{}":"test-update"}}'.format(data.public_issue_ca.id)
# issue_cav_data = json.dumps(issue_cav_data)
# results = helper_test_http_method(client, 'put', public_url, issue_cav_data, users)
# assert results == [401, 403, 403, 403, 200]
#
# issue_cav_data = serializers.IssueCustomAttributesValuesSerializer(data.private_issue_cav1).data
# issue_cav_data["values"] = '{{"{}":"test-update"}}'.format(data.private_issue_ca1.id)
# issue_cav_data = json.dumps(issue_cav_data)
# results = helper_test_http_method(client, 'put', private1_url, issue_cav_data, users)
# assert results == [401, 403, 403, 403, 200]
#
# issue_cav_data = serializers.IssueCustomAttributesValuesSerializer(data.private_issue_cav2).data
# issue_cav_data["values"] = '{{"{}":"test-update"}}'.format(data.private_issue_ca2.id)
# issue_cav_data = json.dumps(issue_cav_data)
# results = helper_test_http_method(client, 'put', private2_url, issue_cav_data, users)
# assert results == [401, 403, 403, 403, 200]
#
#
#def test_issue_custom_attributes_values_delete(client, data):
# public_url = reverse('issue-custom-attributes-values-detail', args=[data.public_issue_cav.issue.id])
# private1_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav1.issue.id])
# private2_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav2.issue.id])
#
# users = [
# None,
# data.registered_user,
# data.project_member_without_perms,
# data.project_member_with_perms,
# data.project_owner
# ]
#
# results = helper_test_http_method(client, 'delete', public_url, None, users)
# assert results == [401, 403, 403, 403, 204]
# results = helper_test_http_method(client, 'delete', private1_url, None, users)
# assert results == [401, 403, 403, 403, 204]
# results = helper_test_http_method(client, 'delete', private2_url, None, users)
# assert results == [401, 403, 403, 403, 204]
#
#
#def test_issue_custom_attributes_values_list(client, data):
# url = reverse('issue-custom-attributes-values-list')
#
# response = client.json.get(url)
# assert response.status_code == 404
#
# client.login(data.registered_user)
# response = client.json.get(url)
# assert response.status_code == 404
#
# client.login(data.project_member_without_perms)
# response = client.json.get(url)
# assert response.status_code == 404
#
# client.login(data.project_member_with_perms)
# response = client.json.get(url)
# assert response.status_code == 404
#
# client.login(data.project_owner)
# response = client.json.get(url)
# assert response.status_code == 404
#
#
#def test_issue_custom_attributes_values_patch(client, data):
# public_url = reverse('issue-custom-attributes-values-detail', args=[data.public_issue_cav.issue.id])
# private1_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav1.issue.id])
# private2_url = reverse('issue-custom-attributes-values-detail', args=[data.private_issue_cav2.issue.id])
#
# users = [
# None,
# data.registered_user,
# data.project_member_without_perms,
# data.project_member_with_perms,
# data.project_owner
# ]
#
# results = helper_test_http_method(client, 'patch', public_url,
# '{{"values": {{"{}": "test-update"}}, "version": 1}}'.format(data.public_issue_ca.id), users)
# assert results == [401, 403, 403, 403, 200]
# results = helper_test_http_method(client, 'patch', private1_url,
# '{{"values": {{"{}": "test-update"}}, "version": 1}}'.format(data.private_issue_ca1.id), users)
# assert results == [401, 403, 403, 403, 200]
# results = helper_test_http_method(client, 'patch', private2_url,
# '{{"values": {{"{}": "test-update"}}, "version": 1}}'.format(data.private_issue_ca2.id), users)
# assert results == [401, 403, 403, 403, 200]

View File

@ -21,7 +21,7 @@ from taiga.base.utils import json
from .. import factories as f from .. import factories as f
import pytest import pytest
pytestmark = pytest.mark.django_db(transaction=True) pytestmark = pytest.mark.django_db
######################################################### #########################################################
@ -83,68 +83,9 @@ def test_issue_custom_attribute_duplicate_name_error_on_move_between_projects(cl
# Issue Custom Attributes Values # Issue Custom Attributes Values
######################################################### #########################################################
def test_issue_custom_attributes_values_list(client): def test_issue_custom_attributes_values_when_create_us(client):
member = f.MembershipFactory(is_owner=True)
url = reverse("issue-custom-attributes-values-list")
client.login(member.user)
response = client.json.get(url)
assert response.status_code == 404
def test_issue_custom_attributes_values_create(client):
issue = f.IssueFactory() issue = f.IssueFactory()
member = f.MembershipFactory(user=issue.project.owner, assert issue.custom_attributes_values.attributes_values == {}
project=issue.project,
is_owner=True)
custom_attr_1 = f.IssueCustomAttributeFactory(project=issue.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("issue-custom-attributes-values-list")
data = {
"issue": issue.id,
"attributes_values": {
ct1_id: "test_1",
ct2_id: "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data["attributes_values"] == data["attributes_values"]
issue = issue.__class__.objects.get(id=issue.id)
assert issue.custom_attributes_values.attributes_values == data["attributes_values"]
def test_issue_custom_attributes_values_create_with_error_invalid_key(client):
issue = f.IssueFactory()
member = f.MembershipFactory(user=issue.project.owner,
project=issue.project,
is_owner=True)
custom_attr_1 = f.IssueCustomAttributeFactory(project=issue.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
url = reverse("issue-custom-attributes-values-list")
data = {
"issue": issue.id,
"attributes_values": {
ct1_id: "test_1",
"123456": "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400
def test_issue_custom_attributes_values_update(client): def test_issue_custom_attributes_values_update(client):
@ -158,13 +99,7 @@ def test_issue_custom_attributes_values_update(client):
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.IssueCustomAttributesValuesFactory( custom_attrs_val = issue.custom_attributes_values
issue=issue,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("issue-custom-attributes-values-detail", args=[issue.id]) url = reverse("issue-custom-attributes-values-detail", args=[issue.id])
data = { data = {
@ -176,6 +111,7 @@ def test_issue_custom_attributes_values_update(client):
} }
assert issue.custom_attributes_values.attributes_values == {}
client.login(member.user) client.login(member.user)
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 200 assert response.status_code == 200
@ -193,15 +129,8 @@ def test_issue_custom_attributes_values_update_with_error_invalid_key(client):
custom_attr_1 = f.IssueCustomAttributeFactory(project=issue.project) custom_attr_1 = f.IssueCustomAttributeFactory(project=issue.project)
ct1_id = "{}".format(custom_attr_1.id) ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.IssueCustomAttributesValuesFactory( custom_attrs_val = issue.custom_attributes_values
issue=issue,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("issue-custom-attributes-values-detail", args=[issue.id]) url = reverse("issue-custom-attributes-values-detail", args=[issue.id])
data = { data = {
@ -216,8 +145,7 @@ def test_issue_custom_attributes_values_update_with_error_invalid_key(client):
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
def test_issue_custom_attributes_values_delete_issue(client):
def test_issue_custom_attributes_values_delete(client):
issue = f.IssueFactory() issue = f.IssueFactory()
member = f.MembershipFactory(user=issue.project.owner, member = f.MembershipFactory(user=issue.project.owner,
project=issue.project, project=issue.project,
@ -228,41 +156,9 @@ def test_issue_custom_attributes_values_delete(client):
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
url = reverse("issue-custom-attributes-values-detail", args=[issue.id]) custom_attrs_val = issue.custom_attributes_values
custom_attrs_val = f.IssueCustomAttributesValuesFactory(
issue=issue,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user)
response = client.json.delete(url)
assert response.status_code == 204
assert issue.__class__.objects.filter(id=issue.id).exists()
assert not custom_attrs_val.__class__.objects.filter(id=custom_attrs_val.id).exists()
def test_issue_custom_attributes_values_delete_us(client):
issue = f.IssueFactory()
member = f.MembershipFactory(user=issue.project.owner,
project=issue.project,
is_owner=True)
custom_attr_1 = f.IssueCustomAttributeFactory(project=issue.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("issues-detail", args=[issue.id]) url = reverse("issues-detail", args=[issue.id])
custom_attrs_val = f.IssueCustomAttributesValuesFactory(
issue=issue,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user) client.login(member.user)
response = client.json.delete(url) response = client.json.delete(url)
@ -286,13 +182,9 @@ def test_trigger_update_issuecustomvalues_afeter_remove_issuecustomattribute():
custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.IssueCustomAttributesValuesFactory( custom_attrs_val = issue.custom_attributes_values
issue=issue, custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"}
attributes_values= { custom_attrs_val.save()
ct1_id: "test_1",
ct2_id: "test_2"
},
)
assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct1_id in custom_attrs_val.attributes_values.keys()
assert ct2_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys()

View File

@ -21,7 +21,7 @@ from taiga.base.utils import json
from .. import factories as f from .. import factories as f
import pytest import pytest
pytestmark = pytest.mark.django_db(transaction=True) pytestmark = pytest.mark.django_db
######################################################### #########################################################
@ -83,66 +83,9 @@ def test_task_custom_attribute_duplicate_name_error_on_move_between_projects(cli
# Task Custom Attributes Values # Task Custom Attributes Values
######################################################### #########################################################
def test_task_custom_attributes_values_list(client): def test_task_custom_attributes_values_when_create_us(client):
member = f.MembershipFactory(is_owner=True)
url = reverse("task-custom-attributes-values-list")
client.login(member.user)
response = client.json.get(url)
assert response.status_code == 404
def test_task_custom_attributes_values_create(client):
task = f.TaskFactory() task = f.TaskFactory()
member = f.MembershipFactory(user=task.project.owner, assert task.custom_attributes_values.attributes_values == {}
project=task.project,
is_owner=True)
custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("task-custom-attributes-values-list")
data = {
"task": task.id,
"attributes_values": {
ct1_id: "test_1",
ct2_id: "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data["attributes_values"] == data["attributes_values"]
task = task.__class__.objects.get(id=task.id)
assert task.custom_attributes_values.attributes_values == data["attributes_values"]
def test_task_custom_attributes_values_create_with_error_invalid_key(client):
task = f.TaskFactory()
member = f.MembershipFactory(user=task.project.owner,
project=task.project,
is_owner=True)
custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
url = reverse("task-custom-attributes-values-list")
data = {
"task": task.id,
"attributes_values": {
ct1_id: "test_1",
"123456": "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400
def test_task_custom_attributes_values_update(client): def test_task_custom_attributes_values_update(client):
@ -156,13 +99,7 @@ def test_task_custom_attributes_values_update(client):
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.TaskCustomAttributesValuesFactory( custom_attrs_val = task.custom_attributes_values
task=task,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("task-custom-attributes-values-detail", args=[task.id]) url = reverse("task-custom-attributes-values-detail", args=[task.id])
data = { data = {
@ -173,6 +110,7 @@ def test_task_custom_attributes_values_update(client):
"version": custom_attrs_val.version "version": custom_attrs_val.version
} }
assert task.custom_attributes_values.attributes_values == {}
client.login(member.user) client.login(member.user)
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 200 assert response.status_code == 200
@ -190,15 +128,9 @@ def test_task_custom_attributes_values_update_with_error_invalid_key(client):
custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project) custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project)
ct1_id = "{}".format(custom_attr_1.id) ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.TaskCustomAttributesValuesFactory( custom_attrs_val = task.custom_attributes_values
task=task,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("task-custom-attributes-values-detail", args=[task.id]) url = reverse("task-custom-attributes-values-detail", args=[task.id])
data = { data = {
"attributes_values": { "attributes_values": {
@ -208,13 +140,13 @@ def test_task_custom_attributes_values_update_with_error_invalid_key(client):
"version": custom_attrs_val.version "version": custom_attrs_val.version
} }
assert task.custom_attributes_values.attributes_values == {}
client.login(member.user) client.login(member.user)
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
def test_task_custom_attributes_values_delete(client): def test_task_custom_attributes_values_delete_task(client):
task = f.TaskFactory() task = f.TaskFactory()
member = f.MembershipFactory(user=task.project.owner, member = f.MembershipFactory(user=task.project.owner,
project=task.project, project=task.project,
@ -225,41 +157,9 @@ def test_task_custom_attributes_values_delete(client):
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
url = reverse("task-custom-attributes-values-detail", args=[task.id]) custom_attrs_val = task.custom_attributes_values
custom_attrs_val = f.TaskCustomAttributesValuesFactory(
task=task,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user)
response = client.json.delete(url)
assert response.status_code == 204
assert task.__class__.objects.filter(id=task.id).exists()
assert not custom_attrs_val.__class__.objects.filter(id=custom_attrs_val.id).exists()
def test_task_custom_attributes_values_delete_us(client):
task = f.TaskFactory()
member = f.MembershipFactory(user=task.project.owner,
project=task.project,
is_owner=True)
custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("tasks-detail", args=[task.id]) url = reverse("tasks-detail", args=[task.id])
custom_attrs_val = f.TaskCustomAttributesValuesFactory(
task=task,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user) client.login(member.user)
response = client.json.delete(url) response = client.json.delete(url)
@ -272,24 +172,21 @@ def test_task_custom_attributes_values_delete_us(client):
# Test tristres triggers :-P # Test tristres triggers :-P
######################################################### #########################################################
def test_trigger_update_userstorycustomvalues_afeter_remove_userstorycustomattribute(): def test_trigger_update_taskcustomvalues_afeter_remove_taskcustomattribute():
user_story = f.UserStoryFactory() task = f.TaskFactory()
member = f.MembershipFactory(user=user_story.project.owner, member = f.MembershipFactory(user=task.project.owner,
project=user_story.project, project=task.project,
is_owner=True) is_owner=True)
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_1 = f.TaskCustomAttributeFactory(project=task.project)
ct1_id = "{}".format(custom_attr_1.id) ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( custom_attrs_val = task.custom_attributes_values
user_story=user_story,
attributes_values= { custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"}
ct1_id: "test_1", custom_attrs_val.save()
ct2_id: "test_2"
},
)
assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct1_id in custom_attrs_val.attributes_values.keys()
assert ct2_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys()

View File

@ -21,7 +21,7 @@ from taiga.base.utils import json
from .. import factories as f from .. import factories as f
import pytest import pytest
pytestmark = pytest.mark.django_db(transaction=True) pytestmark = pytest.mark.django_db
######################################################### #########################################################
@ -83,66 +83,9 @@ def test_userstory_custom_attribute_duplicate_name_error_on_move_between_project
# User Story Custom Attributes Values # User Story Custom Attributes Values
######################################################### #########################################################
def test_userstory_custom_attributes_values_list(client): def test_userstory_custom_attributes_values_when_create_us(client):
member = f.MembershipFactory(is_owner=True)
url = reverse("userstory-custom-attributes-values-list")
client.login(member.user)
response = client.json.get(url)
assert response.status_code == 404
def test_userstory_custom_attributes_values_create(client):
user_story = f.UserStoryFactory() user_story = f.UserStoryFactory()
member = f.MembershipFactory(user=user_story.project.owner, assert user_story.custom_attributes_values.attributes_values == {}
project=user_story.project,
is_owner=True)
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("userstory-custom-attributes-values-list")
data = {
"user_story": user_story.id,
"attributes_values": {
ct1_id: "test_1",
ct2_id: "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data["attributes_values"] == data["attributes_values"]
user_story = user_story.__class__.objects.get(id=user_story.id)
assert user_story.custom_attributes_values.attributes_values == data["attributes_values"]
def test_userstory_custom_attributes_values_create_with_error_invalid_key(client):
user_story = f.UserStoryFactory()
member = f.MembershipFactory(user=user_story.project.owner,
project=user_story.project,
is_owner=True)
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
url = reverse("userstory-custom-attributes-values-list")
data = {
"user_story": user_story.id,
"attributes_values": {
ct1_id: "test_1",
"123456": "test_2"
},
}
client.login(member.user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 400
def test_userstory_custom_attributes_values_update(client): def test_userstory_custom_attributes_values_update(client):
@ -156,13 +99,7 @@ def test_userstory_custom_attributes_values_update(client):
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( custom_attrs_val = user_story.custom_attributes_values
user_story=user_story,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id]) url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id])
data = { data = {
@ -173,6 +110,7 @@ def test_userstory_custom_attributes_values_update(client):
"version": custom_attrs_val.version "version": custom_attrs_val.version
} }
assert user_story.custom_attributes_values.attributes_values == {}
client.login(member.user) client.login(member.user)
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 200 assert response.status_code == 200
@ -190,15 +128,8 @@ def test_userstory_custom_attributes_values_update_with_error_invalid_key(client
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct1_id = "{}".format(custom_attr_1.id) ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( custom_attrs_val = user_story.custom_attributes_values
user_story=user_story,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id]) url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id])
data = { data = {
@ -209,65 +140,12 @@ def test_userstory_custom_attributes_values_update_with_error_invalid_key(client
"version": custom_attrs_val.version "version": custom_attrs_val.version
} }
assert user_story.custom_attributes_values.attributes_values == {}
client.login(member.user) client.login(member.user)
response = client.json.patch(url, json.dumps(data)) response = client.json.patch(url, json.dumps(data))
assert response.status_code == 400 assert response.status_code == 400
def test_userstory_custom_attributes_values_delete(client):
user_story = f.UserStoryFactory()
member = f.MembershipFactory(user=user_story.project.owner,
project=user_story.project,
is_owner=True)
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id])
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory(
user_story=user_story,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user)
response = client.json.delete(url)
assert response.status_code == 204
assert user_story.__class__.objects.filter(id=user_story.id).exists()
assert not custom_attrs_val.__class__.objects.filter(id=custom_attrs_val.id).exists()
def test_userstory_custom_attributes_values_delete_us(client):
user_story = f.UserStoryFactory()
member = f.MembershipFactory(user=user_story.project.owner,
project=user_story.project,
is_owner=True)
custom_attr_1 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct1_id = "{}".format(custom_attr_1.id)
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id)
url = reverse("userstories-detail", args=[user_story.id])
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory(
user_story=user_story,
attributes_values= {
ct1_id: "test_1",
ct2_id: "test_2"
},
)
client.login(member.user)
response = client.json.delete(url)
assert response.status_code == 204
assert not user_story.__class__.objects.filter(id=user_story.id).exists()
assert not custom_attrs_val.__class__.objects.filter(id=custom_attrs_val.id).exists()
######################################################### #########################################################
# Test tristres triggers :-P # Test tristres triggers :-P
######################################################### #########################################################
@ -283,13 +161,10 @@ def test_trigger_update_userstorycustomvalues_afeter_remove_userstorycustomattri
custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project)
ct2_id = "{}".format(custom_attr_2.id) ct2_id = "{}".format(custom_attr_2.id)
custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( custom_attrs_val = user_story.custom_attributes_values
user_story=user_story,
attributes_values= { custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"}
ct1_id: "test_1", custom_attrs_val.save()
ct2_id: "test_2"
},
)
assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct1_id in custom_attrs_val.attributes_values.keys()
assert ct2_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys()