diff --git a/taiga/base/api/__init__.py b/taiga/base/api/__init__.py index 973f17ef..845821b2 100644 --- a/taiga/base/api/__init__.py +++ b/taiga/base/api/__init__.py @@ -19,10 +19,12 @@ from .viewsets import ModelListViewSet from .viewsets import ModelCrudViewSet +from .viewsets import ModelUpdateRetrieveViewSet from .viewsets import GenericViewSet from .viewsets import ReadOnlyListViewSet __all__ = ["ModelCrudViewSet", "ModelListViewSet", + "ModelUpdateRetrieveViewSet", "GenericViewSet", "ReadOnlyListViewSet"] diff --git a/taiga/base/api/viewsets.py b/taiga/base/api/viewsets.py index b2fbdd50..cad36dcd 100644 --- a/taiga/base/api/viewsets.py +++ b/taiga/base/api/viewsets.py @@ -168,3 +168,8 @@ class ModelListViewSet(pagination.HeadersPaginationMixin, mixins.ListModelMixin, GenericViewSet): pass + +class ModelUpdateRetrieveViewSet(mixins.UpdateModelMixin, + mixins.RetrieveModelMixin, + GenericViewSet): + pass diff --git a/taiga/export_import/serializers.py b/taiga/export_import/serializers.py index 0af1ae52..7b27c427 100644 --- a/taiga/export_import/serializers.py +++ b/taiga/export_import/serializers.py @@ -22,6 +22,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.files.base import ContentFile from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ValidationError +from django.core.exceptions import ObjectDoesNotExist from rest_framework import serializers diff --git a/taiga/export_import/service.py b/taiga/export_import/service.py index 9c6b52c4..a5c9e22b 100644 --- a/taiga/export_import/service.py +++ b/taiga/export_import/service.py @@ -20,6 +20,7 @@ from unidecode import unidecode from django.template.defaultfilters import slugify 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.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)) return result + def store_custom_attributes_values(obj, data_values, obj_field, serializer_class): data = { obj_field: obj.id, "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(): serializer.save() return serializer diff --git a/taiga/projects/custom_attributes/api.py b/taiga/projects/custom_attributes/api.py index 7e4033ab..c1edfe33 100644 --- a/taiga/projects/custom_attributes/api.py +++ b/taiga/projects/custom_attributes/api.py @@ -17,7 +17,7 @@ from django.utils.translation import ugettext_lazy as _ 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 filters from taiga.base import response @@ -73,16 +73,7 @@ class IssueCustomAttributeViewSet(ModelCrudViewSet, BulkUpdateOrderMixin): # Custom Attributes Values ViewSets ####################################################### -class BaseCustomAttributesValuesViewSet(OCCResourceMixin, HistoryResourceMixin, ModelViewSet): - 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) - +class BaseCustomAttributesValuesViewSet(OCCResourceMixin, HistoryResourceMixin, ModelUpdateRetrieveViewSet): def get_object_for_snapshot(self, obj): return getattr(obj, self.content_object) diff --git a/taiga/projects/custom_attributes/migrations/0002_issuecustomattributesvalues_taskcustomattributesvalues_userstorycustomattributesvalues.py b/taiga/projects/custom_attributes/migrations/0002_issuecustomattributesvalues_taskcustomattributesvalues_userstorycustomattributesvalues.py index dd9ed428..8c1848db 100644 --- a/taiga/projects/custom_attributes/migrations/0002_issuecustomattributesvalues_taskcustomattributesvalues_userstorycustomattributesvalues.py +++ b/taiga/projects/custom_attributes/migrations/0002_issuecustomattributesvalues_taskcustomattributesvalues_userstorycustomattributesvalues.py @@ -9,8 +9,8 @@ class Migration(migrations.Migration): dependencies = [ ('tasks', '0005_auto_20150114_0954'), - ('userstories', '0009_remove_userstory_is_archived'), ('issues', '0004_auto_20150114_0954'), + ('userstories', '0009_remove_userstory_is_archived'), ('custom_attributes', '0001_initial'), ] @@ -18,14 +18,14 @@ class Migration(migrations.Migration): migrations.CreateModel( name='IssueCustomAttributesValues', 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')), - ('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')), + ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')), + ('issue', models.OneToOneField(verbose_name='issue', to='issues.Issue', related_name='custom_attributes_values')), ], options={ - 'ordering': ['id'], 'verbose_name_plural': 'issue custom attributes values', + 'ordering': ['id'], 'verbose_name': 'issue ustom attributes values', 'abstract': False, }, @@ -34,14 +34,14 @@ class Migration(migrations.Migration): migrations.CreateModel( name='TaskCustomAttributesValues', 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')), - ('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')), + ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')), + ('task', models.OneToOneField(verbose_name='task', to='tasks.Task', related_name='custom_attributes_values')), ], options={ - 'ordering': ['id'], 'verbose_name_plural': 'task custom attributes values', + 'ordering': ['id'], 'verbose_name': 'task ustom attributes values', 'abstract': False, }, @@ -50,14 +50,14 @@ class Migration(migrations.Migration): migrations.CreateModel( name='UserStoryCustomAttributesValues', 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')), - ('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')), + ('attributes_values', django_pgjson.fields.JsonField(default={}, verbose_name='attributes_values')), + ('user_story', models.OneToOneField(verbose_name='user story', to='userstories.UserStory', related_name='custom_attributes_values')), ], options={ - 'ordering': ['id'], 'verbose_name_plural': 'user story custom attributes values', + 'ordering': ['id'], 'verbose_name': 'user story ustom attributes values', 'abstract': False, }, diff --git a/taiga/projects/custom_attributes/migrations/0003_triggers_on_delete_customattribute.py b/taiga/projects/custom_attributes/migrations/0003_triggers_on_delete_customattribute.py index fc237167..8a984a63 100644 --- a/taiga/projects/custom_attributes/migrations/0003_triggers_on_delete_customattribute.py +++ b/taiga/projects/custom_attributes/migrations/0003_triggers_on_delete_customattribute.py @@ -25,7 +25,8 @@ class Migration(migrations.Migration): WHERE "key" <> ALL ("keys_to_delete")), '{}')::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 @@ -50,39 +51,46 @@ class Migration(migrations.Migration): 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 migrations.RunSQL( """ - CREATE TRIGGER "update_userstorycustomvalues_afeter_remove_userstorycustomattribute" + CREATE TRIGGER "update_userstorycustomvalues_after_remove_userstorycustomattribute" BEFORE DELETE ON custom_attributes_userstorycustomattribute FOR EACH ROW 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 migrations.RunSQL( """ - CREATE TRIGGER "update_taskcustomvalues_afeter_remove_taskcustomattribute" + CREATE TRIGGER "update_taskcustomvalues_after_remove_taskcustomattribute" BEFORE DELETE ON custom_attributes_taskcustomattribute FOR EACH ROW 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 migrations.RunSQL( """ - CREATE TRIGGER "update_issuecustomvalues_afeter_remove_issuecustomattribute" + CREATE TRIGGER "update_issuecustomvalues_after_remove_issuecustomattribute" BEFORE DELETE ON custom_attributes_issuecustomattribute FOR EACH ROW 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;""" ) ] diff --git a/taiga/projects/custom_attributes/migrations/0004_create_empty_customattributesvalues_for_existen_object.py b/taiga/projects/custom_attributes/migrations/0004_create_empty_customattributesvalues_for_existen_object.py new file mode 100644 index 00000000..9d807ad4 --- /dev/null +++ b/taiga/projects/custom_attributes/migrations/0004_create_empty_customattributesvalues_for_existen_object.py @@ -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), + ] diff --git a/taiga/projects/custom_attributes/permissions.py b/taiga/projects/custom_attributes/permissions.py index 617e90b0..160d340e 100644 --- a/taiga/projects/custom_attributes/permissions.py +++ b/taiga/projects/custom_attributes/permissions.py @@ -66,24 +66,18 @@ class UserStoryCustomAttributesValuesPermission(TaigaResourcePermission): enought_perms = IsProjectOwner() | IsSuperUser() global_perms = None retrieve_perms = HasProjectPerm('view_us') - create_perms = HasProjectPerm('add_us') update_perms = HasProjectPerm('modify_us') - destroy_perms = HasProjectPerm('delete_us') class TaskCustomAttributesValuesPermission(TaigaResourcePermission): enought_perms = IsProjectOwner() | IsSuperUser() global_perms = None retrieve_perms = HasProjectPerm('view_tasks') - create_perms = HasProjectPerm('add_task') update_perms = HasProjectPerm('modify_task') - destroy_perms = HasProjectPerm('delete_task') class IssueCustomAttributesValuesPermission(TaigaResourcePermission): enought_perms = IsProjectOwner() | IsSuperUser() global_perms = None retrieve_perms = HasProjectPerm('view_issues') - create_perms = HasProjectPerm('add_issue') update_perms = HasProjectPerm('modify_issue') - destroy_perms = HasProjectPerm('delete_issue') diff --git a/taiga/projects/custom_attributes/signals.py b/taiga/projects/custom_attributes/signals.py new file mode 100644 index 00000000..fa90bb10 --- /dev/null +++ b/taiga/projects/custom_attributes/signals.py @@ -0,0 +1,35 @@ +# Copyright (C) 2015 Andrey Antukh +# Copyright (C) 2015 Jesús Espino +# Copyright (C) 2015 David Barragán +# 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 . + +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":{}}) diff --git a/taiga/projects/issues/apps.py b/taiga/projects/issues/apps.py index 4b8714ff..3972ef48 100644 --- a/taiga/projects/issues/apps.py +++ b/taiga/projects/issues/apps.py @@ -19,6 +19,7 @@ from django.apps import apps from django.db.models import signals from taiga.projects import signals as generic_handlers +from taiga.projects.custom_attributes import signals as custom_attributes_handlers from . import signals as handlers @@ -39,3 +40,8 @@ class IssuesAppConfig(AppConfig): sender=apps.get_model("issues", "Issue")) signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, 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") diff --git a/taiga/projects/management/commands/sample_data.py b/taiga/projects/management/commands/sample_data.py index 1e5331a0..b8d86b75 100644 --- a/taiga/projects/management/commands/sample_data.py +++ b/taiga/projects/management/commands/sample_data.py @@ -270,11 +270,13 @@ class Command(BaseCommand): project=project)), 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 custom_attributes_values: - IssueCustomAttributesValues.objects.create(issue=bug, - attributes_values=custom_attributes_values) + bug.custom_attributes_values.attributes_values = custom_attributes_values + bug.custom_attributes_values.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(bug, i+1) @@ -319,11 +321,11 @@ class Command(BaseCommand): 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 custom_attributes_values: - TaskCustomAttributesValues.objects.create(task=task, - attributes_values=custom_attributes_values) + task.custom_attributes_values.attributes_values = custom_attributes_values + task.custom_attributes_values.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(task, i+1) @@ -362,11 +364,13 @@ class Command(BaseCommand): 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 custom_attributes_values: - UserStoryCustomAttributesValues.objects.create(user_story=us, - attributes_values=custom_attributes_values) + us.custom_attributes_values.attributes_values = custom_attributes_values + us.custom_attributes_values.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): diff --git a/taiga/projects/tasks/apps.py b/taiga/projects/tasks/apps.py index 752560de..a6597339 100644 --- a/taiga/projects/tasks/apps.py +++ b/taiga/projects/tasks/apps.py @@ -19,6 +19,7 @@ from django.apps import apps from django.db.models import signals from taiga.projects import signals as generic_handlers +from taiga.projects.custom_attributes import signals as custom_attributes_handlers from . import signals as handlers @@ -44,3 +45,8 @@ class TasksAppConfig(AppConfig): sender=apps.get_model("tasks", "Task")) signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, 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") diff --git a/taiga/projects/userstories/apps.py b/taiga/projects/userstories/apps.py index 299f1cfc..f6b1bb77 100644 --- a/taiga/projects/userstories/apps.py +++ b/taiga/projects/userstories/apps.py @@ -19,6 +19,7 @@ from django.apps import apps from django.db.models import signals from taiga.projects import signals as generic_handlers +from taiga.projects.custom_attributes import signals as custom_attributes_handlers from . import signals as handlers @@ -52,3 +53,8 @@ class UserStoriesAppConfig(AppConfig): sender=apps.get_model("userstories", "UserStory")) signals.post_delete.connect(generic_handlers.update_project_tags_when_delete_taggable_item, 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") diff --git a/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py b/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py index 2af987ad..694bfc36 100644 --- a/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py +++ b/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py @@ -95,23 +95,6 @@ def data(): m.private_issue_ca1 = f.IssueCustomAttributeFactory(project=m.private_project1) 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 @@ -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) 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] diff --git a/tests/integration/test_custom_attributes_issues.py b/tests/integration/test_custom_attributes_issues.py index 505fae5c..b33b7e71 100644 --- a/tests/integration/test_custom_attributes_issues.py +++ b/tests/integration/test_custom_attributes_issues.py @@ -21,7 +21,7 @@ from taiga.base.utils import json from .. import factories as f 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 ######################################################### -def test_issue_custom_attributes_values_list(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): +def test_issue_custom_attributes_values_when_create_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("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 + assert issue.custom_attributes_values.attributes_values == {} 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) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.IssueCustomAttributesValuesFactory( - issue=issue, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = issue.custom_attributes_values url = reverse("issue-custom-attributes-values-detail", args=[issue.id]) data = { @@ -176,6 +111,7 @@ def test_issue_custom_attributes_values_update(client): } + assert issue.custom_attributes_values.attributes_values == {} client.login(member.user) response = client.json.patch(url, json.dumps(data)) 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) ct1_id = "{}".format(custom_attr_1.id) custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) - ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.IssueCustomAttributesValuesFactory( - issue=issue, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = issue.custom_attributes_values url = reverse("issue-custom-attributes-values-detail", args=[issue.id]) 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)) assert response.status_code == 400 - -def test_issue_custom_attributes_values_delete(client): +def test_issue_custom_attributes_values_delete_issue(client): issue = f.IssueFactory() member = f.MembershipFactory(user=issue.project.owner, project=issue.project, @@ -228,41 +156,9 @@ def test_issue_custom_attributes_values_delete(client): custom_attr_2 = f.IssueCustomAttributeFactory(project=issue.project) ct2_id = "{}".format(custom_attr_2.id) - url = reverse("issue-custom-attributes-values-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) - 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) + custom_attrs_val = issue.custom_attributes_values 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) 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) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.IssueCustomAttributesValuesFactory( - issue=issue, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = issue.custom_attributes_values + custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"} + custom_attrs_val.save() assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys() diff --git a/tests/integration/test_custom_attributes_tasks.py b/tests/integration/test_custom_attributes_tasks.py index 1a11bc17..ecb909de 100644 --- a/tests/integration/test_custom_attributes_tasks.py +++ b/tests/integration/test_custom_attributes_tasks.py @@ -21,7 +21,7 @@ from taiga.base.utils import json from .. import factories as f 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 ######################################################### -def test_task_custom_attributes_values_list(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): +def test_task_custom_attributes_values_when_create_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("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 + assert task.custom_attributes_values.attributes_values == {} 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) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.TaskCustomAttributesValuesFactory( - task=task, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = task.custom_attributes_values url = reverse("task-custom-attributes-values-detail", args=[task.id]) data = { @@ -173,6 +110,7 @@ def test_task_custom_attributes_values_update(client): "version": custom_attrs_val.version } + assert task.custom_attributes_values.attributes_values == {} client.login(member.user) response = client.json.patch(url, json.dumps(data)) 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) ct1_id = "{}".format(custom_attr_1.id) custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) - ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.TaskCustomAttributesValuesFactory( - task=task, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = task.custom_attributes_values + url = reverse("task-custom-attributes-values-detail", args=[task.id]) data = { "attributes_values": { @@ -208,13 +140,13 @@ def test_task_custom_attributes_values_update_with_error_invalid_key(client): "version": custom_attrs_val.version } - + assert task.custom_attributes_values.attributes_values == {} client.login(member.user) response = client.json.patch(url, json.dumps(data)) 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() member = f.MembershipFactory(user=task.project.owner, project=task.project, @@ -225,41 +157,9 @@ def test_task_custom_attributes_values_delete(client): custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) ct2_id = "{}".format(custom_attr_2.id) - url = reverse("task-custom-attributes-values-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) - 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) + custom_attrs_val = task.custom_attributes_values 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) response = client.json.delete(url) @@ -272,24 +172,21 @@ def test_task_custom_attributes_values_delete_us(client): # Test tristres triggers :-P ######################################################### -def test_trigger_update_userstorycustomvalues_afeter_remove_userstorycustomattribute(): - user_story = f.UserStoryFactory() - member = f.MembershipFactory(user=user_story.project.owner, - project=user_story.project, +def test_trigger_update_taskcustomvalues_afeter_remove_taskcustomattribute(): + task = f.TaskFactory() + member = f.MembershipFactory(user=task.project.owner, + project=task.project, 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) - custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) + custom_attr_2 = f.TaskCustomAttributeFactory(project=task.project) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( - user_story=user_story, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = task.custom_attributes_values + + custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"} + custom_attrs_val.save() assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys() diff --git a/tests/integration/test_custom_attributes_user_stories.py b/tests/integration/test_custom_attributes_user_stories.py index ab1fb5a3..362f5497 100644 --- a/tests/integration/test_custom_attributes_user_stories.py +++ b/tests/integration/test_custom_attributes_user_stories.py @@ -21,7 +21,7 @@ from taiga.base.utils import json from .. import factories as f 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 ######################################################### -def test_userstory_custom_attributes_values_list(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): +def test_userstory_custom_attributes_values_when_create_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("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 + assert user_story.custom_attributes_values.attributes_values == {} 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) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( - user_story=user_story, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = user_story.custom_attributes_values url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id]) data = { @@ -173,6 +110,7 @@ def test_userstory_custom_attributes_values_update(client): "version": custom_attrs_val.version } + assert user_story.custom_attributes_values.attributes_values == {} client.login(member.user) response = client.json.patch(url, json.dumps(data)) 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) ct1_id = "{}".format(custom_attr_1.id) custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) - ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( - user_story=user_story, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = user_story.custom_attributes_values url = reverse("userstory-custom-attributes-values-detail", args=[user_story.id]) data = { @@ -209,65 +140,12 @@ def test_userstory_custom_attributes_values_update_with_error_invalid_key(client "version": custom_attrs_val.version } + assert user_story.custom_attributes_values.attributes_values == {} client.login(member.user) response = client.json.patch(url, json.dumps(data)) 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 ######################################################### @@ -283,13 +161,10 @@ def test_trigger_update_userstorycustomvalues_afeter_remove_userstorycustomattri custom_attr_2 = f.UserStoryCustomAttributeFactory(project=user_story.project) ct2_id = "{}".format(custom_attr_2.id) - custom_attrs_val = f.UserStoryCustomAttributesValuesFactory( - user_story=user_story, - attributes_values= { - ct1_id: "test_1", - ct2_id: "test_2" - }, - ) + custom_attrs_val = user_story.custom_attributes_values + + custom_attrs_val.attributes_values = {ct1_id: "test_1", ct2_id: "test_2"} + custom_attrs_val.save() assert ct1_id in custom_attrs_val.attributes_values.keys() assert ct2_id in custom_attrs_val.attributes_values.keys()