diff --git a/settings/common.py b/settings/common.py index 3687486b..e013b3f7 100644 --- a/settings/common.py +++ b/settings/common.py @@ -522,6 +522,7 @@ WEBHOOKS_ENABLED = False FRONT_SITEMAP_ENABLED = False FRONT_SITEMAP_CACHE_TIMEOUT = 24*60*60 # In second +EXTRA_BLOCKING_CODES = [] from .sr import * diff --git a/taiga/base/api/mixins.py b/taiga/base/api/mixins.py index 27c05675..e07635ed 100644 --- a/taiga/base/api/mixins.py +++ b/taiga/base/api/mixins.py @@ -53,6 +53,8 @@ from taiga.base import response from .settings import api_settings from .utils import get_object_or_404 +from .. import exceptions as exc + def _get_validation_exclusions(obj, pk=None, slug_field=None, lookup_field=None): """ @@ -237,3 +239,32 @@ class DestroyModelMixin: obj.delete() self.post_delete(obj) return response.NoContent() + + +class BlockeableModelMixin: + def is_blocked(self, obj): + raise NotImplementedError("is_blocked must be overridden") + + def pre_conditions_blocked(self, obj): + #Raises permission exception + if obj is not None and self.is_blocked(obj): + raise exc.Blocked(_("Blocked element")) + + +class BlockeableSaveMixin(BlockeableModelMixin): + def pre_conditions_on_save(self, obj): + # Called on create and update calls + self.pre_conditions_blocked(obj) + super().pre_conditions_on_save(obj) + + +class BlockeableDeleteMixin(): + def pre_conditions_on_delete(self, obj): + # Called on destroy call + self.pre_conditions_blocked(obj) + super().pre_conditions_on_delete(obj) + + +class BlockedByProjectMixin(BlockeableSaveMixin, BlockeableDeleteMixin): + def is_blocked(self, obj): + return obj.project is not None and obj.project.blocked_code is not None diff --git a/taiga/base/api/viewsets.py b/taiga/base/api/viewsets.py index 9c5f1e5d..af2d2789 100644 --- a/taiga/base/api/viewsets.py +++ b/taiga/base/api/viewsets.py @@ -187,11 +187,13 @@ class ModelListViewSet(mixins.RetrieveModelMixin, GenericViewSet): pass + class ModelUpdateRetrieveViewSet(mixins.UpdateModelMixin, mixins.RetrieveModelMixin, GenericViewSet): pass + class ModelRetrieveViewSet(mixins.RetrieveModelMixin, GenericViewSet): pass diff --git a/taiga/base/exceptions.py b/taiga/base/exceptions.py index 3e7c2104..f81c1424 100644 --- a/taiga/base/exceptions.py +++ b/taiga/base/exceptions.py @@ -201,6 +201,11 @@ class NotAuthenticated(NotAuthenticated): pass +class Blocked(APIException): + status_code = status.HTTP_451_BLOCKED + default_detail = _("Blocked element") + + def format_exception(exc): if isinstance(exc.detail, (dict, list, tuple,)): detail = exc.detail diff --git a/taiga/base/status.py b/taiga/base/status.py index 08386721..003c771b 100644 --- a/taiga/base/status.py +++ b/taiga/base/status.py @@ -104,6 +104,7 @@ HTTP_417_EXPECTATION_FAILED = 417 HTTP_428_PRECONDITION_REQUIRED = 428 HTTP_429_TOO_MANY_REQUESTS = 429 HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 +HTTP_451_BLOCKED = 451 HTTP_500_INTERNAL_SERVER_ERROR = 500 HTTP_501_NOT_IMPLEMENTED = 501 HTTP_502_BAD_GATEWAY = 502 diff --git a/taiga/projects/api.py b/taiga/projects/api.py index 2ed19f97..2346ae29 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -33,6 +33,7 @@ from taiga.base import exceptions as exc from taiga.base.decorators import list_route from taiga.base.decorators import detail_route from taiga.base.api import ModelCrudViewSet, ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin, BlockeableSaveMixin, BlockeableDeleteMixin from taiga.base.api.permissions import AllowAnyPermission from taiga.base.api.utils import get_object_or_404 from taiga.base.utils.slug import slugify_uniquely @@ -61,7 +62,9 @@ from . import services ###################################################### ## Project ###################################################### -class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet): +class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, + BlockeableSaveMixin, BlockeableDeleteMixin, ModelCrudViewSet): + queryset = models.Project.objects.all() serializer_class = serializers.ProjectDetailSerializer admin_serializer_class = serializers.ProjectDetailAdminSerializer @@ -87,6 +90,9 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) "total_activity_last_month", "total_activity_last_year") + def is_blocked(self, obj): + return obj.blocked_code is not None + def _get_order_by_field_name(self): order_by_query_param = project_filters.CanViewProjectObjFilterBackend.order_by_query_param order_by = self.request.QUERY_PARAMS.get(order_by_query_param, None) @@ -157,6 +163,8 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) except Exception: raise exc.WrongArguments(_("Invalid image format")) + self.pre_conditions_on_save(self.object) + self.object.logo = logo self.object.save(update_fields=["logo"]) @@ -170,7 +178,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) """ self.object = get_object_or_404(self.get_queryset(), **kwargs) self.check_permissions(request, "remove_logo", self.object) - + self.pre_conditions_on_save(self.object) self.object.logo = None self.object.save(update_fields=["logo"]) @@ -181,6 +189,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) def watch(self, request, pk=None): project = self.get_object() self.check_permissions(request, "watch", project) + self.pre_conditions_on_save(project) notify_level = request.DATA.get("notify_level", NotifyLevel.involved) project.add_watcher(self.request.user, notify_level=notify_level) return response.Ok() @@ -189,6 +198,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) def unwatch(self, request, pk=None): project = self.get_object() self.check_permissions(request, "unwatch", project) + self.pre_conditions_on_save(project) user = self.request.user project.remove_watcher(user) return response.Ok() @@ -206,77 +216,6 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) services.update_projects_order_in_bulk(data, "user_order", request.user) return response.NoContent(data=None) - @list_route(methods=["GET"]) - def by_slug(self, request): - slug = request.QUERY_PARAMS.get("slug", None) - project = get_object_or_404(models.Project, slug=slug) - return self.retrieve(request, pk=project.pk) - - @detail_route(methods=["GET", "PATCH"]) - def modules(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, 'modules', project) - modules_config = services.get_modules_config(project) - - if request.method == "GET": - return response.Ok(modules_config.config) - - else: - modules_config.config.update(request.DATA) - modules_config.save() - return response.NoContent() - - @detail_route(methods=["GET"]) - def stats(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "stats", project) - return response.Ok(services.get_stats_for_project(project)) - - def _regenerate_csv_uuid(self, project, field): - uuid_value = uuid.uuid4().hex - setattr(project, field, uuid_value) - project.save() - return uuid_value - - @detail_route(methods=["POST"]) - def regenerate_userstories_csv_uuid(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "regenerate_userstories_csv_uuid", project) - data = {"uuid": self._regenerate_csv_uuid(project, "userstories_csv_uuid")} - return response.Ok(data) - - @detail_route(methods=["POST"]) - def regenerate_issues_csv_uuid(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "regenerate_issues_csv_uuid", project) - data = {"uuid": self._regenerate_csv_uuid(project, "issues_csv_uuid")} - return response.Ok(data) - - @detail_route(methods=["POST"]) - def regenerate_tasks_csv_uuid(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "regenerate_tasks_csv_uuid", project) - data = {"uuid": self._regenerate_csv_uuid(project, "tasks_csv_uuid")} - return response.Ok(data) - - @detail_route(methods=["GET"]) - def member_stats(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "member_stats", project) - return response.Ok(services.get_member_stats_for_project(project)) - - @detail_route(methods=["GET"]) - def issues_stats(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "issues_stats", project) - return response.Ok(services.get_stats_for_project_issues(project)) - - @detail_route(methods=["GET"]) - def tags_colors(self, request, pk=None): - project = self.get_object() - self.check_permissions(request, "tags_colors", project) - return response.Ok(dict(project.tags_colors)) - @detail_route(methods=["POST"]) def create_template(self, request, **kwargs): template_name = request.DATA.get('template_name', None) @@ -304,13 +243,89 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) template.save() return response.Created(serializers.ProjectTemplateSerializer(template).data) - @detail_route(methods=['post']) + @detail_route(methods=['POST']) def leave(self, request, pk=None): project = self.get_object() self.check_permissions(request, 'leave', project) + self.pre_conditions_on_save(project) services.remove_user_from_project(request.user, project) return response.Ok() + @detail_route(methods=["POST"]) + def regenerate_userstories_csv_uuid(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "regenerate_userstories_csv_uuid", project) + self.pre_conditions_on_save(project) + data = {"uuid": self._regenerate_csv_uuid(project, "userstories_csv_uuid")} + return response.Ok(data) + + @detail_route(methods=["POST"]) + def regenerate_issues_csv_uuid(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "regenerate_issues_csv_uuid", project) + self.pre_conditions_on_save(project) + data = {"uuid": self._regenerate_csv_uuid(project, "issues_csv_uuid")} + return response.Ok(data) + + @detail_route(methods=["POST"]) + def regenerate_tasks_csv_uuid(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "regenerate_tasks_csv_uuid", project) + self.pre_conditions_on_save(project) + data = {"uuid": self._regenerate_csv_uuid(project, "tasks_csv_uuid")} + return response.Ok(data) + + @list_route(methods=["GET"]) + def by_slug(self, request): + slug = request.QUERY_PARAMS.get("slug", None) + project = get_object_or_404(models.Project, slug=slug) + return self.retrieve(request, pk=project.pk) + + @detail_route(methods=["GET", "PATCH"]) + def modules(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, 'modules', project) + modules_config = services.get_modules_config(project) + + if request.method == "GET": + return response.Ok(modules_config.config) + + else: + self.pre_conditions_on_save(project) + modules_config.config.update(request.DATA) + modules_config.save() + return response.NoContent() + + @detail_route(methods=["GET"]) + def stats(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "stats", project) + return response.Ok(services.get_stats_for_project(project)) + + def _regenerate_csv_uuid(self, project, field): + uuid_value = uuid.uuid4().hex + setattr(project, field, uuid_value) + project.save() + return uuid_value + + @detail_route(methods=["GET"]) + def member_stats(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "member_stats", project) + return response.Ok(services.get_member_stats_for_project(project)) + + @detail_route(methods=["GET"]) + def issues_stats(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "issues_stats", project) + return response.Ok(services.get_stats_for_project_issues(project)) + + @detail_route(methods=["GET"]) + def tags_colors(self, request, pk=None): + project = self.get_object() + self.check_permissions(request, "tags_colors", project) + return response.Ok(dict(project.tags_colors)) + def _set_base_permissions(self, obj): update_permissions = False if not obj.id: @@ -364,7 +379,9 @@ class ProjectWatchersViewSet(WatchersViewSetMixin, ModelListViewSet): ## Custom values for selectors ###################################################### -class PointsViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class PointsViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): + model = models.Points serializer_class = serializers.PointsSerializer permission_classes = (permissions.PointsPermission,) @@ -378,7 +395,9 @@ class PointsViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): move_on_destroy_project_default_field = "default_points" -class UserStoryStatusViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class UserStoryStatusViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): + model = models.UserStoryStatus serializer_class = serializers.UserStoryStatusSerializer permission_classes = (permissions.UserStoryStatusPermission,) @@ -392,7 +411,9 @@ class UserStoryStatusViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrd move_on_destroy_project_default_field = "default_us_status" -class TaskStatusViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class TaskStatusViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): + model = models.TaskStatus serializer_class = serializers.TaskStatusSerializer permission_classes = (permissions.TaskStatusPermission,) @@ -406,7 +427,9 @@ class TaskStatusViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMix move_on_destroy_project_default_field = "default_task_status" -class SeverityViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class SeverityViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): + model = models.Severity serializer_class = serializers.SeveritySerializer permission_classes = (permissions.SeverityPermission,) @@ -420,7 +443,8 @@ class SeverityViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin move_on_destroy_project_default_field = "default_severity" -class PriorityViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class PriorityViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): model = models.Priority serializer_class = serializers.PrioritySerializer permission_classes = (permissions.PriorityPermission,) @@ -434,7 +458,8 @@ class PriorityViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin move_on_destroy_project_default_field = "default_priority" -class IssueTypeViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class IssueTypeViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): model = models.IssueType serializer_class = serializers.IssueTypeSerializer permission_classes = (permissions.IssueTypePermission,) @@ -448,7 +473,8 @@ class IssueTypeViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixi move_on_destroy_project_default_field = "default_issue_type" -class IssueStatusViewSet(MoveOnDestroyMixin, ModelCrudViewSet, BulkUpdateOrderMixin): +class IssueStatusViewSet(MoveOnDestroyMixin, BlockedByProjectMixin, + ModelCrudViewSet, BulkUpdateOrderMixin): model = models.IssueStatus serializer_class = serializers.IssueStatusSerializer permission_classes = (permissions.IssueStatusPermission,) @@ -479,7 +505,7 @@ class ProjectTemplateViewSet(ModelCrudViewSet): ## Members & Invitations ###################################################### -class MembershipViewSet(ModelCrudViewSet): +class MembershipViewSet(BlockedByProjectMixin, ModelCrudViewSet): model = models.Membership admin_serializer_class = serializers.MembershipAdminSerializer serializer_class = serializers.MembershipSerializer @@ -517,6 +543,8 @@ class MembershipViewSet(ModelCrudViewSet): project = models.Project.objects.get(id=data["project_id"]) invitation_extra_text = data.get("invitation_extra_text", None) self.check_permissions(request, 'bulk_create', project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) # TODO: this should be moved to main exception handler instead # of handling explicit exception catchin here. @@ -538,6 +566,7 @@ class MembershipViewSet(ModelCrudViewSet): invitation = self.get_object() self.check_permissions(request, 'resend_invitation', invitation.project) + self.pre_conditions_on_save(invitation) services.send_invitation(invitation=invitation) return response.NoContent() diff --git a/taiga/projects/attachments/api.py b/taiga/projects/attachments/api.py index 65ad55b3..481021ed 100644 --- a/taiga/projects/attachments/api.py +++ b/taiga/projects/attachments/api.py @@ -25,6 +25,7 @@ from django.contrib.contenttypes.models import ContentType from taiga.base import filters from taiga.base import exceptions as exc from taiga.base.api import ModelCrudViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api.utils import get_object_or_404 from taiga.projects.notifications.mixins import WatchedResourceMixin @@ -35,7 +36,9 @@ from . import serializers from . import models -class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCrudViewSet): +class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin, + BlockedByProjectMixin, ModelCrudViewSet): + model = models.Attachment serializer_class = serializers.AttachmentSerializer filter_fields = ["project", "object_id"] diff --git a/taiga/projects/choices.py b/taiga/projects/choices.py index 2d929ec7..5a7d8765 100644 --- a/taiga/projects/choices.py +++ b/taiga/projects/choices.py @@ -24,3 +24,10 @@ VIDEOCONFERENCES_CHOICES = ( ("custom", _("Custom")), ("talky", _("Talky")), ) + +BLOCKED_BY_STAFF = "blocked-by-staff" +BLOCKED_BY_OWNER_LEAVING = "blocked-by-owner-leaving" +BLOCKING_CODES = [ + (BLOCKED_BY_STAFF, _("This project was blocked by staff")), + (BLOCKED_BY_OWNER_LEAVING, _("This project was because the owner left")) +] diff --git a/taiga/projects/custom_attributes/api.py b/taiga/projects/custom_attributes/api.py index 3224d617..a11d6e31 100644 --- a/taiga/projects/custom_attributes/api.py +++ b/taiga/projects/custom_attributes/api.py @@ -19,6 +19,7 @@ from django.utils.translation import ugettext_lazy as _ from taiga.base.api import ModelCrudViewSet from taiga.base.api import ModelUpdateRetrieveViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base import exceptions as exc from taiga.base import filters from taiga.base import response @@ -38,7 +39,7 @@ from . import services # Custom Attribute ViewSets ####################################################### -class UserStoryCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): +class UserStoryCustomAttributeViewSet(BulkUpdateOrderMixin, BlockedByProjectMixin, ModelCrudViewSet): model = models.UserStoryCustomAttribute serializer_class = serializers.UserStoryCustomAttributeSerializer permission_classes = (permissions.UserStoryCustomAttributePermission,) @@ -49,7 +50,7 @@ class UserStoryCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): bulk_update_order_action = services.bulk_update_userstory_custom_attribute_order -class TaskCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): +class TaskCustomAttributeViewSet(BulkUpdateOrderMixin, BlockedByProjectMixin, ModelCrudViewSet): model = models.TaskCustomAttribute serializer_class = serializers.TaskCustomAttributeSerializer permission_classes = (permissions.TaskCustomAttributePermission,) @@ -60,7 +61,7 @@ class TaskCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): bulk_update_order_action = services.bulk_update_task_custom_attribute_order -class IssueCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): +class IssueCustomAttributeViewSet(BulkUpdateOrderMixin, BlockedByProjectMixin, ModelCrudViewSet): model = models.IssueCustomAttribute serializer_class = serializers.IssueCustomAttributeSerializer permission_classes = (permissions.IssueCustomAttributePermission,) @@ -76,7 +77,7 @@ class IssueCustomAttributeViewSet(BulkUpdateOrderMixin, ModelCrudViewSet): ####################################################### class BaseCustomAttributesValuesViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin, - ModelUpdateRetrieveViewSet): + BlockedByProjectMixin, ModelUpdateRetrieveViewSet): def get_object_for_snapshot(self, obj): return getattr(obj, self.content_object) diff --git a/taiga/projects/issues/api.py b/taiga/projects/issues/api.py index 59583ee5..0a93250b 100644 --- a/taiga/projects/issues/api.py +++ b/taiga/projects/issues/api.py @@ -24,6 +24,7 @@ from taiga.base import exceptions as exc from taiga.base import response from taiga.base.decorators import detail_route, list_route from taiga.base.api import ModelCrudViewSet, ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api.utils import get_object_or_404 from taiga.users.models import User @@ -43,7 +44,7 @@ from . import serializers class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin, - ModelCrudViewSet): + BlockedByProjectMixin, ModelCrudViewSet): queryset = models.Issue.objects.all() permission_classes = (permissions.IssuePermission, ) filter_backends = (filters.CanViewIssuesFilterBackend, @@ -157,8 +158,6 @@ class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, W super().pre_save(obj) def pre_conditions_on_save(self, obj): - super().pre_conditions_on_save(obj) - if obj.milestone and obj.milestone.project != obj.project: raise exc.PermissionDenied(_("You don't have permissions to set this sprint " "to this issue.")) @@ -179,6 +178,8 @@ class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, W raise exc.PermissionDenied(_("You don't have permissions to set this type " "to this issue.")) + super().pre_conditions_on_save(obj) + @list_route(methods=["GET"]) def by_ref(self, request): ref = request.QUERY_PARAMS.get("ref", None) @@ -232,6 +233,9 @@ class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, W data = serializer.data project = Project.objects.get(pk=data["project_id"]) self.check_permissions(request, 'bulk_create', project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + issues = services.create_issues_in_bulk( data["bulk_issues"], project=project, owner=request.user, status=project.default_issue_status, severity=project.default_severity, diff --git a/taiga/projects/likes/mixins/viewsets.py b/taiga/projects/likes/mixins/viewsets.py index 0b1b1831..03bf8987 100644 --- a/taiga/projects/likes/mixins/viewsets.py +++ b/taiga/projects/likes/mixins/viewsets.py @@ -27,10 +27,15 @@ from taiga.projects.likes import services class LikedResourceMixin: + """ + NOTE:the classes using this mixing must have a method: + def pre_conditions_on_save(self, obj) + """ @detail_route(methods=["POST"]) def like(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "like", obj) + self.pre_conditions_on_save(obj) services.add_like(obj, user=request.user) return response.Ok() @@ -39,6 +44,7 @@ class LikedResourceMixin: def unlike(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "unlike", obj) + self.pre_conditions_on_save(obj) services.remove_like(obj, user=request.user) return response.Ok() diff --git a/taiga/projects/migrations/0035_project_blocked_code.py b/taiga/projects/migrations/0035_project_blocked_code.py new file mode 100644 index 00000000..809e5cef --- /dev/null +++ b/taiga/projects/migrations/0035_project_blocked_code.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0034_project_looking_for_people_note'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='blocked_code', + field=models.CharField(choices=[('blocked-by-staff', 'This project was blocked by staff'), ('blocked-by-owner-leaving', 'This project was because the owner left')], null=True, default=None, max_length=255, blank=True, verbose_name='blocked code'), + ), + ] diff --git a/taiga/projects/milestones/api.py b/taiga/projects/milestones/api.py index 2823f762..b4d54023 100644 --- a/taiga/projects/milestones/api.py +++ b/taiga/projects/milestones/api.py @@ -22,6 +22,7 @@ from taiga.base import filters from taiga.base import response from taiga.base.decorators import detail_route from taiga.base.api import ModelCrudViewSet, ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api.utils import get_object_or_404 from taiga.base.utils.db import get_object_or_none @@ -37,7 +38,8 @@ from . import permissions import datetime -class MilestoneViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCrudViewSet): +class MilestoneViewSet(HistoryResourceMixin, WatchedResourceMixin, + BlockedByProjectMixin, ModelCrudViewSet): serializer_class = serializers.MilestoneSerializer permission_classes = (permissions.MilestonePermission,) filter_backends = (filters.CanViewMilestonesFilterBackend,) diff --git a/taiga/projects/mixins/ordering.py b/taiga/projects/mixins/ordering.py index 0a98c0a9..6917f1e3 100644 --- a/taiga/projects/mixins/ordering.py +++ b/taiga/projects/mixins/ordering.py @@ -54,6 +54,8 @@ class BulkUpdateOrderMixin: project = get_object_or_404(Project, id=project_id) self.check_permissions(request, 'bulk_update_order', project) - + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + self.__class__.bulk_update_order_action(project, request.user, bulk_data) return response.NoContent(data=None) diff --git a/taiga/projects/models.py b/taiga/projects/models.py index b5576a3a..60682a32 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -23,6 +23,7 @@ import uuid from unidecode import unidecode +from django.conf import settings from django.core.exceptions import ValidationError from django.db import models from django.db.models import signals, Q @@ -262,6 +263,10 @@ class Project(ProjectDefaults, TaggedMixin, models.Model): total_activity_last_year = models.PositiveIntegerField(null=False, blank=False, default=0, verbose_name=_("activity last year"), db_index=True) + blocked_code = models.CharField(null=True, blank=True, max_length=255, + choices=choices.BLOCKING_CODES + settings.EXTRA_BLOCKING_CODES, default=None, + verbose_name=_("blocked code")) + _cached_user_stories = None _importing = None diff --git a/taiga/projects/notifications/mixins.py b/taiga/projects/notifications/mixins.py index 726e639b..4fa143a4 100644 --- a/taiga/projects/notifications/mixins.py +++ b/taiga/projects/notifications/mixins.py @@ -45,9 +45,13 @@ class WatchedResourceMixin: Rest Framework resource mixin for resources susceptible to be notifiable about their changes. - NOTE: this mixin has hard dependency on HistoryMixin + NOTE: + - this mixin has hard dependency on HistoryMixin defined on history app and should be located always after it on inheritance definition. + + - the classes using this mixing must have a method: + def pre_conditions_on_save(self, obj) """ _not_notify = False @@ -64,6 +68,7 @@ class WatchedResourceMixin: def watch(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "watch", obj) + self.pre_conditions_on_save(obj) services.add_watcher(obj, request.user) return response.Ok() @@ -71,6 +76,7 @@ class WatchedResourceMixin: def unwatch(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "unwatch", obj) + self.pre_conditions_on_save(obj) services.remove_watcher(obj, request.user) return response.Ok() diff --git a/taiga/projects/serializers.py b/taiga/projects/serializers.py index a313b8a6..70875cd4 100644 --- a/taiga/projects/serializers.py +++ b/taiga/projects/serializers.py @@ -325,7 +325,7 @@ class ProjectSerializer(FanResourceSerializerMixin, WatchedResourceModelSerializ class Meta: model = models.Project - read_only_fields = ("created_date", "modified_date", "owner", "slug") + read_only_fields = ("created_date", "modified_date", "owner", "slug", "blocked_code") exclude = ("logo", "last_us_ref", "last_task_ref", "last_issue_ref", "issues_csv_uuid", "tasks_csv_uuid", "userstories_csv_uuid") @@ -402,7 +402,7 @@ class ProjectDetailSerializer(ProjectSerializer): class ProjectDetailAdminSerializer(ProjectDetailSerializer): class Meta: model = models.Project - read_only_fields = ("created_date", "modified_date", "owner", "slug") + read_only_fields = ("created_date", "modified_date", "owner", "slug", "blocked_code") exclude = ("logo", "last_us_ref", "last_task_ref", "last_issue_ref") diff --git a/taiga/projects/tasks/api.py b/taiga/projects/tasks/api.py index 8d4cf373..6bb2a1a3 100644 --- a/taiga/projects/tasks/api.py +++ b/taiga/projects/tasks/api.py @@ -22,6 +22,7 @@ from taiga.base import filters, response from taiga.base import exceptions as exc from taiga.base.decorators import list_route from taiga.base.api import ModelCrudViewSet, ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.projects.models import Project, TaskStatus from django.http import HttpResponse @@ -38,7 +39,7 @@ from . import services class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin, - ModelCrudViewSet): + BlockedByProjectMixin, ModelCrudViewSet): queryset = models.Task.objects.all() permission_classes = (permissions.TaskPermission,) filter_backends = (filters.CanViewTasksFilterBackend, filters.WatchersFilter) @@ -95,7 +96,7 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, Wa "assigned_to", "status", "project") - + return self.attach_watchers_attrs_to_queryset(qs) def pre_save(self, obj): @@ -147,6 +148,9 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, Wa data = serializer.data project = Project.objects.get(id=data["project_id"]) self.check_permissions(request, 'bulk_create', project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + tasks = services.create_tasks_in_bulk( data["bulk_tasks"], milestone_id=data["sprint_id"], user_story_id=data["us_id"], status_id=data.get("status_id") or project.default_task_status_id, @@ -166,6 +170,9 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, Wa project = get_object_or_404(Project, pk=data["project_id"]) self.check_permissions(request, "bulk_update_order", project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + services.update_tasks_order_in_bulk(data["bulk_tasks"], project=project, field=order_field) diff --git a/taiga/projects/userstories/api.py b/taiga/projects/userstories/api.py index 3a1650ea..815560c1 100644 --- a/taiga/projects/userstories/api.py +++ b/taiga/projects/userstories/api.py @@ -29,6 +29,7 @@ from taiga.base import exceptions as exc from taiga.base import response from taiga.base import status from taiga.base.decorators import list_route +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api import ModelCrudViewSet, ModelListViewSet from taiga.base.api.utils import get_object_or_404 @@ -46,7 +47,7 @@ from . import services class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin, - ModelCrudViewSet): + BlockedByProjectMixin, ModelCrudViewSet): queryset = models.UserStory.objects.all() permission_classes = (permissions.UserStoryPermission,) filter_backends = (filters.CanViewUsFilterBackend, @@ -213,6 +214,9 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi data = serializer.data project = Project.objects.get(id=data["project_id"]) self.check_permissions(request, 'bulk_create', project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + user_stories = services.create_userstories_in_bulk( data["bulk_stories"], project=project, owner=request.user, status_id=data.get("status_id") or project.default_us_status_id, @@ -230,6 +234,9 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi project = get_object_or_404(Project, pk=data["project_id"]) self.check_permissions(request, "bulk_update_order", project) + if project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) + services.update_userstories_order_in_bulk(data["bulk_stories"], project=project, field=order_field) diff --git a/taiga/projects/votes/mixins/viewsets.py b/taiga/projects/votes/mixins/viewsets.py index fb33304b..2fce2d60 100644 --- a/taiga/projects/votes/mixins/viewsets.py +++ b/taiga/projects/votes/mixins/viewsets.py @@ -28,10 +28,15 @@ from taiga.projects.votes.utils import attach_total_voters_to_queryset, attach_i class VotedResourceMixin: - # Note: Update get_queryset method: - # def get_queryset(self): - # qs = super().get_queryset() - # return self.attach_votes_attrs_to_queryset(qs) + """ + Note: Update get_queryset method: + def get_queryset(self): + qs = super().get_queryset() + return self.attach_votes_attrs_to_queryset(qs) + + - the classes using this mixing must have a method: + def pre_conditions_on_save(self, obj) + """ def attach_votes_attrs_to_queryset(self, queryset): qs = attach_total_voters_to_queryset(queryset) @@ -45,6 +50,7 @@ class VotedResourceMixin: def upvote(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "upvote", obj) + self.pre_conditions_on_save(obj) services.add_vote(obj, user=request.user) return response.Ok() @@ -53,6 +59,7 @@ class VotedResourceMixin: def downvote(self, request, pk=None): obj = self.get_object() self.check_permissions(request, "downvote", obj) + self.pre_conditions_on_save(obj) services.remove_vote(obj, user=request.user) return response.Ok() diff --git a/taiga/projects/wiki/api.py b/taiga/projects/wiki/api.py index a88c8d14..ea014233 100644 --- a/taiga/projects/wiki/api.py +++ b/taiga/projects/wiki/api.py @@ -23,6 +23,7 @@ from taiga.base import filters from taiga.base import exceptions as exc from taiga.base import response from taiga.base.api import ModelCrudViewSet, ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.api.utils import get_object_or_404 from taiga.base.decorators import list_route from taiga.projects.models import Project @@ -38,7 +39,9 @@ from . import permissions from . import serializers -class WikiViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin, ModelCrudViewSet): +class WikiViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin, + BlockedByProjectMixin, ModelCrudViewSet): + model = models.WikiPage serializer_class = serializers.WikiPageSerializer permission_classes = (permissions.WikiPagePermission,) @@ -89,7 +92,7 @@ class WikiWatchersViewSet(WatchersViewSetMixin, ModelListViewSet): resource_model = models.WikiPage -class WikiLinkViewSet(ModelCrudViewSet): +class WikiLinkViewSet(BlockedByProjectMixin, ModelCrudViewSet): model = models.WikiLink serializer_class = serializers.WikiLinkSerializer permission_classes = (permissions.WikiLinkPermission,) diff --git a/taiga/users/api.py b/taiga/users/api.py index f5d59bd4..96e2742d 100644 --- a/taiga/users/api.py +++ b/taiga/users/api.py @@ -31,6 +31,7 @@ from taiga.auth.tokens import get_user_for_token from taiga.base.decorators import list_route from taiga.base.decorators import detail_route from taiga.base.api import ModelCrudViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.filters import PermissionBasedFilterBackend from taiga.base.api.utils import get_object_or_404 from taiga.base.filters import MembersFilterBackend @@ -403,7 +404,7 @@ class UsersViewSet(ModelCrudViewSet): ## Role ###################################################### -class RolesViewSet(ModelCrudViewSet): +class RolesViewSet(BlockedByProjectMixin, ModelCrudViewSet): model = models.Role serializer_class = serializers.RoleSerializer permission_classes = (permissions.RolesPermission, ) diff --git a/taiga/webhooks/api.py b/taiga/webhooks/api.py index b9092f47..a9b8545e 100644 --- a/taiga/webhooks/api.py +++ b/taiga/webhooks/api.py @@ -15,10 +15,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from django.utils.translation import ugettext as _ + from taiga.base import filters from taiga.base import response +from taiga.base import exceptions as exc from taiga.base.api import ModelCrudViewSet from taiga.base.api import ModelListViewSet +from taiga.base.api.mixins import BlockedByProjectMixin from taiga.base.decorators import detail_route @@ -28,7 +32,7 @@ from . import permissions from . import tasks -class WebhookViewSet(ModelCrudViewSet): +class WebhookViewSet(BlockedByProjectMixin, ModelCrudViewSet): model = models.Webhook serializer_class = serializers.WebhookSerializer permission_classes = (permissions.WebhookPermission,) @@ -39,6 +43,7 @@ class WebhookViewSet(ModelCrudViewSet): def test(self, request, pk=None): webhook = self.get_object() self.check_permissions(request, 'test', webhook) + self.pre_conditions_blocked(webhook) webhooklog = tasks.test_webhook(webhook.id, webhook.url, webhook.key) log = serializers.WebhookLogSerializer(webhooklog) @@ -57,8 +62,9 @@ class WebhookLogViewSet(ModelListViewSet): def resend(self, request, pk=None): webhooklog = self.get_object() self.check_permissions(request, 'resend', webhooklog) - webhook = webhooklog.webhook + if webhook.project.blocked_code is not None: + raise exc.Blocked(_("Blocked element")) webhooklog = tasks.resend_webhook(webhook.id, webhook.url, webhook.key, webhooklog.request_data) diff --git a/tests/integration/resources_permissions/test_attachment_resources.py b/tests/integration/resources_permissions/test_attachment_resources.py index 520e266a..f6cc6339 100644 --- a/tests/integration/resources_permissions/test_attachment_resources.py +++ b/tests/integration/resources_permissions/test_attachment_resources.py @@ -5,6 +5,7 @@ from django.test.client import MULTIPART_CONTENT from taiga.base.utils import json from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS +from taiga.projects import choices as project_choices from taiga.projects.attachments.serializers import AttachmentSerializer from tests import factories as f @@ -47,6 +48,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -68,6 +74,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -81,6 +95,9 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) return m @@ -96,6 +113,9 @@ def data_us(data): m.private_user_story2 = f.UserStoryFactory(project=data.private_project2, ref=9) m.private_user_story2_attachment = f.UserStoryAttachmentFactory(project=data.private_project2, content_object=m.private_user_story2) + m.blocked_user_story = f.UserStoryFactory(project=data.blocked_project, ref=13) + m.blocked_user_story_attachment = f.UserStoryAttachmentFactory(project=data.blocked_project, + content_object=m.blocked_user_story) return m @@ -108,6 +128,8 @@ def data_task(data): m.private_task1_attachment = f.TaskAttachmentFactory(project=data.private_project1, content_object=m.private_task1) m.private_task2 = f.TaskFactory(project=data.private_project2, ref=10) m.private_task2_attachment = f.TaskAttachmentFactory(project=data.private_project2, content_object=m.private_task2) + m.blocked_task = f.TaskFactory(project=data.blocked_project, ref=14) + m.blocked_task_attachment = f.TaskAttachmentFactory(project=data.blocked_project, content_object=m.blocked_task) return m @@ -120,6 +142,8 @@ def data_issue(data): m.private_issue1_attachment = f.IssueAttachmentFactory(project=data.private_project1, content_object=m.private_issue1) m.private_issue2 = f.IssueFactory(project=data.private_project2, ref=11) m.private_issue2_attachment = f.IssueAttachmentFactory(project=data.private_project2, content_object=m.private_issue2) + m.blocked_issue = f.IssueFactory(project=data.blocked_project, ref=11) + m.blocked_issue_attachment = f.IssueAttachmentFactory(project=data.blocked_project, content_object=m.blocked_issue) return m @@ -132,6 +156,8 @@ def data_wiki(data): m.private_wiki1_attachment = f.WikiAttachmentFactory(project=data.private_project1, content_object=m.private_wiki1) m.private_wiki2 = f.WikiPageFactory(project=data.private_project2, slug=12) m.private_wiki2_attachment = f.WikiAttachmentFactory(project=data.private_project2, content_object=m.private_wiki2) + m.blocked_wiki = f.WikiPageFactory(project=data.blocked_project, slug=1) + m.blocked_wiki_attachment = f.WikiAttachmentFactory(project=data.blocked_project, content_object=m.blocked_wiki) return m @@ -139,6 +165,7 @@ def test_user_story_attachment_retrieve(client, data, data_us): public_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.public_user_story_attachment.pk}) private_url1 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story1_attachment.pk}) private_url2 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story2_attachment.pk}) + blocked_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.blocked_user_story_attachment.pk}) users = [ None, @@ -154,12 +181,15 @@ def test_user_story_attachment_retrieve(client, data, data_us): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_attachment_retrieve(client, data, data_task): public_url = reverse('task-attachments-detail', kwargs={"pk": data_task.public_task_attachment.pk}) private_url1 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task1_attachment.pk}) private_url2 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task2_attachment.pk}) + blocked_url = reverse('task-attachments-detail', kwargs={"pk": data_task.blocked_task_attachment.pk}) users = [ None, @@ -175,12 +205,15 @@ def test_task_attachment_retrieve(client, data, data_task): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_attachment_retrieve(client, data, data_issue): public_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.public_issue_attachment.pk}) private_url1 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue1_attachment.pk}) private_url2 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue2_attachment.pk}) + blocked_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.blocked_issue_attachment.pk}) users = [ None, @@ -196,12 +229,15 @@ def test_issue_attachment_retrieve(client, data, data_issue): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_wiki_attachment_retrieve(client, data, data_wiki): public_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.public_wiki_attachment.pk}) private_url1 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki1_attachment.pk}) private_url2 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki2_attachment.pk}) + blocked_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.blocked_wiki_attachment.pk}) users = [ None, @@ -217,6 +253,8 @@ def test_wiki_attachment_retrieve(client, data, data_wiki): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_user_story_attachment_update(client, data, data_us): @@ -226,7 +264,8 @@ def test_user_story_attachment_update(client, data, data_us): args=[data_us.private_user_story1_attachment.pk]) private_url2 = reverse("userstory-attachments-detail", args=[data_us.private_user_story2_attachment.pk]) - + blocked_url = reverse("userstory-attachments-detail", + args=[data_us.blocked_user_story_attachment.pk]) users = [ None, data.registered_user, @@ -252,11 +291,16 @@ def test_user_story_attachment_update(client, data, data_us): # assert results == [401, 403, 403, 400, 400] assert results == [405, 405, 405, 405, 405] + results = helper_test_http_method(client, "put", blocked_url, attachment_data, users) + # assert results == [401, 403, 403, 400, 400] + assert results == [405, 405, 405, 405, 405] + def test_task_attachment_update(client, data, data_task): public_url = reverse('task-attachments-detail', kwargs={"pk": data_task.public_task_attachment.pk}) private_url1 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task1_attachment.pk}) private_url2 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task2_attachment.pk}) + blocked_url = reverse('task-attachments-detail', kwargs={"pk": data_task.blocked_task_attachment.pk}) users = [ None, @@ -279,12 +323,16 @@ def test_task_attachment_update(client, data, data_task): results = helper_test_http_method(client, 'put', private_url2, attachment_data, users) assert results == [405, 405, 405, 405, 405] # assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'put', blocked_url, attachment_data, users) + assert results == [405, 405, 405, 405, 405] + # assert results == [401, 403, 403, 200, 200] def test_issue_attachment_update(client, data, data_issue): public_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.public_issue_attachment.pk}) private_url1 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue1_attachment.pk}) private_url2 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue2_attachment.pk}) + blocked_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.blocked_issue_attachment.pk}) users = [ None, @@ -307,12 +355,16 @@ def test_issue_attachment_update(client, data, data_issue): results = helper_test_http_method(client, 'put', private_url2, attachment_data, users) assert results == [405, 405, 405, 405, 405] # assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'put', blocked_url, attachment_data, users) + assert results == [405, 405, 405, 405, 405] + # assert results == [401, 403, 403, 200, 200] def test_wiki_attachment_update(client, data, data_wiki): public_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.public_wiki_attachment.pk}) private_url1 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki1_attachment.pk}) private_url2 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki2_attachment.pk}) + blocked_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.blocked_wiki_attachment.pk}) users = [ None, @@ -335,12 +387,16 @@ def test_wiki_attachment_update(client, data, data_wiki): results = helper_test_http_method(client, 'put', private_url2, attachment_data, users) assert results == [405, 405, 405, 405, 405] # assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'put', blocked_url, attachment_data, users) + assert results == [405, 405, 405, 405, 405] + # assert results == [401, 403, 403, 200, 200] def test_user_story_attachment_patch(client, data, data_us): public_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.public_user_story_attachment.pk}) private_url1 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story1_attachment.pk}) private_url2 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story2_attachment.pk}) + blocked_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.blocked_user_story_attachment.pk}) users = [ None, @@ -359,12 +415,15 @@ def test_user_story_attachment_patch(client, data, data_us): assert results == [401, 403, 403, 200, 200] results = helper_test_http_method(client, 'patch', private_url2, attachment_data, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'patch', blocked_url, attachment_data, users) + assert results == [401, 403, 403, 451, 451] def test_task_attachment_patch(client, data, data_task): public_url = reverse('task-attachments-detail', kwargs={"pk": data_task.public_task_attachment.pk}) private_url1 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task1_attachment.pk}) private_url2 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task2_attachment.pk}) + blocked_url = reverse('task-attachments-detail', kwargs={"pk": data_task.blocked_task_attachment.pk}) users = [ None, @@ -383,12 +442,15 @@ def test_task_attachment_patch(client, data, data_task): assert results == [401, 403, 403, 200, 200] results = helper_test_http_method(client, 'patch', private_url2, attachment_data, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'patch', blocked_url, attachment_data, users) + assert results == [401, 403, 403, 451, 451] def test_issue_attachment_patch(client, data, data_issue): public_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.public_issue_attachment.pk}) private_url1 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue1_attachment.pk}) private_url2 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue2_attachment.pk}) + blocked_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.blocked_issue_attachment.pk}) users = [ None, @@ -407,12 +469,15 @@ def test_issue_attachment_patch(client, data, data_issue): assert results == [401, 403, 403, 200, 200] results = helper_test_http_method(client, 'patch', private_url2, attachment_data, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'patch', blocked_url, attachment_data, users) + assert results == [401, 403, 403, 451, 451] def test_wiki_attachment_patch(client, data, data_wiki): public_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.public_wiki_attachment.pk}) private_url1 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki1_attachment.pk}) private_url2 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki2_attachment.pk}) + blocked_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.blocked_wiki_attachment.pk}) users = [ None, @@ -431,12 +496,15 @@ def test_wiki_attachment_patch(client, data, data_wiki): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'patch', private_url2, attachment_data, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'patch', blocked_url, attachment_data, users) + assert results == [401, 403, 403, 451, 451] def test_user_story_attachment_delete(client, data, data_us): public_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.public_user_story_attachment.pk}) private_url1 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story1_attachment.pk}) private_url2 = reverse('userstory-attachments-detail', kwargs={"pk": data_us.private_user_story2_attachment.pk}) + blocked_url = reverse('userstory-attachments-detail', kwargs={"pk": data_us.blocked_user_story_attachment.pk}) users = [ None, @@ -451,12 +519,15 @@ def test_user_story_attachment_delete(client, data, data_us): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_task_attachment_delete(client, data, data_task): public_url = reverse('task-attachments-detail', kwargs={"pk": data_task.public_task_attachment.pk}) private_url1 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task1_attachment.pk}) private_url2 = reverse('task-attachments-detail', kwargs={"pk": data_task.private_task2_attachment.pk}) + blocked_url = reverse('task-attachments-detail', kwargs={"pk": data_task.blocked_task_attachment.pk}) users = [ None, @@ -471,12 +542,15 @@ def test_task_attachment_delete(client, data, data_task): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_issue_attachment_delete(client, data, data_issue): public_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.public_issue_attachment.pk}) private_url1 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue1_attachment.pk}) private_url2 = reverse('issue-attachments-detail', kwargs={"pk": data_issue.private_issue2_attachment.pk}) + blocked_url = reverse('issue-attachments-detail', kwargs={"pk": data_issue.blocked_issue_attachment.pk}) users = [ None, @@ -491,12 +565,15 @@ def test_issue_attachment_delete(client, data, data_issue): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_wiki_attachment_delete(client, data, data_wiki): public_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.public_wiki_attachment.pk}) private_url1 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki1_attachment.pk}) private_url2 = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.private_wiki2_attachment.pk}) + blocked_url = reverse('wiki-attachments-detail', kwargs={"pk": data_wiki.blocked_wiki_attachment.pk}) users = [ None, @@ -511,6 +588,8 @@ def test_wiki_attachment_delete(client, data, data_wiki): assert results == [401, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_user_story_attachment_create(client, data, data_us): @@ -536,6 +615,15 @@ def test_user_story_attachment_create(client, data, data_us): after_each_request=_after_each_request_hook) assert results == [401, 403, 403, 201, 201] + attachment_data = {"description": "test", + "object_id": data_us.blocked_user_story_attachment.object_id, + "project": data_us.blocked_user_story_attachment.project_id, + "attached_file": SimpleUploadedFile("test.txt", b"test")} + results = helper_test_http_method(client, 'post', url, attachment_data, users, + content_type=MULTIPART_CONTENT, + after_each_request=_after_each_request_hook) + assert results == [401, 403, 403, 451, 451] + def test_task_attachment_create(client, data, data_task): url = reverse('task-attachments-list') @@ -560,6 +648,18 @@ def test_task_attachment_create(client, data, data_task): after_each_request=_after_each_request_hook) assert results == [401, 403, 403, 201, 201] + attachment_data = {"description": "test", + "object_id": data_task.blocked_task_attachment.object_id, + "project": data_task.blocked_task_attachment.project_id, + "attached_file": SimpleUploadedFile("test.txt", b"test")} + + _after_each_request_hook = lambda: attachment_data["attached_file"].seek(0) + + results = helper_test_http_method(client, 'post', url, attachment_data, users, + content_type=MULTIPART_CONTENT, + after_each_request=_after_each_request_hook) + assert results == [401, 403, 403, 451, 451] + def test_issue_attachment_create(client, data, data_issue): url = reverse('issue-attachments-list') @@ -585,6 +685,19 @@ def test_issue_attachment_create(client, data, data_issue): assert results == [401, 403, 403, 201, 201] + attachment_data = {"description": "test", + "object_id": data_issue.blocked_issue_attachment.object_id, + "project": data_issue.blocked_issue_attachment.project_id, + "attached_file": SimpleUploadedFile("test.txt", b"test")} + + _after_each_request_hook = lambda: attachment_data["attached_file"].seek(0) + + results = helper_test_http_method(client, 'post', url, attachment_data, users, + content_type=MULTIPART_CONTENT, + after_each_request=_after_each_request_hook) + + assert results == [401, 403, 403, 451, 451] + def test_wiki_attachment_create(client, data, data_wiki): url = reverse('wiki-attachments-list') @@ -610,6 +723,19 @@ def test_wiki_attachment_create(client, data, data_wiki): assert results == [401, 201, 201, 201, 201] + attachment_data = {"description": "test", + "object_id": data_wiki.blocked_wiki_attachment.object_id, + "project": data_wiki.blocked_wiki_attachment.project_id, + "attached_file": SimpleUploadedFile("test.txt", b"test")} + + _after_each_request_hook = lambda: attachment_data["attached_file"].seek(0) + + results = helper_test_http_method(client, 'post', url, attachment_data, users, + content_type=MULTIPART_CONTENT, + after_each_request=_after_each_request_hook) + + assert results == [401, 403, 403, 451, 451] + def test_user_story_attachment_list(client, data, data_us): url = reverse('userstory-attachments-list') @@ -623,7 +749,7 @@ def test_user_story_attachment_list(client, data, data_us): ] results = helper_test_http_method_and_count(client, 'get', url, None, users) - assert results == [(200, 2), (200, 2), (200, 2), (200, 3), (200, 3)] + assert results == [(200, 2), (200, 2), (200, 2), (200, 4), (200, 4)] def test_task_attachment_list(client, data, data_task): @@ -638,7 +764,7 @@ def test_task_attachment_list(client, data, data_task): ] results = helper_test_http_method_and_count(client, 'get', url, None, users) - assert results == [(200, 2), (200, 2), (200, 2), (200, 3), (200, 3)] + assert results == [(200, 2), (200, 2), (200, 2), (200, 4), (200, 4)] def test_issue_attachment_list(client, data, data_issue): @@ -653,7 +779,7 @@ def test_issue_attachment_list(client, data, data_issue): ] results = helper_test_http_method_and_count(client, 'get', url, None, users) - assert results == [(200, 2), (200, 2), (200, 2), (200, 3), (200, 3)] + assert results == [(200, 2), (200, 2), (200, 2), (200, 4), (200, 4)] def test_wiki_attachment_list(client, data, data_wiki): @@ -668,4 +794,4 @@ def test_wiki_attachment_list(client, data, data_wiki): ] results = helper_test_http_method_and_count(client, 'get', url, None, users) - assert results == [(200, 2), (200, 2), (200, 2), (200, 3), (200, 3)] + assert results == [(200, 2), (200, 2), (200, 2), (200, 4), (200, 4)] 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 da0fa833..81cfdb31 100644 --- a/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py +++ b/tests/integration/resources_permissions/test_issues_custom_attributes_resource.py @@ -19,6 +19,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.custom_attributes import serializers from taiga.permissions.permissions import (MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS) @@ -52,6 +53,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -81,6 +87,17 @@ def data(): role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + email=m.project_member_with_perms.email, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + email=m.project_member_without_perms.email, + role__project=m.blocked_project, + role__permissions=[]) + f.MembershipFactory(project=m.public_project, user=m.project_owner, is_owner=True) @@ -93,9 +110,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_issue_ca = f.IssueCustomAttributeFactory(project=m.public_project) m.private_issue_ca1 = f.IssueCustomAttributeFactory(project=m.private_project1) m.private_issue_ca2 = f.IssueCustomAttributeFactory(project=m.private_project2) + m.blocked_issue_ca = f.IssueCustomAttributeFactory(project=m.blocked_project) m.public_issue = f.IssueFactory(project=m.public_project, status__project=m.public_project, @@ -115,10 +137,17 @@ def data(): priority__project=m.private_project2, type__project=m.private_project2, milestone__project=m.private_project2) + m.blocked_issue = f.IssueFactory(project=m.blocked_project, + status__project=m.blocked_project, + severity__project=m.blocked_project, + priority__project=m.blocked_project, + type__project=m.blocked_project, + milestone__project=m.blocked_project) m.public_issue_cav = m.public_issue.custom_attributes_values m.private_issue_cav1 = m.private_issue1.custom_attributes_values m.private_issue_cav2 = m.private_issue2.custom_attributes_values + m.blocked_issue_cav = m.blocked_issue.custom_attributes_values return m @@ -131,6 +160,7 @@ def test_issue_custom_attribute_retrieve(client, data): public_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.public_issue_ca.pk}) private1_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca1.pk}) private2_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca2.pk}) + blocked_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.blocked_issue_ca.pk}) users = [ None, @@ -146,12 +176,15 @@ def test_issue_custom_attribute_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_custom_attribute_create(client, data): public_url = reverse('issue-custom-attributes-list') private1_url = reverse('issue-custom-attributes-list') private2_url = reverse('issue-custom-attributes-list') + blocked_url = reverse('issue-custom-attributes-list') users = [ None, @@ -176,11 +209,17 @@ def test_issue_custom_attribute_create(client, data): results = helper_test_http_method(client, 'post', private2_url, issue_ca_data, users) assert results == [401, 403, 403, 403, 201] + issue_ca_data = {"name": "test-new", "project": data.blocked_project.id} + issue_ca_data = json.dumps(issue_ca_data) + results = helper_test_http_method(client, 'post', private2_url, issue_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_custom_attribute_update(client, data): public_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.public_issue_ca.pk}) private1_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca1.pk}) private2_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca2.pk}) + blocked_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.blocked_issue_ca.pk}) users = [ None, @@ -208,11 +247,18 @@ def test_issue_custom_attribute_update(client, data): results = helper_test_http_method(client, 'put', private2_url, issue_ca_data, users) assert results == [401, 403, 403, 403, 200] + issue_ca_data = serializers.IssueCustomAttributeSerializer(data.blocked_issue_ca).data + issue_ca_data["name"] = "test" + issue_ca_data = json.dumps(issue_ca_data) + results = helper_test_http_method(client, 'put', blocked_url, issue_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_custom_attribute_delete(client, data): public_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.public_issue_ca.pk}) private1_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca1.pk}) private2_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca2.pk}) + blocked_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.blocked_issue_ca.pk}) users = [ None, @@ -228,6 +274,8 @@ def test_issue_custom_attribute_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_issue_custom_attribute_list(client, data): @@ -249,12 +297,12 @@ def test_issue_custom_attribute_list(client, data): client.login(data.project_member_with_perms) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 @@ -262,6 +310,7 @@ def test_issue_custom_attribute_patch(client, data): public_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.public_issue_ca.pk}) private1_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca1.pk}) private2_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.private_issue_ca2.pk}) + blocked_url = reverse('issue-custom-attributes-detail', kwargs={"pk": data.blocked_issue_ca.pk}) users = [ None, @@ -277,6 +326,8 @@ def test_issue_custom_attribute_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_issue_custom_attribute_action_bulk_update_order(client, data): @@ -311,6 +362,12 @@ 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] + post_data = json.dumps({ + "bulk_issue_custom_attributes": [(1,2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] ######################################################### # Issue Custom Attribute @@ -321,6 +378,7 @@ def test_issue_custom_attributes_values_retrieve(client, data): public_url = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.public_issue.pk}) private_url1 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue1.pk}) private_url2 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue2.pk}) + blocked_url = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.blocked_issue.pk}) users = [ None, @@ -336,12 +394,15 @@ def test_issue_custom_attributes_values_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_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', kwargs={"issue_id": data.public_issue.pk}) private_url1 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue1.pk}) private_url2 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue2.pk}) + blocked_url = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.blocked_issue.pk}) users = [ None, @@ -369,11 +430,18 @@ def test_issue_custom_attributes_values_update(client, data): results = helper_test_http_method(client, 'put', private_url2, issue_data, users) assert results == [401, 403, 403, 200, 200] + issue_data = serializers.IssueCustomAttributesValuesSerializer(data.blocked_issue_cav).data + issue_data["attributes_values"] = {str(data.blocked_issue_ca.pk): "test"} + issue_data = json.dumps(issue_data) + results = helper_test_http_method(client, 'put', blocked_url, issue_data, users) + assert results == [401, 403, 403, 451, 451] + def test_issue_custom_attributes_values_patch(client, data): public_url = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.public_issue.pk}) private_url1 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue1.pk}) private_url2 = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.private_issue2.pk}) + blocked_url = reverse('issue-custom-attributes-values-detail', kwargs={"issue_id": data.blocked_issue.pk}) users = [ None, @@ -397,3 +465,8 @@ def test_issue_custom_attributes_values_patch(client, data): "version": data.private_issue2.version}) results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + + patch_data = json.dumps({"attributes_values": {str(data.blocked_issue_ca.pk): "test"}, + "version": data.blocked_issue.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] diff --git a/tests/integration/resources_permissions/test_issues_resources.py b/tests/integration/resources_permissions/test_issues_resources.py index 469efacc..11d3bf62 100644 --- a/tests/integration/resources_permissions/test_issues_resources.py +++ b/tests/integration/resources_permissions/test_issues_resources.py @@ -2,6 +2,7 @@ import uuid from django.core.urlresolvers import reverse +from taiga.projects import choices as project_choices from taiga.projects.issues.serializers import IssueSerializer from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS from taiga.base.utils import json @@ -51,6 +52,12 @@ def data(): public_permissions=[], owner=m.project_owner, issues_csv_uuid=uuid.uuid4().hex) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + issues_csv_uuid=uuid.uuid4().hex, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -72,6 +79,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -85,6 +100,10 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_issue = f.IssueFactory(project=m.public_project, status__project=m.public_project, severity__project=m.public_project, @@ -103,6 +122,12 @@ def data(): priority__project=m.private_project2, type__project=m.private_project2, milestone__project=m.private_project2) + m.blocked_issue = f.IssueFactory(project=m.blocked_project, + status__project=m.blocked_project, + severity__project=m.blocked_project, + priority__project=m.blocked_project, + type__project=m.blocked_project, + milestone__project=m.blocked_project) return m @@ -111,6 +136,7 @@ def test_issue_retrieve(client, data): public_url = reverse('issues-detail', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-detail', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-detail', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-detail', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -126,12 +152,15 @@ def test_issue_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_update(client, data): public_url = reverse('issues-detail', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-detail', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-detail', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-detail', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -160,6 +189,12 @@ def test_issue_update(client, data): results = helper_test_http_method(client, 'put', private_url2, issue_data, users) assert results == [401, 403, 403, 200, 200] + issue_data = IssueSerializer(data.blocked_issue).data + issue_data["subject"] = "test" + issue_data = json.dumps(issue_data) + results = helper_test_http_method(client, 'put', blocked_url, issue_data, users) + assert results == [401, 403, 403, 451, 451] + def test_issue_update_with_project_change(client): user1 = f.UserFactory.create() @@ -278,6 +313,7 @@ def test_issue_delete(client, data): public_url = reverse('issues-detail', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-detail', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-detail', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-detail', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -292,6 +328,8 @@ def test_issue_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_issue_list(client, data): @@ -313,14 +351,14 @@ def test_issue_list(client, data): response = client.get(url) issues_data = json.loads(response.content.decode('utf-8')) - assert len(issues_data) == 3 + assert len(issues_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) issues_data = json.loads(response.content.decode('utf-8')) - assert len(issues_data) == 3 + assert len(issues_data) == 4 assert response.status_code == 200 @@ -390,11 +428,24 @@ def test_issue_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({ + "subject": "test", + "ref": 3, + "project": data.blocked_project.pk, + "severity": data.blocked_project.severities.all()[0].pk, + "priority": data.blocked_project.priorities.all()[0].pk, + "status": data.blocked_project.issue_statuses.all()[0].pk, + "type": data.blocked_project.issue_types.all()[0].pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users) + assert results == [401, 403, 403, 451, 451] + def test_issue_patch(client, data): public_url = reverse('issues-detail', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-detail', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-detail', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-detail', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -417,6 +468,10 @@ def test_issue_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"subject": "test", "version": data.blocked_issue.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_issue_bulk_create(client, data): data.public_issue.project.default_issue_status = f.IssueStatusFactory() @@ -437,6 +492,12 @@ def test_issue_bulk_create(client, data): data.private_issue2.project.default_severity = f.SeverityFactory() data.private_issue2.project.save() + data.blocked_issue.project.default_issue_status = f.IssueStatusFactory() + data.blocked_issue.project.default_issue_type = f.IssueTypeFactory() + data.blocked_issue.project.default_priority = f.PriorityFactory() + data.blocked_issue.project.default_severity = f.SeverityFactory() + data.blocked_issue.project.save() + url = reverse('issues-bulk-create') users = [ @@ -462,11 +523,17 @@ def test_issue_bulk_create(client, data): results = helper_test_http_method(client, 'post', url, bulk_data, users) assert results == [401, 403, 403, 200, 200] + bulk_data = json.dumps({"bulk_issues": "test1\ntest2", + "project_id": data.blocked_issue.project.pk}) + results = helper_test_http_method(client, 'post', url, bulk_data, users) + assert results == [401, 403, 403, 451, 451] + def test_issue_action_upvote(client, data): public_url = reverse('issues-upvote', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-upvote', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-upvote', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-upvote', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -482,12 +549,15 @@ def test_issue_action_upvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_issue_action_downvote(client, data): public_url = reverse('issues-downvote', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-downvote', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-downvote', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-downvote', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -503,12 +573,15 @@ def test_issue_action_downvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_issue_voters_list(client, data): public_url = reverse('issue-voters-list', kwargs={"resource_id": data.public_issue.pk}) private_url1 = reverse('issue-voters-list', kwargs={"resource_id": data.private_issue1.pk}) private_url2 = reverse('issue-voters-list', kwargs={"resource_id": data.private_issue2.pk}) + blocked_url = reverse('issue-voters-list', kwargs={"resource_id": data.blocked_issue.pk}) users = [ None, @@ -524,6 +597,8 @@ def test_issue_voters_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_voters_retrieve(client, data): @@ -536,6 +611,9 @@ def test_issue_voters_retrieve(client, data): add_vote(data.private_issue2, data.project_owner) private_url2 = reverse('issue-voters-detail', kwargs={"resource_id": data.private_issue2.pk, "pk": data.project_owner.pk}) + add_vote(data.blocked_issue, data.project_owner) + blocked_url = reverse('issue-voters-detail', kwargs={"resource_id": data.blocked_issue.pk, + "pk": data.project_owner.pk}) users = [ None, @@ -551,13 +629,16 @@ def test_issue_voters_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issues_csv(client, data): url = reverse('issues-csv') csv_public_uuid = data.public_project.issues_csv_uuid csv_private1_uuid = data.private_project1.issues_csv_uuid - csv_private2_uuid = data.private_project1.issues_csv_uuid + csv_private2_uuid = data.private_project2.issues_csv_uuid + csv_blocked_uuid = data.blocked_project.issues_csv_uuid users = [ None, @@ -576,11 +657,15 @@ def test_issues_csv(client, data): results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private2_uuid), None, users) assert results == [200, 200, 200, 200, 200] + results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_blocked_uuid), None, users) + assert results == [200, 200, 200, 200, 200] + def test_issue_action_watch(client, data): public_url = reverse('issues-watch', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-watch', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-watch', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-watch', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -596,12 +681,15 @@ def test_issue_action_watch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_issue_action_unwatch(client, data): public_url = reverse('issues-unwatch', kwargs={"pk": data.public_issue.pk}) private_url1 = reverse('issues-unwatch', kwargs={"pk": data.private_issue1.pk}) private_url2 = reverse('issues-unwatch', kwargs={"pk": data.private_issue2.pk}) + blocked_url = reverse('issues-unwatch', kwargs={"pk": data.blocked_issue.pk}) users = [ None, @@ -617,12 +705,15 @@ def test_issue_action_unwatch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_issue_watchers_list(client, data): public_url = reverse('issue-watchers-list', kwargs={"resource_id": data.public_issue.pk}) private_url1 = reverse('issue-watchers-list', kwargs={"resource_id": data.private_issue1.pk}) private_url2 = reverse('issue-watchers-list', kwargs={"resource_id": data.private_issue2.pk}) + blocked_url = reverse('issue-watchers-list', kwargs={"resource_id": data.blocked_issue.pk}) users = [ None, @@ -638,6 +729,8 @@ def test_issue_watchers_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_watchers_retrieve(client, data): @@ -650,7 +743,9 @@ def test_issue_watchers_retrieve(client, data): add_watcher(data.private_issue2, data.project_owner) private_url2 = reverse('issue-watchers-detail', kwargs={"resource_id": data.private_issue2.pk, "pk": data.project_owner.pk}) - + add_watcher(data.blocked_issue, data.project_owner) + blocked_url = reverse('issue-watchers-detail', kwargs={"resource_id": data.blocked_issue.pk, + "pk": data.project_owner.pk}) users = [ None, data.registered_user, @@ -665,3 +760,5 @@ def test_issue_watchers_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] diff --git a/tests/integration/resources_permissions/test_milestones_resources.py b/tests/integration/resources_permissions/test_milestones_resources.py index 40a8c008..b9777ce1 100644 --- a/tests/integration/resources_permissions/test_milestones_resources.py +++ b/tests/integration/resources_permissions/test_milestones_resources.py @@ -1,6 +1,8 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json + +from taiga.projects import choices as project_choices from taiga.projects.milestones.serializers import MilestoneSerializer from taiga.projects.milestones.models import Milestone from taiga.projects.notifications.services import add_watcher @@ -43,6 +45,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -64,6 +71,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -77,9 +92,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_milestone = f.MilestoneFactory(project=m.public_project) m.private_milestone1 = f.MilestoneFactory(project=m.private_project1) m.private_milestone2 = f.MilestoneFactory(project=m.private_project2) + m.blocked_milestone = f.MilestoneFactory(project=m.blocked_project) return m @@ -88,6 +108,7 @@ def test_milestone_retrieve(client, data): public_url = reverse('milestones-detail', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-detail', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-detail', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-detail', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -103,12 +124,15 @@ def test_milestone_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_milestone_update(client, data): public_url = reverse('milestones-detail', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-detail', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-detail', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-detail', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -136,11 +160,18 @@ def test_milestone_update(client, data): results = helper_test_http_method(client, 'put', private_url2, milestone_data, users) assert results == [401, 403, 403, 200, 200] + milestone_data = MilestoneSerializer(data.blocked_milestone).data + milestone_data["name"] = "test" + milestone_data = json.dumps(milestone_data) + results = helper_test_http_method(client, 'put', blocked_url, milestone_data, users) + assert results == [401, 403, 403, 451, 451] + def test_milestone_delete(client, data): public_url = reverse('milestones-detail', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-detail', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-detail', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-detail', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -154,6 +185,8 @@ def test_milestone_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_milestone_list(client, data): @@ -175,14 +208,14 @@ def test_milestone_list(client, data): response = client.get(url) milestones_data = json.loads(response.content.decode('utf-8')) - assert len(milestones_data) == 3 + assert len(milestones_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) milestones_data = json.loads(response.content.decode('utf-8')) - assert len(milestones_data) == 3 + assert len(milestones_data) == 4 assert response.status_code == 200 @@ -227,11 +260,21 @@ def test_milestone_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users, lambda: Milestone.objects.all().delete()) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({ + "name": "test", + "estimated_start": "2014-12-10", + "estimated_finish": "2014-12-24", + "project": data.blocked_project.pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users, lambda: Milestone.objects.all().delete()) + assert results == [401, 403, 403, 451, 451] + def test_milestone_patch(client, data): public_url = reverse('milestones-detail', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-detail', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-detail', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-detail', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -253,11 +296,16 @@ def test_milestone_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"name": "test"}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_milestone_action_stats(client, data): public_url = reverse('milestones-stats', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-stats', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-stats', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-stats', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -276,11 +324,15 @@ def test_milestone_action_stats(client, data): results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] + def test_milestone_action_watch(client, data): public_url = reverse('milestones-watch', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-watch', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-watch', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-watch', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -296,12 +348,15 @@ def test_milestone_action_watch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_milestone_action_unwatch(client, data): public_url = reverse('milestones-unwatch', kwargs={"pk": data.public_milestone.pk}) private_url1 = reverse('milestones-unwatch', kwargs={"pk": data.private_milestone1.pk}) private_url2 = reverse('milestones-unwatch', kwargs={"pk": data.private_milestone2.pk}) + blocked_url = reverse('milestones-unwatch', kwargs={"pk": data.blocked_milestone.pk}) users = [ None, @@ -317,12 +372,15 @@ def test_milestone_action_unwatch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_milestone_watchers_list(client, data): public_url = reverse('milestone-watchers-list', kwargs={"resource_id": data.public_milestone.pk}) private_url1 = reverse('milestone-watchers-list', kwargs={"resource_id": data.private_milestone1.pk}) private_url2 = reverse('milestone-watchers-list', kwargs={"resource_id": data.private_milestone2.pk}) + blocked_url = reverse('milestone-watchers-list', kwargs={"resource_id": data.blocked_milestone.pk}) users = [ None, @@ -338,6 +396,8 @@ def test_milestone_watchers_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_milestone_watchers_retrieve(client, data): @@ -350,6 +410,9 @@ def test_milestone_watchers_retrieve(client, data): add_watcher(data.private_milestone2, data.project_owner) private_url2 = reverse('milestone-watchers-detail', kwargs={"resource_id": data.private_milestone2.pk, "pk": data.project_owner.pk}) + add_watcher(data.blocked_milestone, data.project_owner) + blocked_url = reverse('milestone-watchers-detail', kwargs={"resource_id": data.blocked_milestone.pk, + "pk": data.project_owner.pk}) users = [ None, @@ -365,3 +428,5 @@ def test_milestone_watchers_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] diff --git a/tests/integration/resources_permissions/test_modules_resources.py b/tests/integration/resources_permissions/test_modules_resources.py new file mode 100644 index 00000000..1f77d055 --- /dev/null +++ b/tests/integration/resources_permissions/test_modules_resources.py @@ -0,0 +1,209 @@ +import uuid + +from django.core.urlresolvers import reverse + +from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS +from taiga.base.utils import json + +from tests import factories as f +from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals +from taiga.projects import choices as project_choices +from taiga.projects.votes.services import add_vote +from taiga.projects.notifications.services import add_watcher +from taiga.projects.occ import OCCResourceMixin + +from unittest import mock + +import pytest +pytestmark = pytest.mark.django_db + + +def setup_module(module): + disconnect_signals() + + +def teardown_module(module): + reconnect_signals() + + +@pytest.fixture +def data(): + m = type("Models", (object,), {}) + + m.registered_user = f.UserFactory.create() + m.project_member_with_perms = f.UserFactory.create() + m.project_member_without_perms = f.UserFactory.create() + m.project_owner = f.UserFactory.create() + m.other_user = f.UserFactory.create() + + m.public_project = f.ProjectFactory(is_private=False, + anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)), + public_permissions=list(map(lambda x: x[0], USER_PERMISSIONS)), + owner=m.project_owner) + m.private_project1 = f.ProjectFactory(is_private=True, + anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)), + public_permissions=list(map(lambda x: x[0], USER_PERMISSIONS)), + owner=m.project_owner) + m.private_project2 = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) + + m.public_membership = f.MembershipFactory(project=m.public_project, + user=m.project_member_with_perms, + role__project=m.public_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + m.private_membership1 = f.MembershipFactory(project=m.private_project1, + user=m.project_member_with_perms, + role__project=m.private_project1, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.private_project1, + user=m.project_member_without_perms, + role__project=m.private_project1, + role__permissions=[]) + m.private_membership2 = f.MembershipFactory(project=m.private_project2, + user=m.project_member_with_perms, + role__project=m.private_project2, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.private_project2, + user=m.project_member_without_perms, + role__project=m.private_project2, + role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) + + f.MembershipFactory(project=m.public_project, + user=m.project_owner, + is_owner=True) + + f.MembershipFactory(project=m.private_project1, + user=m.project_owner, + is_owner=True) + + f.MembershipFactory(project=m.private_project2, + user=m.project_owner, + is_owner=True) + + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + + return m + + +def test_modules_retrieve(client, data): + public_url = reverse('projects-modules', kwargs={"pk": data.public_project.pk}) + private_url1 = reverse('projects-modules', kwargs={"pk": data.private_project1.pk}) + private_url2 = reverse('projects-modules', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-modules', kwargs={"pk": data.blocked_project.pk}) + + 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 == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'get', private_url1, None, users) + assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'get', private_url2, None, users) + assert results == [404, 404, 404, 403, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [404, 404, 404, 403, 200] + + +def test_modules_update(client, data): + public_url = reverse('projects-modules', kwargs={"pk": data.public_project.pk}) + private_url1 = reverse('projects-modules', kwargs={"pk": data.private_project1.pk}) + private_url2 = reverse('projects-modules', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-modules', kwargs={"pk": data.blocked_project.pk}) + + users = [ + None, + data.registered_user, + data.project_member_without_perms, + data.project_member_with_perms, + data.project_owner + ] + + with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"): + results = helper_test_http_method(client, 'put', public_url, {"att": "test"}, users) + assert results == [405, 405, 405, 405, 405] + + results = helper_test_http_method(client, 'put', private_url1, {"att": "test"}, users) + assert results == [405, 405, 405, 405, 405] + + results = helper_test_http_method(client, 'put', private_url2, {"att": "test"}, users) + assert results == [405, 405, 405, 405, 405] + + results = helper_test_http_method(client, 'put', blocked_url, {"att": "test"}, users) + assert results == [405, 405, 405, 405, 405] + + +def test_modules_delete(client, data): + public_url = reverse('projects-modules', kwargs={"pk": data.public_project.pk}) + private_url1 = reverse('projects-modules', kwargs={"pk": data.private_project1.pk}) + private_url2 = reverse('projects-modules', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-modules', kwargs={"pk": data.blocked_project.pk}) + + users = [ + None, + data.registered_user, + data.project_member_without_perms, + data.project_member_with_perms, + ] + + results = helper_test_http_method(client, 'delete', public_url, None, users) + assert results == [405, 405, 405, 405] + results = helper_test_http_method(client, 'delete', private_url1, None, users) + assert results == [405, 405, 405, 405] + results = helper_test_http_method(client, 'delete', private_url2, None, users) + assert results == [405, 405, 405, 405] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [405, 405, 405, 405] + + +def test_modules_patch(client, data): + public_url = reverse('projects-modules', kwargs={"pk": data.public_project.pk}) + private_url1 = reverse('projects-modules', kwargs={"pk": data.private_project1.pk}) + private_url2 = reverse('projects-modules', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-modules', kwargs={"pk": data.blocked_project.pk}) + + users = [ + None, + data.registered_user, + data.project_member_without_perms, + data.project_member_with_perms, + data.project_owner + ] + + with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"): + patch_data = json.dumps({"att": "test"}) + results = helper_test_http_method(client, 'patch', public_url, patch_data, users) + assert results == [401, 403, 403, 403, 204] + + patch_data = json.dumps({"att": "test"}) + results = helper_test_http_method(client, 'patch', private_url1, patch_data, users) + assert results == [401, 403, 403, 403, 204] + + patch_data = json.dumps({"att": "test"}) + results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) + assert results == [404, 404, 404, 403, 204] + + patch_data = json.dumps({"att": "test"}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [404, 404, 404, 403, 451] diff --git a/tests/integration/resources_permissions/test_projects_choices_resources.py b/tests/integration/resources_permissions/test_projects_choices_resources.py index c94ec9cc..1ffcf87a 100644 --- a/tests/integration/resources_permissions/test_projects_choices_resources.py +++ b/tests/integration/resources_permissions/test_projects_choices_resources.py @@ -1,6 +1,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects import serializers from taiga.users.serializers import RoleSerializer from taiga.permissions.permissions import MEMBERS_PERMISSIONS @@ -34,6 +35,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -61,6 +67,14 @@ def data(): email=m.project_member_without_perms.email, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -74,33 +88,44 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_points = f.PointsFactory(project=m.public_project) m.private_points1 = f.PointsFactory(project=m.private_project1) m.private_points2 = f.PointsFactory(project=m.private_project2) + m.blocked_points = f.PointsFactory(project=m.blocked_project) m.public_user_story_status = f.UserStoryStatusFactory(project=m.public_project) m.private_user_story_status1 = f.UserStoryStatusFactory(project=m.private_project1) m.private_user_story_status2 = f.UserStoryStatusFactory(project=m.private_project2) + m.blocked_user_story_status = f.UserStoryStatusFactory(project=m.blocked_project) m.public_task_status = f.TaskStatusFactory(project=m.public_project) m.private_task_status1 = f.TaskStatusFactory(project=m.private_project1) m.private_task_status2 = f.TaskStatusFactory(project=m.private_project2) + m.blocked_task_status = f.TaskStatusFactory(project=m.blocked_project) m.public_issue_status = f.IssueStatusFactory(project=m.public_project) m.private_issue_status1 = f.IssueStatusFactory(project=m.private_project1) m.private_issue_status2 = f.IssueStatusFactory(project=m.private_project2) + m.blocked_issue_status = f.IssueStatusFactory(project=m.blocked_project) m.public_issue_type = f.IssueTypeFactory(project=m.public_project) m.private_issue_type1 = f.IssueTypeFactory(project=m.private_project1) m.private_issue_type2 = f.IssueTypeFactory(project=m.private_project2) + m.blocked_issue_type = f.IssueTypeFactory(project=m.blocked_project) m.public_priority = f.PriorityFactory(project=m.public_project) m.private_priority1 = f.PriorityFactory(project=m.private_project1) m.private_priority2 = f.PriorityFactory(project=m.private_project2) + m.blocked_priority = f.PriorityFactory(project=m.blocked_project) m.public_severity = f.SeverityFactory(project=m.public_project) m.private_severity1 = f.SeverityFactory(project=m.private_project1) m.private_severity2 = f.SeverityFactory(project=m.private_project2) + m.blocked_severity = f.SeverityFactory(project=m.blocked_project) m.project_template = m.public_project.creation_template @@ -111,6 +136,7 @@ def test_roles_retrieve(client, data): public_url = reverse('roles-detail', kwargs={"pk": data.public_project.roles.all()[0].pk}) private1_url = reverse('roles-detail', kwargs={"pk": data.private_project1.roles.all()[0].pk}) private2_url = reverse('roles-detail', kwargs={"pk": data.private_project2.roles.all()[0].pk}) + blocked_url = reverse('roles-detail', kwargs={"pk": data.blocked_project.roles.all()[0].pk}) users = [ None, @@ -126,12 +152,15 @@ def test_roles_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_roles_update(client, data): public_url = reverse('roles-detail', kwargs={"pk": data.public_project.roles.all()[0].pk}) private1_url = reverse('roles-detail', kwargs={"pk": data.private_project1.roles.all()[0].pk}) private2_url = reverse('roles-detail', kwargs={"pk": data.private_project2.roles.all()[0].pk}) + blocked_url = reverse('roles-detail', kwargs={"pk": data.blocked_project.roles.all()[0].pk}) users = [ None, @@ -159,11 +188,18 @@ def test_roles_update(client, data): results = helper_test_http_method(client, 'put', private2_url, role_data, users) assert results == [401, 403, 403, 403, 200] + role_data = RoleSerializer(data.blocked_project.roles.all()[0]).data + role_data["name"] = "test" + role_data = json.dumps(role_data) + results = helper_test_http_method(client, 'put', blocked_url, role_data, users) + assert results == [401, 403, 403, 403, 451] + def test_roles_delete(client, data): public_url = reverse('roles-detail', kwargs={"pk": data.public_project.roles.all()[0].pk}) private1_url = reverse('roles-detail', kwargs={"pk": data.private_project1.roles.all()[0].pk}) private2_url = reverse('roles-detail', kwargs={"pk": data.private_project2.roles.all()[0].pk}) + blocked_url = reverse('roles-detail', kwargs={"pk": data.blocked_project.roles.all()[0].pk}) users = [ None, @@ -179,6 +215,8 @@ def test_roles_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_roles_list(client, data): @@ -204,13 +242,13 @@ def test_roles_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 5 + assert len(projects_data) == 7 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 5 + assert len(projects_data) == 7 assert response.status_code == 200 @@ -218,6 +256,7 @@ def test_roles_patch(client, data): public_url = reverse('roles-detail', kwargs={"pk": data.public_project.roles.all()[0].pk}) private1_url = reverse('roles-detail', kwargs={"pk": data.private_project1.roles.all()[0].pk}) private2_url = reverse('roles-detail', kwargs={"pk": data.private_project2.roles.all()[0].pk}) + blocked_url = reverse('roles-detail', kwargs={"pk": data.blocked_project.roles.all()[0].pk}) users = [ None, @@ -233,12 +272,15 @@ def test_roles_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_points_retrieve(client, data): public_url = reverse('points-detail', kwargs={"pk": data.public_points.pk}) private1_url = reverse('points-detail', kwargs={"pk": data.private_points1.pk}) private2_url = reverse('points-detail', kwargs={"pk": data.private_points2.pk}) + blocked_url = reverse('points-detail', kwargs={"pk": data.blocked_points.pk}) users = [ None, @@ -254,12 +296,15 @@ def test_points_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_points_update(client, data): public_url = reverse('points-detail', kwargs={"pk": data.public_points.pk}) private1_url = reverse('points-detail', kwargs={"pk": data.private_points1.pk}) private2_url = reverse('points-detail', kwargs={"pk": data.private_points2.pk}) + blocked_url = reverse('points-detail', kwargs={"pk": data.blocked_points.pk}) users = [ None, @@ -287,11 +332,18 @@ def test_points_update(client, data): results = helper_test_http_method(client, 'put', private2_url, points_data, users) assert results == [401, 403, 403, 403, 200] + points_data = serializers.PointsSerializer(data.blocked_points).data + points_data["name"] = "test" + points_data = json.dumps(points_data) + results = helper_test_http_method(client, 'put', blocked_url, points_data, users) + assert results == [401, 403, 403, 403, 451] + def test_points_delete(client, data): public_url = reverse('points-detail', kwargs={"pk": data.public_points.pk}) private1_url = reverse('points-detail', kwargs={"pk": data.private_points1.pk}) private2_url = reverse('points-detail', kwargs={"pk": data.private_points2.pk}) + blocked_url = reverse('points-detail', kwargs={"pk": data.blocked_points.pk}) users = [ None, @@ -307,6 +359,8 @@ def test_points_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_points_list(client, data): @@ -332,13 +386,13 @@ def test_points_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -346,6 +400,7 @@ def test_points_patch(client, data): public_url = reverse('points-detail', kwargs={"pk": data.public_points.pk}) private1_url = reverse('points-detail', kwargs={"pk": data.private_points1.pk}) private2_url = reverse('points-detail', kwargs={"pk": data.private_points2.pk}) + blocked_url = reverse('points-detail', kwargs={"pk": data.blocked_points.pk}) users = [ None, @@ -361,6 +416,8 @@ def test_points_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_points_action_bulk_update_order(client, data): @@ -395,11 +452,19 @@ def test_points_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_points": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_user_story_status_retrieve(client, data): public_url = reverse('userstory-statuses-detail', kwargs={"pk": data.public_user_story_status.pk}) private1_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status1.pk}) private2_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status2.pk}) + blocked_url = reverse('userstory-statuses-detail', kwargs={"pk": data.blocked_user_story_status.pk}) users = [ None, @@ -415,12 +480,15 @@ def test_user_story_status_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_user_story_status_update(client, data): public_url = reverse('userstory-statuses-detail', kwargs={"pk": data.public_user_story_status.pk}) private1_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status1.pk}) private2_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status2.pk}) + blocked_url = reverse('userstory-statuses-detail', kwargs={"pk": data.blocked_user_story_status.pk}) users = [ None, @@ -448,11 +516,18 @@ def test_user_story_status_update(client, data): results = helper_test_http_method(client, 'put', private2_url, user_story_status_data, users) assert results == [401, 403, 403, 403, 200] + user_story_status_data = serializers.UserStoryStatusSerializer(data.blocked_user_story_status).data + user_story_status_data["name"] = "test" + user_story_status_data = json.dumps(user_story_status_data) + results = helper_test_http_method(client, 'put', blocked_url, user_story_status_data, users) + assert results == [401, 403, 403, 403, 451] + def test_user_story_status_delete(client, data): public_url = reverse('userstory-statuses-detail', kwargs={"pk": data.public_user_story_status.pk}) private1_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status1.pk}) private2_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status2.pk}) + blocked_url = reverse('userstory-statuses-detail', kwargs={"pk": data.blocked_user_story_status.pk}) users = [ None, @@ -468,6 +543,9 @@ def test_user_story_status_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] + def test_user_story_status_list(client, data): @@ -493,13 +571,13 @@ def test_user_story_status_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -507,6 +585,7 @@ def test_user_story_status_patch(client, data): public_url = reverse('userstory-statuses-detail', kwargs={"pk": data.public_user_story_status.pk}) private1_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status1.pk}) private2_url = reverse('userstory-statuses-detail', kwargs={"pk": data.private_user_story_status2.pk}) + blocked_url = reverse('userstory-statuses-detail', kwargs={"pk": data.blocked_user_story_status.pk}) users = [ None, @@ -522,6 +601,8 @@ def test_user_story_status_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_user_story_status_action_bulk_update_order(client, data): @@ -556,11 +637,19 @@ def test_user_story_status_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_userstory_statuses": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_task_status_retrieve(client, data): public_url = reverse('task-statuses-detail', kwargs={"pk": data.public_task_status.pk}) private1_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status1.pk}) private2_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status2.pk}) + blocked_url = reverse('task-statuses-detail', kwargs={"pk": data.blocked_task_status.pk}) users = [ None, @@ -576,12 +665,15 @@ def test_task_status_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_status_update(client, data): public_url = reverse('task-statuses-detail', kwargs={"pk": data.public_task_status.pk}) private1_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status1.pk}) private2_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status2.pk}) + blocked_url = reverse('task-statuses-detail', kwargs={"pk": data.blocked_task_status.pk}) users = [ None, @@ -609,11 +701,18 @@ def test_task_status_update(client, data): results = helper_test_http_method(client, 'put', private2_url, task_status_data, users) assert results == [401, 403, 403, 403, 200] + task_status_data = serializers.TaskStatusSerializer(data.blocked_task_status).data + task_status_data["name"] = "test" + task_status_data = json.dumps(task_status_data) + results = helper_test_http_method(client, 'put', blocked_url, task_status_data, users) + assert results == [401, 403, 403, 403, 451] + def test_task_status_delete(client, data): public_url = reverse('task-statuses-detail', kwargs={"pk": data.public_task_status.pk}) private1_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status1.pk}) private2_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status2.pk}) + blocked_url = reverse('task-statuses-detail', kwargs={"pk": data.blocked_task_status.pk}) users = [ None, @@ -629,6 +728,9 @@ def test_task_status_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] + def test_task_status_list(client, data): @@ -654,13 +756,13 @@ def test_task_status_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -668,6 +770,7 @@ def test_task_status_patch(client, data): public_url = reverse('task-statuses-detail', kwargs={"pk": data.public_task_status.pk}) private1_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status1.pk}) private2_url = reverse('task-statuses-detail', kwargs={"pk": data.private_task_status2.pk}) + blocked_url = reverse('task-statuses-detail', kwargs={"pk": data.blocked_task_status.pk}) users = [ None, @@ -683,6 +786,8 @@ def test_task_status_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_task_status_action_bulk_update_order(client, data): @@ -717,11 +822,19 @@ def test_task_status_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_task_statuses": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_status_retrieve(client, data): public_url = reverse('issue-statuses-detail', kwargs={"pk": data.public_issue_status.pk}) private1_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status1.pk}) private2_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status2.pk}) + blocked_url = reverse('issue-statuses-detail', kwargs={"pk": data.blocked_issue_status.pk}) users = [ None, @@ -737,12 +850,15 @@ def test_issue_status_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_status_update(client, data): public_url = reverse('issue-statuses-detail', kwargs={"pk": data.public_issue_status.pk}) private1_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status1.pk}) private2_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status2.pk}) + blocked_url = reverse('issue-statuses-detail', kwargs={"pk": data.blocked_issue_status.pk}) users = [ None, @@ -770,11 +886,18 @@ def test_issue_status_update(client, data): results = helper_test_http_method(client, 'put', private2_url, issue_status_data, users) assert results == [401, 403, 403, 403, 200] + issue_status_data = serializers.IssueStatusSerializer(data.blocked_issue_status).data + issue_status_data["name"] = "test" + issue_status_data = json.dumps(issue_status_data) + results = helper_test_http_method(client, 'put', blocked_url, issue_status_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_status_delete(client, data): public_url = reverse('issue-statuses-detail', kwargs={"pk": data.public_issue_status.pk}) private1_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status1.pk}) private2_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status2.pk}) + blocked_url = reverse('issue-statuses-detail', kwargs={"pk": data.blocked_issue_status.pk}) users = [ None, @@ -790,6 +913,8 @@ def test_issue_status_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_issue_status_list(client, data): @@ -815,13 +940,13 @@ def test_issue_status_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -829,6 +954,7 @@ def test_issue_status_patch(client, data): public_url = reverse('issue-statuses-detail', kwargs={"pk": data.public_issue_status.pk}) private1_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status1.pk}) private2_url = reverse('issue-statuses-detail', kwargs={"pk": data.private_issue_status2.pk}) + blocked_url = reverse('issue-statuses-detail', kwargs={"pk": data.blocked_issue_status.pk}) users = [ None, @@ -844,6 +970,8 @@ def test_issue_status_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_issue_status_action_bulk_update_order(client, data): @@ -878,11 +1006,19 @@ def test_issue_status_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_issue_statuses": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_type_retrieve(client, data): public_url = reverse('issue-types-detail', kwargs={"pk": data.public_issue_type.pk}) private1_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type1.pk}) private2_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type2.pk}) + blocked_url = reverse('issue-types-detail', kwargs={"pk": data.blocked_issue_type.pk}) users = [ None, @@ -898,12 +1034,15 @@ def test_issue_type_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_issue_type_update(client, data): public_url = reverse('issue-types-detail', kwargs={"pk": data.public_issue_type.pk}) private1_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type1.pk}) private2_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type2.pk}) + blocked_url = reverse('issue-types-detail', kwargs={"pk": data.blocked_issue_type.pk}) users = [ None, @@ -931,11 +1070,18 @@ def test_issue_type_update(client, data): results = helper_test_http_method(client, 'put', private2_url, issue_type_data, users) assert results == [401, 403, 403, 403, 200] + issue_type_data = serializers.IssueTypeSerializer(data.blocked_issue_type).data + issue_type_data["name"] = "test" + issue_type_data = json.dumps(issue_type_data) + results = helper_test_http_method(client, 'put', blocked_url, issue_type_data, users) + assert results == [401, 403, 403, 403, 451] + def test_issue_type_delete(client, data): public_url = reverse('issue-types-detail', kwargs={"pk": data.public_issue_type.pk}) private1_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type1.pk}) private2_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type2.pk}) + blocked_url = reverse('issue-types-detail', kwargs={"pk": data.blocked_issue_type.pk}) users = [ None, @@ -951,6 +1097,8 @@ def test_issue_type_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_issue_type_list(client, data): @@ -976,13 +1124,13 @@ def test_issue_type_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -990,6 +1138,7 @@ def test_issue_type_patch(client, data): public_url = reverse('issue-types-detail', kwargs={"pk": data.public_issue_type.pk}) private1_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type1.pk}) private2_url = reverse('issue-types-detail', kwargs={"pk": data.private_issue_type2.pk}) + blocked_url = reverse('issue-types-detail', kwargs={"pk": data.blocked_issue_type.pk}) users = [ None, @@ -1005,6 +1154,8 @@ def test_issue_type_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_issue_type_action_bulk_update_order(client, data): @@ -1039,11 +1190,19 @@ def test_issue_type_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_issue_types": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_priority_retrieve(client, data): public_url = reverse('priorities-detail', kwargs={"pk": data.public_priority.pk}) private1_url = reverse('priorities-detail', kwargs={"pk": data.private_priority1.pk}) private2_url = reverse('priorities-detail', kwargs={"pk": data.private_priority2.pk}) + blocked_url = reverse('priorities-detail', kwargs={"pk": data.blocked_priority.pk}) users = [ None, @@ -1059,12 +1218,15 @@ def test_priority_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_priority_update(client, data): public_url = reverse('priorities-detail', kwargs={"pk": data.public_priority.pk}) private1_url = reverse('priorities-detail', kwargs={"pk": data.private_priority1.pk}) private2_url = reverse('priorities-detail', kwargs={"pk": data.private_priority2.pk}) + blocked_url = reverse('priorities-detail', kwargs={"pk": data.blocked_priority.pk}) users = [ None, @@ -1092,11 +1254,17 @@ def test_priority_update(client, data): results = helper_test_http_method(client, 'put', private2_url, priority_data, users) assert results == [401, 403, 403, 403, 200] + priority_data = serializers.PrioritySerializer(data.blocked_priority).data + priority_data["name"] = "test" + priority_data = json.dumps(priority_data) + results = helper_test_http_method(client, 'put', blocked_url, priority_data, users) + assert results == [401, 403, 403, 403, 451] def test_priority_delete(client, data): public_url = reverse('priorities-detail', kwargs={"pk": data.public_priority.pk}) private1_url = reverse('priorities-detail', kwargs={"pk": data.private_priority1.pk}) private2_url = reverse('priorities-detail', kwargs={"pk": data.private_priority2.pk}) + blocked_url = reverse('priorities-detail', kwargs={"pk": data.blocked_priority.pk}) users = [ None, @@ -1112,6 +1280,8 @@ def test_priority_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_priority_list(client, data): @@ -1137,13 +1307,13 @@ def test_priority_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -1151,6 +1321,7 @@ def test_priority_patch(client, data): public_url = reverse('priorities-detail', kwargs={"pk": data.public_priority.pk}) private1_url = reverse('priorities-detail', kwargs={"pk": data.private_priority1.pk}) private2_url = reverse('priorities-detail', kwargs={"pk": data.private_priority2.pk}) + blocked_url = reverse('priorities-detail', kwargs={"pk": data.blocked_priority.pk}) users = [ None, @@ -1166,6 +1337,8 @@ def test_priority_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_priority_action_bulk_update_order(client, data): @@ -1200,11 +1373,19 @@ def test_priority_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_priorities": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_severity_retrieve(client, data): public_url = reverse('severities-detail', kwargs={"pk": data.public_severity.pk}) private1_url = reverse('severities-detail', kwargs={"pk": data.private_severity1.pk}) private2_url = reverse('severities-detail', kwargs={"pk": data.private_severity2.pk}) + blocked_url = reverse('severities-detail', kwargs={"pk": data.blocked_severity.pk}) users = [ None, @@ -1220,12 +1401,15 @@ def test_severity_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_severity_update(client, data): public_url = reverse('severities-detail', kwargs={"pk": data.public_severity.pk}) private1_url = reverse('severities-detail', kwargs={"pk": data.private_severity1.pk}) private2_url = reverse('severities-detail', kwargs={"pk": data.private_severity2.pk}) + blocked_url = reverse('severities-detail', kwargs={"pk": data.blocked_severity.pk}) users = [ None, @@ -1253,11 +1437,18 @@ def test_severity_update(client, data): results = helper_test_http_method(client, 'put', private2_url, severity_data, users) assert results == [401, 403, 403, 403, 200] + severity_data = serializers.SeveritySerializer(data.blocked_severity).data + severity_data["name"] = "test" + severity_data = json.dumps(severity_data) + results = helper_test_http_method(client, 'put', blocked_url, severity_data, users) + assert results == [401, 403, 403, 403, 451] + def test_severity_delete(client, data): public_url = reverse('severities-detail', kwargs={"pk": data.public_severity.pk}) private1_url = reverse('severities-detail', kwargs={"pk": data.private_severity1.pk}) private2_url = reverse('severities-detail', kwargs={"pk": data.private_severity2.pk}) + blocked_url = reverse('severities-detail', kwargs={"pk": data.blocked_severity.pk}) users = [ None, @@ -1273,6 +1464,8 @@ def test_severity_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_severity_list(client, data): @@ -1298,13 +1491,13 @@ def test_severity_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 @@ -1312,6 +1505,7 @@ def test_severity_patch(client, data): public_url = reverse('severities-detail', kwargs={"pk": data.public_severity.pk}) private1_url = reverse('severities-detail', kwargs={"pk": data.private_severity1.pk}) private2_url = reverse('severities-detail', kwargs={"pk": data.private_severity2.pk}) + blocked_url = reverse('severities-detail', kwargs={"pk": data.blocked_severity.pk}) users = [ None, @@ -1327,6 +1521,8 @@ def test_severity_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_severity_action_bulk_update_order(client, data): @@ -1361,11 +1557,19 @@ def test_severity_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 403, 204] + post_data = json.dumps({ + "bulk_severities": [(1, 2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] + def test_membership_retrieve(client, data): public_url = reverse('memberships-detail', kwargs={"pk": data.public_membership.pk}) private1_url = reverse('memberships-detail', kwargs={"pk": data.private_membership1.pk}) private2_url = reverse('memberships-detail', kwargs={"pk": data.private_membership2.pk}) + blocked_url = reverse('memberships-detail', kwargs={"pk": data.blocked_membership.pk}) users = [ None, @@ -1381,12 +1585,15 @@ def test_membership_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_membership_update(client, data): public_url = reverse('memberships-detail', kwargs={"pk": data.public_membership.pk}) private1_url = reverse('memberships-detail', kwargs={"pk": data.private_membership1.pk}) private2_url = reverse('memberships-detail', kwargs={"pk": data.private_membership2.pk}) + blocked_url = reverse('memberships-detail', kwargs={"pk": data.blocked_membership.pk}) users = [ None, @@ -1414,11 +1621,18 @@ def test_membership_update(client, data): results = helper_test_http_method(client, 'put', private2_url, membership_data, users) assert results == [401, 403, 403, 403, 200] + membership_data = serializers.MembershipSerializer(data.blocked_membership).data + membership_data["token"] = "test" + membership_data = json.dumps(membership_data) + results = helper_test_http_method(client, 'put', blocked_url, membership_data, users) + assert results == [401, 403, 403, 403, 451] + def test_membership_delete(client, data): public_url = reverse('memberships-detail', kwargs={"pk": data.public_membership.pk}) private1_url = reverse('memberships-detail', kwargs={"pk": data.private_membership1.pk}) private2_url = reverse('memberships-detail', kwargs={"pk": data.private_membership2.pk}) + blocked_url = reverse('memberships-detail', kwargs={"pk": data.blocked_membership.pk}) users = [ None, @@ -1434,6 +1648,8 @@ def test_membership_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_membership_list(client, data): @@ -1459,13 +1675,13 @@ def test_membership_list(client, data): client.login(data.project_member_with_perms) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 8 + assert len(projects_data) == 11 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 8 + assert len(projects_data) == 11 assert response.status_code == 200 @@ -1473,6 +1689,7 @@ def test_membership_patch(client, data): public_url = reverse('memberships-detail', kwargs={"pk": data.public_membership.pk}) private1_url = reverse('memberships-detail', kwargs={"pk": data.private_membership1.pk}) private2_url = reverse('memberships-detail', kwargs={"pk": data.private_membership2.pk}) + blocked_url = reverse('memberships-detail', kwargs={"pk": data.blocked_membership.pk}) users = [ None, @@ -1488,6 +1705,8 @@ def test_membership_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_membership_create(client, data): @@ -1522,6 +1741,13 @@ def test_membership_create(client, data): results = helper_test_http_method(client, 'post', url, membership_data, users) assert results == [401, 403, 403, 403, 201] + membership_data = serializers.MembershipSerializer(data.blocked_membership).data + membership_data["id"] = None + membership_data["email"] = "test4@test.com" + membership_data = json.dumps(membership_data) + results = helper_test_http_method(client, 'post', url, membership_data, users) + assert results == [401, 403, 403, 403, 451] + def test_membership_action_bulk_create(client, data): url = reverse('memberships-bulk-create') @@ -1567,15 +1793,27 @@ def test_membership_action_bulk_create(client, data): results = helper_test_http_method(client, 'post', url, bulk_data, users) assert results == [401, 403, 403, 403, 200] + bulk_data = { + "project_id": data.blocked_project.id, + "bulk_memberships": [ + {"role_id": data.private_membership2.role.pk, "email": "test1@test.com"}, + {"role_id": data.private_membership2.role.pk, "email": "test2@test.com"}, + ] + } + bulk_data = json.dumps(bulk_data) + results = helper_test_http_method(client, 'post', url, bulk_data, users) + assert results == [401, 403, 403, 403, 451] def test_membership_action_resend_invitation(client, data): public_invitation = f.InvitationFactory(project=data.public_project, role__project=data.public_project) private_invitation1 = f.InvitationFactory(project=data.private_project1, role__project=data.private_project1) private_invitation2 = f.InvitationFactory(project=data.private_project2, role__project=data.private_project2) + blocked_invitation = f.InvitationFactory(project=data.blocked_project, role__project=data.blocked_project) public_url = reverse('memberships-resend-invitation', kwargs={"pk": public_invitation.pk}) private1_url = reverse('memberships-resend-invitation', kwargs={"pk": private_invitation1.pk}) private2_url = reverse('memberships-resend-invitation', kwargs={"pk": private_invitation2.pk}) + blocked_url = reverse('memberships-resend-invitation', kwargs={"pk": blocked_invitation.pk}) users = [ None, @@ -1594,6 +1832,9 @@ def test_membership_action_resend_invitation(client, data): results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 404, 403, 204] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 404, 403, 451] + def test_project_template_retrieve(client, data): url = reverse('project-templates-detail', kwargs={"pk": data.project_template.pk}) diff --git a/tests/integration/resources_permissions/test_projects_resource.py b/tests/integration/resources_permissions/test_projects_resource.py index 023fee94..f90c10b7 100644 --- a/tests/integration/resources_permissions/test_projects_resource.py +++ b/tests/integration/resources_permissions/test_projects_resource.py @@ -2,6 +2,7 @@ from django.core.urlresolvers import reverse from django.apps import apps from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.serializers import ProjectDetailSerializer from taiga.permissions.permissions import MEMBERS_PERMISSIONS @@ -33,6 +34,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) f.RoleFactory(project=m.public_project) @@ -52,6 +58,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + m.membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -65,6 +79,10 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + ContentType = apps.get_model("contenttypes", "ContentType") Project = apps.get_model("projects", "Project") @@ -76,6 +94,8 @@ def data(): f.LikeFactory(content_type=project_ct, object_id=m.private_project1.pk, user=m.project_owner) f.LikeFactory(content_type=project_ct, object_id=m.private_project2.pk, user=m.project_member_with_perms) f.LikeFactory(content_type=project_ct, object_id=m.private_project2.pk, user=m.project_owner) + f.LikeFactory(content_type=project_ct, object_id=m.blocked_project.pk, user=m.project_member_with_perms) + f.LikeFactory(content_type=project_ct, object_id=m.blocked_project.pk, user=m.project_owner) return m @@ -84,6 +104,7 @@ def test_project_retrieve(client, data): public_url = reverse('projects-detail', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-detail', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-detail', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-detail', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -98,15 +119,13 @@ def test_project_retrieve(client, data): assert results == [200, 200, 200, 200] results = helper_test_http_method(client, 'get', private2_url, None, users) assert results == [401, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 200, 200] def test_project_update(client, data): url = reverse('projects-detail', kwargs={"pk": data.private_project2.pk}) - - project_data = ProjectDetailSerializer(data.private_project2).data - project_data["is_private"] = False - - project_data = json.dumps(project_data) + blocked_url = reverse('projects-detail', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -115,12 +134,20 @@ def test_project_update(client, data): data.project_owner ] - results = helper_test_http_method(client, 'put', url, project_data, users) + project_data = ProjectDetailSerializer(data.private_project2).data + project_data["is_private"] = False + results = helper_test_http_method(client, 'put', url, json.dumps(project_data), users) assert results == [401, 403, 403, 200] + project_data = ProjectDetailSerializer(data.blocked_project).data + project_data["is_private"] = False + results = helper_test_http_method(client, 'put', blocked_url, json.dumps(project_data), users) + assert results == [401, 403, 403, 451] + def test_project_delete(client, data): url = reverse('projects-detail', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-detail', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -131,6 +158,9 @@ def test_project_delete(client, data): results = helper_test_http_method(client, 'delete', url, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] + def test_project_list(client, data): url = reverse('projects-list') @@ -151,19 +181,20 @@ def test_project_list(client, data): response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) projects_data = json.loads(response.content.decode('utf-8')) - assert len(projects_data) == 3 + assert len(projects_data) == 4 assert response.status_code == 200 def test_project_patch(client, data): url = reverse('projects-detail', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-detail', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -172,14 +203,19 @@ def test_project_patch(client, data): data.project_owner ] data = json.dumps({"is_private": False}) + results = helper_test_http_method(client, 'patch', url, data, users) assert results == [401, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, data, users) + assert results == [401, 403, 403, 451] + def test_project_action_stats(client, data): public_url = reverse('projects-stats', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-stats', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-stats', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-stats', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -193,12 +229,15 @@ def test_project_action_stats(client, data): assert results == [200, 200, 200, 200] results = helper_test_http_method(client, 'get', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [404, 404, 200, 200] def test_project_action_issues_stats(client, data): public_url = reverse('projects-issues-stats', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-issues-stats', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-issues-stats', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-issues-stats', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -212,12 +251,15 @@ def test_project_action_issues_stats(client, data): assert results == [200, 200, 200, 200] results = helper_test_http_method(client, 'get', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [404, 404, 200, 200] def test_project_action_like(client, data): public_url = reverse('projects-like', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-like', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-like', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-like', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -231,12 +273,15 @@ def test_project_action_like(client, data): assert results == [401, 200, 200, 200] results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451, 451] def test_project_action_unlike(client, data): public_url = reverse('projects-unlike', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-unlike', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-unlike', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-unlike', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -250,12 +295,15 @@ def test_project_action_unlike(client, data): assert results == [401, 200, 200, 200] results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451, 451] def test_project_fans_list(client, data): public_url = reverse('project-fans-list', kwargs={"resource_id": data.public_project.pk}) private1_url = reverse('project-fans-list', kwargs={"resource_id": data.private_project1.pk}) private2_url = reverse('project-fans-list', kwargs={"resource_id": data.private_project2.pk}) + blocked_url = reverse('project-fans-list', kwargs={"resource_id": data.blocked_project.pk}) users = [ None, @@ -271,6 +319,8 @@ def test_project_fans_list(client, data): assert results == [(200, 2), (200, 2), (200, 2), (200, 2), (200, 2)] results = helper_test_http_method_and_count(client, 'get', private2_url, None, users) assert results == [(401, 0), (403, 0), (403, 0), (200, 2), (200, 2)] + results = helper_test_http_method_and_count(client, 'get', blocked_url, None, users) + assert results == [(401, 0), (403, 0), (403, 0), (200, 2), (200, 2)] def test_project_fans_retrieve(client, data): @@ -280,6 +330,8 @@ def test_project_fans_retrieve(client, data): "pk": data.project_owner.pk}) private2_url = reverse('project-fans-detail', kwargs={"resource_id": data.private_project2.pk, "pk": data.project_owner.pk}) + blocked_url = reverse('project-fans-detail', kwargs={"resource_id": data.blocked_project.pk, + "pk": data.project_owner.pk}) users = [ None, @@ -295,12 +347,15 @@ def test_project_fans_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_project_watchers_list(client, data): public_url = reverse('project-watchers-list', kwargs={"resource_id": data.public_project.pk}) private1_url = reverse('project-watchers-list', kwargs={"resource_id": data.private_project1.pk}) private2_url = reverse('project-watchers-list', kwargs={"resource_id": data.private_project2.pk}) + blocked_url = reverse('project-watchers-list', kwargs={"resource_id": data.blocked_project.pk}) users = [ None, @@ -316,6 +371,8 @@ def test_project_watchers_list(client, data): assert results == [(200, 3), (200, 3), (200, 3), (200, 3), (200, 3)] results = helper_test_http_method_and_count(client, 'get', private2_url, None, users) assert results == [(401, 0), (403, 0), (403, 0), (200, 3), (200, 3)] + results = helper_test_http_method_and_count(client, 'get', blocked_url, None, users) + assert results == [(401, 0), (403, 0), (403, 0), (200, 3), (200, 3)] def test_project_watchers_retrieve(client, data): @@ -325,6 +382,8 @@ def test_project_watchers_retrieve(client, data): "pk": data.project_owner.pk}) private2_url = reverse('project-watchers-detail', kwargs={"resource_id": data.private_project2.pk, "pk": data.project_owner.pk}) + blocked_url = reverse('project-watchers-detail', kwargs={"resource_id": data.blocked_project.pk, + "pk": data.project_owner.pk}) users = [ None, @@ -340,6 +399,8 @@ def test_project_watchers_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_project_action_create_template(client, data): @@ -401,6 +462,7 @@ def test_regenerate_userstories_csv_uuid(client, data): public_url = reverse('projects-regenerate-userstories-csv-uuid', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-regenerate-userstories-csv-uuid', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-regenerate-userstories-csv-uuid', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-regenerate-userstories-csv-uuid', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -417,11 +479,15 @@ def test_regenerate_userstories_csv_uuid(client, data): results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 403, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 403, 451] + def test_regenerate_tasks_csv_uuid(client, data): public_url = reverse('projects-regenerate-tasks-csv-uuid', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-regenerate-tasks-csv-uuid', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-regenerate-tasks-csv-uuid', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-regenerate-tasks-csv-uuid', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -438,11 +504,15 @@ def test_regenerate_tasks_csv_uuid(client, data): results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 403, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 403, 451] + def test_regenerate_issues_csv_uuid(client, data): public_url = reverse('projects-regenerate-issues-csv-uuid', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-regenerate-issues-csv-uuid', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-regenerate-issues-csv-uuid', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-regenerate-issues-csv-uuid', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -459,11 +529,15 @@ def test_regenerate_issues_csv_uuid(client, data): results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 403, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 403, 451] + def test_project_action_watch(client, data): public_url = reverse('projects-watch', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-watch', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-watch', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-watch', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -477,12 +551,15 @@ def test_project_action_watch(client, data): assert results == [401, 200, 200, 200] results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451, 451] def test_project_action_unwatch(client, data): public_url = reverse('projects-unwatch', kwargs={"pk": data.public_project.pk}) private1_url = reverse('projects-unwatch', kwargs={"pk": data.private_project1.pk}) private2_url = reverse('projects-unwatch', kwargs={"pk": data.private_project2.pk}) + blocked_url = reverse('projects-unwatch', kwargs={"pk": data.blocked_project.pk}) users = [ None, @@ -496,3 +573,5 @@ def test_project_action_unwatch(client, data): assert results == [401, 200, 200, 200] results = helper_test_http_method(client, 'post', private2_url, None, users) assert results == [404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451, 451] diff --git a/tests/integration/resources_permissions/test_tasks_custom_attributes_resource.py b/tests/integration/resources_permissions/test_tasks_custom_attributes_resource.py index 05b5f49d..b02a34a6 100644 --- a/tests/integration/resources_permissions/test_tasks_custom_attributes_resource.py +++ b/tests/integration/resources_permissions/test_tasks_custom_attributes_resource.py @@ -19,6 +19,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.custom_attributes import serializers from taiga.permissions.permissions import (MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS) @@ -52,6 +53,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -81,6 +87,17 @@ def data(): role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + email=m.project_member_with_perms.email, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + email=m.project_member_without_perms.email, + role__project=m.blocked_project, + role__permissions=[]) + f.MembershipFactory(project=m.public_project, user=m.project_owner, is_owner=True) @@ -93,9 +110,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_task_ca = f.TaskCustomAttributeFactory(project=m.public_project) m.private_task_ca1 = f.TaskCustomAttributeFactory(project=m.private_project1) m.private_task_ca2 = f.TaskCustomAttributeFactory(project=m.private_project2) + m.blocked_task_ca = f.TaskCustomAttributeFactory(project=m.blocked_project) m.public_task = f.TaskFactory(project=m.public_project, status__project=m.public_project, @@ -109,10 +131,15 @@ def data(): status__project=m.private_project2, milestone__project=m.private_project2, user_story__project=m.private_project2) + m.blocked_task = f.TaskFactory(project=m.blocked_project, + status__project=m.blocked_project, + milestone__project=m.blocked_project, + user_story__project=m.blocked_project) m.public_task_cav = m.public_task.custom_attributes_values m.private_task_cav1 = m.private_task1.custom_attributes_values m.private_task_cav2 = m.private_task2.custom_attributes_values + m.blocked_task_cav = m.blocked_task.custom_attributes_values return m @@ -125,6 +152,7 @@ def test_task_custom_attribute_retrieve(client, data): public_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.public_task_ca.pk}) private1_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca1.pk}) private2_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca2.pk}) + blocked_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.blocked_task_ca.pk}) users = [ None, @@ -140,12 +168,15 @@ def test_task_custom_attribute_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_custom_attribute_create(client, data): public_url = reverse('task-custom-attributes-list') private1_url = reverse('task-custom-attributes-list') private2_url = reverse('task-custom-attributes-list') + blocked_url = reverse('task-custom-attributes-list') users = [ None, @@ -170,11 +201,17 @@ def test_task_custom_attribute_create(client, data): results = helper_test_http_method(client, 'post', private2_url, task_ca_data, users) assert results == [401, 403, 403, 403, 201] + task_ca_data = {"name": "test-new", "project": data.blocked_project.id} + task_ca_data = json.dumps(task_ca_data) + results = helper_test_http_method(client, 'post', blocked_url, task_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_task_custom_attribute_update(client, data): public_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.public_task_ca.pk}) private1_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca1.pk}) private2_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca2.pk}) + blocked_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.blocked_task_ca.pk}) users = [ None, @@ -202,11 +239,18 @@ def test_task_custom_attribute_update(client, data): results = helper_test_http_method(client, 'put', private2_url, task_ca_data, users) assert results == [401, 403, 403, 403, 200] + task_ca_data = serializers.TaskCustomAttributeSerializer(data.blocked_task_ca).data + task_ca_data["name"] = "test" + task_ca_data = json.dumps(task_ca_data) + results = helper_test_http_method(client, 'put', private2_url, task_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_task_custom_attribute_delete(client, data): public_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.public_task_ca.pk}) private1_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca1.pk}) private2_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca2.pk}) + blocked_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.blocked_task_ca.pk}) users = [ None, @@ -222,6 +266,9 @@ def test_task_custom_attribute_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] + def test_task_custom_attribute_list(client, data): @@ -243,12 +290,12 @@ def test_task_custom_attribute_list(client, data): client.login(data.project_member_with_perms) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 @@ -256,6 +303,7 @@ def test_task_custom_attribute_patch(client, data): public_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.public_task_ca.pk}) private1_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca1.pk}) private2_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.private_task_ca2.pk}) + blocked_url = reverse('task-custom-attributes-detail', kwargs={"pk": data.blocked_task_ca.pk}) users = [ None, @@ -271,6 +319,8 @@ def test_task_custom_attribute_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_task_custom_attribute_action_bulk_update_order(client, data): @@ -305,6 +355,12 @@ def test_task_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] + post_data = json.dumps({ + "bulk_task_custom_attributes": [(1,2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] ######################################################### # Task Custom Attribute @@ -315,6 +371,7 @@ def test_task_custom_attributes_values_retrieve(client, data): public_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.public_task.pk}) private_url1 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task1.pk}) private_url2 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task2.pk}) + blocked_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.blocked_task.pk}) users = [ None, @@ -330,12 +387,15 @@ def test_task_custom_attributes_values_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_custom_attributes_values_update(client, data): public_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.public_task.pk}) private_url1 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task1.pk}) private_url2 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task2.pk}) + blocked_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.blocked_task.pk}) users = [ None, @@ -363,11 +423,18 @@ def test_task_custom_attributes_values_update(client, data): results = helper_test_http_method(client, 'put', private_url2, task_data, users) assert results == [401, 403, 403, 200, 200] + task_data = serializers.TaskCustomAttributesValuesSerializer(data.blocked_task_cav).data + task_data["attributes_values"] = {str(data.blocked_task_ca.pk): "test"} + task_data = json.dumps(task_data) + results = helper_test_http_method(client, 'put', blocked_url, task_data, users) + assert results == [401, 403, 403, 451, 451] + def test_task_custom_attributes_values_patch(client, data): public_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.public_task.pk}) private_url1 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task1.pk}) private_url2 = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.private_task2.pk}) + blocked_url = reverse('task-custom-attributes-values-detail', kwargs={"task_id": data.blocked_task.pk}) users = [ None, @@ -391,3 +458,8 @@ def test_task_custom_attributes_values_patch(client, data): "version": data.private_task2.version}) results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + + patch_data = json.dumps({"attributes_values": {str(data.blocked_task_ca.pk): "test"}, + "version": data.blocked_task.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] diff --git a/tests/integration/resources_permissions/test_tasks_resources.py b/tests/integration/resources_permissions/test_tasks_resources.py index 4a871e8e..88a130c8 100644 --- a/tests/integration/resources_permissions/test_tasks_resources.py +++ b/tests/integration/resources_permissions/test_tasks_resources.py @@ -3,6 +3,7 @@ import uuid from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.tasks.serializers import TaskSerializer from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS from taiga.projects.occ import OCCResourceMixin @@ -51,6 +52,12 @@ def data(): public_permissions=[], owner=m.project_owner, tasks_csv_uuid=uuid.uuid4().hex) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + tasks_csv_uuid=uuid.uuid4().hex, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -72,6 +79,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -85,9 +100,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + milestone_public_task = f.MilestoneFactory(project=m.public_project) milestone_private_task1 = f.MilestoneFactory(project=m.private_project1) milestone_private_task2 = f.MilestoneFactory(project=m.private_project2) + milestone_blocked_task = f.MilestoneFactory(project=m.blocked_project) m.public_task = f.TaskFactory(project=m.public_project, status__project=m.public_project, @@ -104,6 +124,11 @@ def data(): milestone=milestone_private_task2, user_story__project=m.private_project2, user_story__milestone=milestone_private_task2) + m.blocked_task = f.TaskFactory(project=m.blocked_project, + status__project=m.blocked_project, + milestone=milestone_blocked_task, + user_story__project=m.blocked_project, + user_story__milestone=milestone_blocked_task) m.public_project.default_task_status = m.public_task.status m.public_project.save() @@ -111,6 +136,8 @@ def data(): m.private_project1.save() m.private_project2.default_task_status = m.private_task2.status m.private_project2.save() + m.blocked_project.default_task_status = m.blocked_task.status + m.blocked_project.save() return m @@ -119,6 +146,7 @@ def test_task_retrieve(client, data): public_url = reverse('tasks-detail', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-detail', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-detail', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-detail', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -134,12 +162,15 @@ def test_task_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_update(client, data): public_url = reverse('tasks-detail', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-detail', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-detail', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-detail', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -168,6 +199,12 @@ def test_task_update(client, data): results = helper_test_http_method(client, 'put', private_url2, task_data, users) assert results == [401, 403, 403, 200, 200] + task_data = TaskSerializer(data.blocked_task).data + task_data["subject"] = "test" + task_data = json.dumps(task_data) + results = helper_test_http_method(client, 'put', blocked_url, task_data, users) + assert results == [401, 403, 403, 451, 451] + def test_task_update_with_project_change(client): user1 = f.UserFactory.create() @@ -268,6 +305,7 @@ def test_task_delete(client, data): public_url = reverse('tasks-detail', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-detail', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-detail', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-detail', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -281,6 +319,8 @@ def test_task_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_task_list(client, data): @@ -302,14 +342,14 @@ def test_task_list(client, data): response = client.get(url) tasks_data = json.loads(response.content.decode('utf-8')) - assert len(tasks_data) == 3 + assert len(tasks_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) tasks_data = json.loads(response.content.decode('utf-8')) - assert len(tasks_data) == 3 + assert len(tasks_data) == 4 assert response.status_code == 200 @@ -351,11 +391,21 @@ def test_task_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({ + "subject": "test", + "ref": 3, + "project": data.blocked_project.pk, + "status": data.blocked_project.task_statuses.all()[0].pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users) + assert results == [401, 403, 403, 451, 451] + def test_task_patch(client, data): public_url = reverse('tasks-detail', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-detail', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-detail', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-detail', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -378,6 +428,10 @@ def test_task_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"subject": "test", "version": data.blocked_task.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_task_action_bulk_create(client, data): url = reverse('tasks-bulk-create') @@ -417,11 +471,21 @@ def test_task_action_bulk_create(client, data): results = helper_test_http_method(client, 'post', url, bulk_data, users) assert results == [401, 403, 403, 200, 200] + bulk_data = json.dumps({ + "bulk_tasks": "test1\ntest2", + "us_id": data.blocked_task.user_story.pk, + "project_id": data.blocked_task.project.pk, + "sprint_id": data.blocked_task.milestone.pk, + }) + results = helper_test_http_method(client, 'post', url, bulk_data, users) + assert results == [401, 403, 403, 451, 451] + def test_task_action_upvote(client, data): public_url = reverse('tasks-upvote', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-upvote', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-upvote', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-upvote', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -437,12 +501,15 @@ def test_task_action_upvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_task_action_downvote(client, data): public_url = reverse('tasks-downvote', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-downvote', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-downvote', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-downvote', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -458,12 +525,15 @@ def test_task_action_downvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_task_voters_list(client, data): public_url = reverse('task-voters-list', kwargs={"resource_id": data.public_task.pk}) private_url1 = reverse('task-voters-list', kwargs={"resource_id": data.private_task1.pk}) private_url2 = reverse('task-voters-list', kwargs={"resource_id": data.private_task2.pk}) + blocked_url = reverse('task-voters-list', kwargs={"resource_id": data.blocked_task.pk}) users = [ None, @@ -479,6 +549,8 @@ def test_task_voters_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_voters_retrieve(client, data): @@ -492,6 +564,10 @@ def test_task_voters_retrieve(client, data): private_url2 = reverse('task-voters-detail', kwargs={"resource_id": data.private_task2.pk, "pk": data.project_owner.pk}) + add_vote(data.blocked_task, data.project_owner) + blocked_url = reverse('task-voters-detail', kwargs={"resource_id": data.blocked_task.pk, + "pk": data.project_owner.pk}) + users = [ None, data.registered_user, @@ -506,6 +582,8 @@ def test_task_voters_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_tasks_csv(client, data): @@ -513,6 +591,7 @@ def test_tasks_csv(client, data): csv_public_uuid = data.public_project.tasks_csv_uuid csv_private1_uuid = data.private_project1.tasks_csv_uuid csv_private2_uuid = data.private_project1.tasks_csv_uuid + csv_blocked_uuid = data.blocked_project.tasks_csv_uuid users = [ None, @@ -531,11 +610,15 @@ def test_tasks_csv(client, data): results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private2_uuid), None, users) assert results == [200, 200, 200, 200, 200] + results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_blocked_uuid), None, users) + assert results == [200, 200, 200, 200, 200] + def test_task_action_watch(client, data): public_url = reverse('tasks-watch', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-watch', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-watch', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-watch', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -551,12 +634,15 @@ def test_task_action_watch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_task_action_unwatch(client, data): public_url = reverse('tasks-unwatch', kwargs={"pk": data.public_task.pk}) private_url1 = reverse('tasks-unwatch', kwargs={"pk": data.private_task1.pk}) private_url2 = reverse('tasks-unwatch', kwargs={"pk": data.private_task2.pk}) + blocked_url = reverse('tasks-unwatch', kwargs={"pk": data.blocked_task.pk}) users = [ None, @@ -572,12 +658,15 @@ def test_task_action_unwatch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_task_watchers_list(client, data): public_url = reverse('task-watchers-list', kwargs={"resource_id": data.public_task.pk}) private_url1 = reverse('task-watchers-list', kwargs={"resource_id": data.private_task1.pk}) private_url2 = reverse('task-watchers-list', kwargs={"resource_id": data.private_task2.pk}) + blocked_url = reverse('task-watchers-list', kwargs={"resource_id": data.blocked_task.pk}) users = [ None, @@ -593,6 +682,8 @@ def test_task_watchers_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_task_watchers_retrieve(client, data): @@ -606,6 +697,9 @@ def test_task_watchers_retrieve(client, data): private_url2 = reverse('task-watchers-detail', kwargs={"resource_id": data.private_task2.pk, "pk": data.project_owner.pk}) + add_watcher(data.blocked_task, data.project_owner) + blocked_url = reverse('task-watchers-detail', kwargs={"resource_id": data.blocked_task.pk, + "pk": data.project_owner.pk}) users = [ None, data.registered_user, @@ -620,3 +714,5 @@ def test_task_watchers_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] diff --git a/tests/integration/resources_permissions/test_userstories_custom_attributes_resource.py b/tests/integration/resources_permissions/test_userstories_custom_attributes_resource.py index a665e566..7c951322 100644 --- a/tests/integration/resources_permissions/test_userstories_custom_attributes_resource.py +++ b/tests/integration/resources_permissions/test_userstories_custom_attributes_resource.py @@ -19,6 +19,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.custom_attributes import serializers from taiga.permissions.permissions import (MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS) @@ -53,18 +54,23 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, email=m.project_member_with_perms.email, role__project=m.public_project, role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + m.private_membership1 = f.MembershipFactory(project=m.private_project1, user=m.project_member_with_perms, email=m.project_member_with_perms.email, role__project=m.private_project1, role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) - f.MembershipFactory(project=m.private_project1, user=m.project_member_without_perms, email=m.project_member_without_perms.email, @@ -82,6 +88,17 @@ def data(): role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + email=m.project_member_with_perms.email, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + email=m.project_member_without_perms.email, + role__project=m.blocked_project, + role__permissions=[]) + f.MembershipFactory(project=m.public_project, user=m.project_owner, is_owner=True) @@ -94,10 +111,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_userstory_ca = f.UserStoryCustomAttributeFactory(project=m.public_project) m.private_userstory_ca1 = f.UserStoryCustomAttributeFactory(project=m.private_project1) m.private_userstory_ca2 = f.UserStoryCustomAttributeFactory(project=m.private_project2) - + m.blocked_userstory_ca = f.UserStoryCustomAttributeFactory(project=m.blocked_project) m.public_user_story = f.UserStoryFactory(project=m.public_project, status__project=m.public_project) @@ -105,10 +126,13 @@ def data(): status__project=m.private_project1) m.private_user_story2 = f.UserStoryFactory(project=m.private_project2, status__project=m.private_project2) + m.blocked_user_story = f.UserStoryFactory(project=m.blocked_project, + status__project=m.blocked_project) m.public_user_story_cav = m.public_user_story.custom_attributes_values m.private_user_story_cav1 = m.private_user_story1.custom_attributes_values m.private_user_story_cav2 = m.private_user_story2.custom_attributes_values + m.blocked_user_story_cav = m.blocked_user_story.custom_attributes_values return m @@ -121,6 +145,7 @@ def test_userstory_custom_attribute_retrieve(client, data): public_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.public_userstory_ca.pk}) private1_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca1.pk}) private2_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca2.pk}) + blocked_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.blocked_userstory_ca.pk}) users = [ None, @@ -136,12 +161,15 @@ def test_userstory_custom_attribute_retrieve(client, data): 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] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_userstory_custom_attribute_create(client, data): public_url = reverse('userstory-custom-attributes-list') private1_url = reverse('userstory-custom-attributes-list') private2_url = reverse('userstory-custom-attributes-list') + blocked_url = reverse('userstory-custom-attributes-list') users = [ None, @@ -166,11 +194,17 @@ def test_userstory_custom_attribute_create(client, data): results = helper_test_http_method(client, 'post', private2_url, userstory_ca_data, users) assert results == [401, 403, 403, 403, 201] + userstory_ca_data = {"name": "test-new", "project": data.blocked_project.id} + userstory_ca_data = json.dumps(userstory_ca_data) + results = helper_test_http_method(client, 'post', blocked_url, userstory_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_userstory_custom_attribute_update(client, data): public_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.public_userstory_ca.pk}) private1_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca1.pk}) private2_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca2.pk}) + blocked_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.blocked_userstory_ca.pk}) users = [ None, @@ -198,11 +232,18 @@ def test_userstory_custom_attribute_update(client, data): results = helper_test_http_method(client, 'put', private2_url, userstory_ca_data, users) assert results == [401, 403, 403, 403, 200] + userstory_ca_data = serializers.UserStoryCustomAttributeSerializer(data.blocked_userstory_ca).data + userstory_ca_data["name"] = "test" + userstory_ca_data = json.dumps(userstory_ca_data) + results = helper_test_http_method(client, 'put', blocked_url, userstory_ca_data, users) + assert results == [401, 403, 403, 403, 451] + def test_userstory_custom_attribute_delete(client, data): public_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.public_userstory_ca.pk}) private1_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca1.pk}) private2_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca2.pk}) + blocked_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.blocked_userstory_ca.pk}) users = [ None, @@ -218,6 +259,8 @@ def test_userstory_custom_attribute_delete(client, data): 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] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 403, 451] def test_userstory_custom_attribute_list(client, data): @@ -239,12 +282,12 @@ def test_userstory_custom_attribute_list(client, data): client.login(data.project_member_with_perms) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.json.get(url) - assert len(response.data) == 3 + assert len(response.data) == 4 assert response.status_code == 200 @@ -252,6 +295,7 @@ def test_userstory_custom_attribute_patch(client, data): public_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.public_userstory_ca.pk}) private1_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca1.pk}) private2_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.private_userstory_ca2.pk}) + blocked_url = reverse('userstory-custom-attributes-detail', kwargs={"pk": data.blocked_userstory_ca.pk}) users = [ None, @@ -267,6 +311,8 @@ def test_userstory_custom_attribute_patch(client, data): assert results == [401, 403, 403, 403, 200] results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] + results = helper_test_http_method(client, 'patch', blocked_url, '{"name": "Test"}', users) + assert results == [401, 403, 403, 403, 451] def test_userstory_custom_attribute_action_bulk_update_order(client, data): @@ -301,6 +347,12 @@ def test_userstory_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] + post_data = json.dumps({ + "bulk_userstory_custom_attributes": [(1,2)], + "project": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 403, 451] ######################################################### @@ -315,6 +367,8 @@ def test_userstory_custom_attributes_values_retrieve(client, data): "user_story_id": data.private_user_story1.pk}) private_url2 = reverse('userstory-custom-attributes-values-detail', kwargs={ "user_story_id": data.private_user_story2.pk}) + blocked_url = reverse('userstory-custom-attributes-values-detail', kwargs={ + "user_story_id": data.blocked_user_story.pk}) users = [ None, @@ -330,6 +384,8 @@ def test_userstory_custom_attributes_values_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_userstory_custom_attributes_values_update(client, data): @@ -339,7 +395,8 @@ def test_userstory_custom_attributes_values_update(client, data): "user_story_id": data.private_user_story1.pk}) private_url2 = reverse('userstory-custom-attributes-values-detail', kwargs={ "user_story_id": data.private_user_story2.pk}) - + blocked_url = reverse('userstory-custom-attributes-values-detail', kwargs={ + "user_story_id": data.blocked_user_story.pk}) users = [ None, data.registered_user, @@ -366,6 +423,12 @@ def test_userstory_custom_attributes_values_update(client, data): results = helper_test_http_method(client, 'put', private_url2, user_story_data, users) assert results == [401, 403, 403, 200, 200] + user_story_data = serializers.UserStoryCustomAttributesValuesSerializer(data.blocked_user_story_cav).data + user_story_data["attributes_values"] = {str(data.blocked_userstory_ca.pk): "test"} + user_story_data = json.dumps(user_story_data) + results = helper_test_http_method(client, 'put', blocked_url, user_story_data, users) + assert results == [401, 403, 403, 451, 451] + def test_userstory_custom_attributes_values_patch(client, data): public_url = reverse('userstory-custom-attributes-values-detail', kwargs={ @@ -374,7 +437,8 @@ def test_userstory_custom_attributes_values_patch(client, data): "user_story_id": data.private_user_story1.pk}) private_url2 = reverse('userstory-custom-attributes-values-detail', kwargs={ "user_story_id": data.private_user_story2.pk}) - + blocked_url = reverse('userstory-custom-attributes-values-detail', kwargs={ + "user_story_id": data.blocked_user_story.pk}) users = [ None, data.registered_user, @@ -397,3 +461,8 @@ def test_userstory_custom_attributes_values_patch(client, data): "version": data.private_user_story2.version}) results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + + patch_data = json.dumps({"attributes_values": {str(data.blocked_userstory_ca.pk): "test"}, + "version": data.blocked_user_story.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] diff --git a/tests/integration/resources_permissions/test_userstories_resources.py b/tests/integration/resources_permissions/test_userstories_resources.py index 20881aed..3d7a3dd7 100644 --- a/tests/integration/resources_permissions/test_userstories_resources.py +++ b/tests/integration/resources_permissions/test_userstories_resources.py @@ -3,6 +3,7 @@ import uuid from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.projects.userstories.serializers import UserStorySerializer from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS from taiga.projects.occ import OCCResourceMixin @@ -51,6 +52,12 @@ def data(): public_permissions=[], owner=m.project_owner, userstories_csv_uuid=uuid.uuid4().hex) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + userstories_csv_uuid=uuid.uuid4().hex, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -72,6 +79,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -85,9 +100,14 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_points = f.PointsFactory(project=m.public_project) m.private_points1 = f.PointsFactory(project=m.private_project1) m.private_points2 = f.PointsFactory(project=m.private_project2) + m.blocked_points = f.PointsFactory(project=m.blocked_project) m.public_role_points = f.RolePointsFactory(role=m.public_project.roles.all()[0], points=m.public_points, @@ -104,10 +124,16 @@ def data(): user_story__project=m.private_project2, user_story__milestone__project=m.private_project2, user_story__status__project=m.private_project2) + m.blocked_role_points = f.RolePointsFactory(role=m.blocked_project.roles.all()[0], + points=m.blocked_points, + user_story__project=m.blocked_project, + user_story__milestone__project=m.blocked_project, + user_story__status__project=m.blocked_project) m.public_user_story = m.public_role_points.user_story m.private_user_story1 = m.private_role_points1.user_story m.private_user_story2 = m.private_role_points2.user_story + m.blocked_user_story = m.blocked_role_points.user_story return m @@ -116,6 +142,7 @@ def test_user_story_retrieve(client, data): public_url = reverse('userstories-detail', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-detail', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-detail', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-detail', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -131,12 +158,15 @@ def test_user_story_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_user_story_update(client, data): public_url = reverse('userstories-detail', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-detail', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-detail', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-detail', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -165,6 +195,11 @@ def test_user_story_update(client, data): results = helper_test_http_method(client, 'put', private_url2, user_story_data, users) assert results == [401, 403, 403, 200, 200] + user_story_data = UserStorySerializer(data.blocked_user_story).data + user_story_data["subject"] = "test" + user_story_data = json.dumps(user_story_data) + results = helper_test_http_method(client, 'put', blocked_url, user_story_data, users) + assert results == [401, 403, 403, 451, 451] def test_user_story_update_with_project_change(client): user1 = f.UserFactory.create() @@ -265,6 +300,7 @@ def test_user_story_delete(client, data): public_url = reverse('userstories-detail', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-detail', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-detail', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-detail', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -278,6 +314,8 @@ def test_user_story_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_user_story_list(client, data): @@ -299,14 +337,14 @@ def test_user_story_list(client, data): response = client.get(url) userstories_data = json.loads(response.content.decode('utf-8')) - assert len(userstories_data) == 3 + assert len(userstories_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) userstories_data = json.loads(response.content.decode('utf-8')) - assert len(userstories_data) == 3 + assert len(userstories_data) == 4 assert response.status_code == 200 @@ -333,11 +371,16 @@ def test_user_story_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({"subject": "test", "ref": 4, "project": data.blocked_project.pk}) + results = helper_test_http_method(client, 'post', url, create_data, users) + assert results == [401, 403, 403, 451, 451] + def test_user_story_patch(client, data): public_url = reverse('userstories-detail', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-detail', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-detail', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-detail', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -360,6 +403,10 @@ def test_user_story_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"subject": "test", "version": data.blocked_user_story.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_user_story_action_bulk_create(client, data): url = reverse('userstories-bulk-create') @@ -384,6 +431,10 @@ def test_user_story_action_bulk_create(client, data): results = helper_test_http_method(client, 'post', url, bulk_data, users) assert results == [401, 403, 403, 200, 200] + bulk_data = json.dumps({"bulk_stories": "test1\ntest2", "project_id": data.blocked_user_story.project.pk}) + results = helper_test_http_method(client, 'post', url, bulk_data, users) + assert results == [401, 403, 403, 451, 451] + def test_user_story_action_bulk_update_order(client, data): url = reverse('userstories-bulk-update-backlog-order') @@ -417,10 +468,19 @@ def test_user_story_action_bulk_update_order(client, data): results = helper_test_http_method(client, 'post', url, post_data, users) assert results == [401, 403, 403, 204, 204] + post_data = json.dumps({ + "bulk_stories": [{"us_id": data.blocked_user_story.id, "order": 2}], + "project_id": data.blocked_project.pk + }) + results = helper_test_http_method(client, 'post', url, post_data, users) + assert results == [401, 403, 403, 451, 451] + + def test_user_story_action_upvote(client, data): public_url = reverse('userstories-upvote', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-upvote', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-upvote', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-upvote', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -436,12 +496,15 @@ def test_user_story_action_upvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_user_story_action_downvote(client, data): public_url = reverse('userstories-downvote', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-downvote', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-downvote', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-downvote', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -457,12 +520,15 @@ def test_user_story_action_downvote(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_user_story_voters_list(client, data): public_url = reverse('userstory-voters-list', kwargs={"resource_id": data.public_user_story.pk}) private_url1 = reverse('userstory-voters-list', kwargs={"resource_id": data.private_user_story1.pk}) private_url2 = reverse('userstory-voters-list', kwargs={"resource_id": data.private_user_story2.pk}) + blocked_url = reverse('userstory-voters-list', kwargs={"resource_id": data.blocked_user_story.pk}) users = [ None, @@ -478,6 +544,8 @@ def test_user_story_voters_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_user_story_voters_retrieve(client, data): @@ -491,6 +559,9 @@ def test_user_story_voters_retrieve(client, data): private_url2 = reverse('userstory-voters-detail', kwargs={"resource_id": data.private_user_story2.pk, "pk": data.project_owner.pk}) + add_vote(data.blocked_user_story, data.project_owner) + blocked_url = reverse('userstory-voters-detail', kwargs={"resource_id": data.blocked_user_story.pk, + "pk": data.project_owner.pk}) users = [ None, data.registered_user, @@ -505,6 +576,8 @@ def test_user_story_voters_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_user_stories_csv(client, data): @@ -535,6 +608,7 @@ def test_user_story_action_watch(client, data): public_url = reverse('userstories-watch', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-watch', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-watch', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-watch', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -550,12 +624,15 @@ def test_user_story_action_watch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_user_story_action_unwatch(client, data): public_url = reverse('userstories-unwatch', kwargs={"pk": data.public_user_story.pk}) private_url1 = reverse('userstories-unwatch', kwargs={"pk": data.private_user_story1.pk}) private_url2 = reverse('userstories-unwatch', kwargs={"pk": data.private_user_story2.pk}) + blocked_url = reverse('userstories-unwatch', kwargs={"pk": data.blocked_user_story.pk}) users = [ None, @@ -571,12 +648,15 @@ def test_user_story_action_unwatch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_userstory_watchers_list(client, data): public_url = reverse('userstory-watchers-list', kwargs={"resource_id": data.public_user_story.pk}) private_url1 = reverse('userstory-watchers-list', kwargs={"resource_id": data.private_user_story1.pk}) private_url2 = reverse('userstory-watchers-list', kwargs={"resource_id": data.private_user_story2.pk}) + blocked_url = reverse('userstory-watchers-list', kwargs={"resource_id": data.blocked_user_story.pk}) users = [ None, @@ -592,6 +672,8 @@ def test_userstory_watchers_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_userstory_watchers_retrieve(client, data): @@ -604,6 +686,9 @@ def test_userstory_watchers_retrieve(client, data): add_watcher(data.private_user_story2, data.project_owner) private_url2 = reverse('userstory-watchers-detail', kwargs={"resource_id": data.private_user_story2.pk, "pk": data.project_owner.pk}) + add_watcher(data.blocked_user_story, data.project_owner) + blocked_url = reverse('userstory-watchers-detail', kwargs={"resource_id": data.blocked_user_story.pk, + "pk": data.project_owner.pk}) users = [ None, @@ -619,3 +704,5 @@ def test_userstory_watchers_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] diff --git a/tests/integration/resources_permissions/test_webhooks_resources.py b/tests/integration/resources_permissions/test_webhooks_resources.py index 63ef52e6..30c72097 100644 --- a/tests/integration/resources_permissions/test_webhooks_resources.py +++ b/tests/integration/resources_permissions/test_webhooks_resources.py @@ -1,6 +1,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json +from taiga.projects import choices as project_choices from taiga.webhooks.serializers import WebhookSerializer from taiga.webhooks.models import Webhook @@ -36,15 +37,25 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) f.MembershipFactory(project=m.project1, user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) m.webhook1 = f.WebhookFactory(project=m.project1) m.webhooklog1 = f.WebhookLogFactory(webhook=m.webhook1) m.webhook2 = f.WebhookFactory(project=m.project2) m.webhooklog2 = f.WebhookLogFactory(webhook=m.webhook2) + m.blocked_webhook = f.WebhookFactory(project=m.blocked_project) + m.blocked_webhooklog = f.WebhookLogFactory(webhook=m.blocked_webhook) return m @@ -52,6 +63,7 @@ def data(): def test_webhook_retrieve(client, data): url1 = reverse('webhooks-detail', kwargs={"pk": data.webhook1.pk}) url2 = reverse('webhooks-detail', kwargs={"pk": data.webhook2.pk}) + blocked_url = reverse('webhooks-detail', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -63,11 +75,14 @@ def test_webhook_retrieve(client, data): assert results == [401, 403, 200] results = helper_test_http_method(client, 'get', url2, None, users) assert results == [401, 403, 403] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 200] def test_webhook_update(client, data): url1 = reverse('webhooks-detail', kwargs={"pk": data.webhook1.pk}) url2 = reverse('webhooks-detail', kwargs={"pk": data.webhook2.pk}) + blocked_url = reverse('webhooks-detail', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -87,10 +102,17 @@ def test_webhook_update(client, data): results = helper_test_http_method(client, 'put', url2, webhook_data, users) assert results == [401, 403, 403] + webhook_data = WebhookSerializer(data.blocked_webhook).data + webhook_data["key"] = "test" + webhook_data = json.dumps(webhook_data) + results = helper_test_http_method(client, 'put', blocked_url, webhook_data, users) + assert results == [401, 403, 451] + def test_webhook_delete(client, data): url1 = reverse('webhooks-detail', kwargs={"pk": data.webhook1.pk}) url2 = reverse('webhooks-detail', kwargs={"pk": data.webhook2.pk}) + blocked_url = reverse('webhooks-detail', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -101,6 +123,8 @@ def test_webhook_delete(client, data): assert results == [401, 403, 204] results = helper_test_http_method(client, 'delete', url2, None, users) assert results == [401, 403, 403] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 451] def test_webhook_list(client, data): @@ -122,7 +146,7 @@ def test_webhook_list(client, data): response = client.get(url) webhooks_data = json.loads(response.content.decode('utf-8')) - assert len(webhooks_data) == 1 + assert len(webhooks_data) == 2 assert response.status_code == 200 @@ -153,10 +177,20 @@ def test_webhook_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users, lambda: Webhook.objects.all().delete()) assert results == [401, 403, 403] + create_data = json.dumps({ + "name": "Test", + "url": "http://test.com", + "key": "test", + "project": data.blocked_project.pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users, lambda: Webhook.objects.all().delete()) + assert results == [401, 403, 451] + def test_webhook_patch(client, data): url1 = reverse('webhooks-detail', kwargs={"pk": data.webhook1.pk}) url2 = reverse('webhooks-detail', kwargs={"pk": data.webhook2.pk}) + blocked_url = reverse('webhooks-detail', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -172,10 +206,15 @@ def test_webhook_patch(client, data): results = helper_test_http_method(client, 'patch', url2, patch_data, users) assert results == [401, 403, 403] + patch_data = json.dumps({"key": "test"}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 451] + def test_webhook_action_test(client, data): url1 = reverse('webhooks-test', kwargs={"pk": data.webhook1.pk}) url2 = reverse('webhooks-test', kwargs={"pk": data.webhook2.pk}) + blocked_url = reverse('webhooks-test', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -193,6 +232,11 @@ def test_webhook_action_test(client, data): assert results == [404, 404, 404] assert _send_request_mock.called is False + with mock.patch('taiga.webhooks.tasks._send_request') as _send_request_mock: + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451] + assert _send_request_mock.called is False + def test_webhooklogs_list(client, data): url = reverse('webhooklogs-list') @@ -213,13 +257,14 @@ def test_webhooklogs_list(client, data): response = client.get(url) webhooklogs_data = json.loads(response.content.decode('utf-8')) - assert len(webhooklogs_data) == 1 + assert len(webhooklogs_data) == 2 assert response.status_code == 200 def test_webhooklogs_retrieve(client, data): url1 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog1.pk}) url2 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog2.pk}) + blocked_url = reverse('webhooks-detail', kwargs={"pk": data.blocked_webhook.pk}) users = [ None, @@ -233,10 +278,14 @@ def test_webhooklogs_retrieve(client, data): results = helper_test_http_method(client, 'get', url2, None, users) assert results == [401, 403, 403] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 200] + def test_webhooklogs_create(client, data): url1 = reverse('webhooklogs-list') url2 = reverse('webhooklogs-list') + blocked_url = reverse('webhooklogs-list') users = [ None, @@ -250,10 +299,14 @@ def test_webhooklogs_create(client, data): results = helper_test_http_method(client, 'post', url2, None, users) assert results == [405, 405, 405] + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [405, 405, 405] + def test_webhooklogs_delete(client, data): url1 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog1.pk}) url2 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog2.pk}) + blocked_url = reverse('webhooklogs-detail', kwargs={"pk": data.blocked_webhooklog.pk}) users = [ None, @@ -267,10 +320,14 @@ def test_webhooklogs_delete(client, data): results = helper_test_http_method(client, 'delete', url2, None, users) assert results == [405, 405, 405] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [405, 405, 405] + def test_webhooklogs_update(client, data): url1 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog1.pk}) url2 = reverse('webhooklogs-detail', kwargs={"pk": data.webhooklog2.pk}) + blocked_url = reverse('webhooklogs-detail', kwargs={"pk": data.blocked_webhooklog.pk}) users = [ None, @@ -284,16 +341,23 @@ def test_webhooklogs_update(client, data): results = helper_test_http_method(client, 'put', url2, None, users) assert results == [405, 405, 405] + results = helper_test_http_method(client, 'put', blocked_url, None, users) + assert results == [405, 405, 405] + results = helper_test_http_method(client, 'patch', url1, None, users) assert results == [405, 405, 405] results = helper_test_http_method(client, 'patch', url2, None, users) assert results == [405, 405, 405] + results = helper_test_http_method(client, 'patch', blocked_url, None, users) + assert results == [405, 405, 405] + def test_webhooklogs_action_resend(client, data): url1 = reverse('webhooklogs-resend', kwargs={"pk": data.webhooklog1.pk}) url2 = reverse('webhooklogs-resend', kwargs={"pk": data.webhooklog2.pk}) + blocked_url = reverse('webhooklogs-resend', kwargs={"pk": data.blocked_webhooklog.pk}) users = [ None, @@ -306,3 +370,6 @@ def test_webhooklogs_action_resend(client, data): results = helper_test_http_method(client, 'post', url2, None, users) assert results == [404, 404, 404] + + results = helper_test_http_method(client, 'post', blocked_url, None, users) + assert results == [404, 404, 451] diff --git a/tests/integration/resources_permissions/test_wiki_resources.py b/tests/integration/resources_permissions/test_wiki_resources.py index 14f2f92b..ecbfb83b 100644 --- a/tests/integration/resources_permissions/test_wiki_resources.py +++ b/tests/integration/resources_permissions/test_wiki_resources.py @@ -2,6 +2,7 @@ from django.core.urlresolvers import reverse from taiga.base.utils import json from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS +from taiga.projects import choices as project_choices from taiga.projects.notifications.services import add_watcher from taiga.projects.occ import OCCResourceMixin from taiga.projects.wiki.serializers import WikiPageSerializer, WikiLinkSerializer @@ -46,6 +47,11 @@ def data(): anon_permissions=[], public_permissions=[], owner=m.project_owner) + m.blocked_project = f.ProjectFactory(is_private=True, + anon_permissions=[], + public_permissions=[], + owner=m.project_owner, + blocked_code=project_choices.BLOCKED_BY_STAFF) m.public_membership = f.MembershipFactory(project=m.public_project, user=m.project_member_with_perms, @@ -67,6 +73,14 @@ def data(): user=m.project_member_without_perms, role__project=m.private_project2, role__permissions=[]) + m.blocked_membership = f.MembershipFactory(project=m.blocked_project, + user=m.project_member_with_perms, + role__project=m.blocked_project, + role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) + f.MembershipFactory(project=m.blocked_project, + user=m.project_member_without_perms, + role__project=m.blocked_project, + role__permissions=[]) f.MembershipFactory(project=m.public_project, user=m.project_owner, @@ -80,13 +94,19 @@ def data(): user=m.project_owner, is_owner=True) + f.MembershipFactory(project=m.blocked_project, + user=m.project_owner, + is_owner=True) + m.public_wiki_page = f.WikiPageFactory(project=m.public_project) m.private_wiki_page1 = f.WikiPageFactory(project=m.private_project1) m.private_wiki_page2 = f.WikiPageFactory(project=m.private_project2) + m.blocked_wiki_page = f.WikiPageFactory(project=m.blocked_project) m.public_wiki_link = f.WikiLinkFactory(project=m.public_project) m.private_wiki_link1 = f.WikiLinkFactory(project=m.private_project1) m.private_wiki_link2 = f.WikiLinkFactory(project=m.private_project2) + m.blocked_wiki_link = f.WikiLinkFactory(project=m.blocked_project) return m @@ -95,6 +115,7 @@ def test_wiki_page_retrieve(client, data): public_url = reverse('wiki-detail', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-detail', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -110,12 +131,15 @@ def test_wiki_page_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_wiki_page_update(client, data): public_url = reverse('wiki-detail', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-detail', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -144,11 +168,18 @@ def test_wiki_page_update(client, data): results = helper_test_http_method(client, 'put', private_url2, wiki_page_data, users) assert results == [401, 403, 403, 200, 200] + wiki_page_data = WikiPageSerializer(data.blocked_wiki_page).data + wiki_page_data["content"] = "test" + wiki_page_data = json.dumps(wiki_page_data) + results = helper_test_http_method(client, 'put', blocked_url, wiki_page_data, users) + assert results == [401, 403, 403, 451, 451] + def test_wiki_page_delete(client, data): public_url = reverse('wiki-detail', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-detail', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -162,6 +193,8 @@ def test_wiki_page_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_wiki_page_list(client, data): @@ -183,14 +216,14 @@ def test_wiki_page_list(client, data): response = client.get(url) wiki_pages_data = json.loads(response.content.decode('utf-8')) - assert len(wiki_pages_data) == 3 + assert len(wiki_pages_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) wiki_pages_data = json.loads(response.content.decode('utf-8')) - assert len(wiki_pages_data) == 3 + assert len(wiki_pages_data) == 4 assert response.status_code == 200 @@ -229,11 +262,19 @@ def test_wiki_page_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiPage.objects.all().delete()) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({ + "content": "test", + "slug": "test", + "project": data.blocked_project.pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiPage.objects.all().delete()) + assert results == [401, 403, 403, 451, 451] def test_wiki_page_patch(client, data): public_url = reverse('wiki-detail', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-detail', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-detail', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -256,6 +297,10 @@ def test_wiki_page_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"content": "test", "version": data.blocked_wiki_page.version}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_wiki_page_action_render(client, data): url = reverse('wiki-render') @@ -277,6 +322,7 @@ def test_wiki_link_retrieve(client, data): public_url = reverse('wiki-links-detail', kwargs={"pk": data.public_wiki_link.pk}) private_url1 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link1.pk}) private_url2 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link2.pk}) + blocked_url = reverse('wiki-links-detail', kwargs={"pk": data.blocked_wiki_link.pk}) users = [ None, @@ -292,12 +338,15 @@ def test_wiki_link_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_wiki_link_update(client, data): public_url = reverse('wiki-links-detail', kwargs={"pk": data.public_wiki_link.pk}) private_url1 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link1.pk}) private_url2 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link2.pk}) + blocked_url = reverse('wiki-links-detail', kwargs={"pk": data.blocked_wiki_link.pk}) users = [ None, @@ -326,11 +375,17 @@ def test_wiki_link_update(client, data): results = helper_test_http_method(client, 'put', private_url2, wiki_link_data, users) assert results == [401, 403, 403, 200, 200] + wiki_link_data = WikiLinkSerializer(data.blocked_wiki_link).data + wiki_link_data["title"] = "test" + wiki_link_data = json.dumps(wiki_link_data) + results = helper_test_http_method(client, 'put', blocked_url, wiki_link_data, users) + assert results == [401, 403, 403, 451, 451] def test_wiki_link_delete(client, data): public_url = reverse('wiki-links-detail', kwargs={"pk": data.public_wiki_link.pk}) private_url1 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link1.pk}) private_url2 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link2.pk}) + blocked_url = reverse('wiki-links-detail', kwargs={"pk": data.blocked_wiki_link.pk}) users = [ None, @@ -344,6 +399,8 @@ def test_wiki_link_delete(client, data): assert results == [401, 403, 403, 204] results = helper_test_http_method(client, 'delete', private_url2, None, users) assert results == [401, 403, 403, 204] + results = helper_test_http_method(client, 'delete', blocked_url, None, users) + assert results == [401, 403, 403, 451] def test_wiki_link_list(client, data): @@ -365,14 +422,14 @@ def test_wiki_link_list(client, data): response = client.get(url) wiki_links_data = json.loads(response.content.decode('utf-8')) - assert len(wiki_links_data) == 3 + assert len(wiki_links_data) == 4 assert response.status_code == 200 client.login(data.project_owner) response = client.get(url) wiki_links_data = json.loads(response.content.decode('utf-8')) - assert len(wiki_links_data) == 3 + assert len(wiki_links_data) == 4 assert response.status_code == 200 @@ -411,11 +468,20 @@ def test_wiki_link_create(client, data): results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiLink.objects.all().delete()) assert results == [401, 403, 403, 201, 201] + create_data = json.dumps({ + "title": "test", + "href": "test", + "project": data.blocked_project.pk, + }) + results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiLink.objects.all().delete()) + assert results == [401, 403, 403, 451, 451] + def test_wiki_link_patch(client, data): public_url = reverse('wiki-links-detail', kwargs={"pk": data.public_wiki_link.pk}) private_url1 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link1.pk}) private_url2 = reverse('wiki-links-detail', kwargs={"pk": data.private_wiki_link2.pk}) + blocked_url = reverse('wiki-links-detail', kwargs={"pk": data.blocked_wiki_link.pk}) users = [ None, @@ -438,11 +504,16 @@ def test_wiki_link_patch(client, data): results = helper_test_http_method(client, 'patch', private_url2, patch_data, users) assert results == [401, 403, 403, 200, 200] + patch_data = json.dumps({"title": "test"}) + results = helper_test_http_method(client, 'patch', blocked_url, patch_data, users) + assert results == [401, 403, 403, 451, 451] + def test_wikipage_action_watch(client, data): public_url = reverse('wiki-watch', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-watch', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-watch', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-watch', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -458,12 +529,15 @@ def test_wikipage_action_watch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_wikipage_action_unwatch(client, data): public_url = reverse('wiki-unwatch', kwargs={"pk": data.public_wiki_page.pk}) private_url1 = reverse('wiki-unwatch', kwargs={"pk": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-unwatch', kwargs={"pk": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-unwatch', kwargs={"pk": data.blocked_wiki_page.pk}) users = [ None, @@ -479,12 +553,15 @@ def test_wikipage_action_unwatch(client, data): assert results == [401, 200, 200, 200, 200] results = helper_test_http_method(client, 'post', private_url2, "", users) assert results == [404, 404, 404, 200, 200] + results = helper_test_http_method(client, 'post', blocked_url, "", users) + assert results == [404, 404, 404, 451, 451] def test_wikipage_watchers_list(client, data): public_url = reverse('wiki-watchers-list', kwargs={"resource_id": data.public_wiki_page.pk}) private_url1 = reverse('wiki-watchers-list', kwargs={"resource_id": data.private_wiki_page1.pk}) private_url2 = reverse('wiki-watchers-list', kwargs={"resource_id": data.private_wiki_page2.pk}) + blocked_url = reverse('wiki-watchers-list', kwargs={"resource_id": data.blocked_wiki_page.pk}) users = [ None, @@ -500,6 +577,8 @@ def test_wikipage_watchers_list(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] def test_wikipage_watchers_retrieve(client, data): @@ -512,7 +591,9 @@ def test_wikipage_watchers_retrieve(client, data): add_watcher(data.private_wiki_page2, data.project_owner) private_url2 = reverse('wiki-watchers-detail', kwargs={"resource_id": data.private_wiki_page2.pk, "pk": data.project_owner.pk}) - + add_watcher(data.blocked_wiki_page, data.project_owner) + blocked_url = reverse('wiki-watchers-detail', kwargs={"resource_id": data.blocked_wiki_page.pk, + "pk": data.project_owner.pk}) users = [ None, data.registered_user, @@ -527,3 +608,5 @@ def test_wikipage_watchers_retrieve(client, data): assert results == [200, 200, 200, 200, 200] results = helper_test_http_method(client, 'get', private_url2, None, users) assert results == [401, 403, 403, 200, 200] + results = helper_test_http_method(client, 'get', blocked_url, None, users) + assert results == [401, 403, 403, 200, 200] diff --git a/tests/integration/test_vote_tasks.py b/tests/integration/test_vote_tasks.py index f387474d..c400f3ad 100644 --- a/tests/integration/test_vote_tasks.py +++ b/tests/integration/test_vote_tasks.py @@ -26,7 +26,7 @@ pytestmark = pytest.mark.django_db def test_upvote_task(client): user = f.UserFactory.create() - task = f.create_task(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) url = reverse("tasks-upvote", args=(task.id,)) @@ -38,7 +38,7 @@ def test_upvote_task(client): def test_downvote_task(client): user = f.UserFactory.create() - task = f.create_task(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) url = reverse("tasks-downvote", args=(task.id,)) @@ -93,7 +93,7 @@ def test_get_task_votes(client): def test_get_task_is_voted(client): user = f.UserFactory.create() - task = f.create_task(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) f.VotesFactory.create(content_object=task) url_detail = reverse("tasks-detail", args=(task.id,)) diff --git a/tests/integration/test_vote_userstories.py b/tests/integration/test_vote_userstories.py index 772937b8..4fbc0e6b 100644 --- a/tests/integration/test_vote_userstories.py +++ b/tests/integration/test_vote_userstories.py @@ -26,7 +26,7 @@ pytestmark = pytest.mark.django_db def test_upvote_user_story(client): user = f.UserFactory.create() - user_story = f.create_userstory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url = reverse("userstories-upvote", args=(user_story.id,)) @@ -38,7 +38,7 @@ def test_upvote_user_story(client): def test_downvote_user_story(client): user = f.UserFactory.create() - user_story = f.create_userstory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url = reverse("userstories-downvote", args=(user_story.id,)) @@ -92,7 +92,7 @@ def test_get_user_story_votes(client): def test_get_user_story_is_voted(client): user = f.UserFactory.create() - user_story = f.create_userstory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) f.VotesFactory.create(content_object=user_story) url_detail = reverse("userstories-detail", args=(user_story.id,)) diff --git a/tests/integration/test_watch_issues.py b/tests/integration/test_watch_issues.py index c5010827..885e0a96 100644 --- a/tests/integration/test_watch_issues.py +++ b/tests/integration/test_watch_issues.py @@ -79,7 +79,7 @@ def test_get_issue_watcher(client): def test_get_issue_watchers(client): user = f.UserFactory.create() - issue = f.IssueFactory(owner=user) + issue = f.create_issue(owner=user) f.MembershipFactory.create(project=issue.project, user=user, is_owner=True) url = reverse("issues-detail", args=(issue.id,)) @@ -95,7 +95,7 @@ def test_get_issue_watchers(client): def test_get_issue_is_watcher(client): user = f.UserFactory.create() - issue = f.IssueFactory(owner=user) + issue = f.create_issue(owner=user) f.MembershipFactory.create(project=issue.project, user=user, is_owner=True) url_detail = reverse("issues-detail", args=(issue.id,)) url_watch = reverse("issues-watch", args=(issue.id,)) diff --git a/tests/integration/test_watch_tasks.py b/tests/integration/test_watch_tasks.py index cde26ed0..c0fbc59b 100644 --- a/tests/integration/test_watch_tasks.py +++ b/tests/integration/test_watch_tasks.py @@ -27,7 +27,7 @@ pytestmark = pytest.mark.django_db def test_watch_task(client): user = f.UserFactory.create() - task = f.create_task(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) url = reverse("tasks-watch", args=(task.id,)) @@ -39,7 +39,7 @@ def test_watch_task(client): def test_unwatch_task(client): user = f.UserFactory.create() - task = f.create_task(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) url = reverse("tasks-watch", args=(task.id,)) @@ -95,7 +95,7 @@ def test_get_task_watchers(client): def test_get_task_is_watcher(client): user = f.UserFactory.create() - task = f.TaskFactory(owner=user) + task = f.create_task(owner=user, milestone=None) f.MembershipFactory.create(project=task.project, user=user, is_owner=True) url_detail = reverse("tasks-detail", args=(task.id,)) url_watch = reverse("tasks-watch", args=(task.id,)) @@ -109,6 +109,7 @@ def test_get_task_is_watcher(client): assert response.data['is_watcher'] == False response = client.post(url_watch) + print(response.data) assert response.status_code == 200 response = client.get(url_detail) diff --git a/tests/integration/test_watch_userstories.py b/tests/integration/test_watch_userstories.py index e17081cd..7e940664 100644 --- a/tests/integration/test_watch_userstories.py +++ b/tests/integration/test_watch_userstories.py @@ -27,7 +27,7 @@ pytestmark = pytest.mark.django_db def test_watch_user_story(client): user = f.UserFactory.create() - user_story = f.create_userstory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url = reverse("userstories-watch", args=(user_story.id,)) @@ -39,7 +39,7 @@ def test_watch_user_story(client): def test_unwatch_user_story(client): user = f.UserFactory.create() - user_story = f.create_userstory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url = reverse("userstories-unwatch", args=(user_story.id,)) @@ -65,7 +65,7 @@ def test_list_user_story_watchers(client): def test_get_user_story_watcher(client): user = f.UserFactory.create() - user_story = f.UserStoryFactory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) watch = f.WatchedFactory.create(content_object=user_story, user=user) url = reverse("userstory-watchers-detail", args=(user_story.id, watch.user.id)) @@ -79,7 +79,7 @@ def test_get_user_story_watcher(client): def test_get_user_story_watchers(client): user = f.UserFactory.create() - user_story = f.UserStoryFactory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url = reverse("userstories-detail", args=(user_story.id,)) @@ -95,7 +95,7 @@ def test_get_user_story_watchers(client): def test_get_user_story_is_watcher(client): user = f.UserFactory.create() - user_story = f.UserStoryFactory(owner=user) + user_story = f.create_userstory(owner=user, status=None) f.MembershipFactory.create(project=user_story.project, user=user, is_owner=True) url_detail = reverse("userstories-detail", args=(user_story.id,)) url_watch = reverse("userstories-watch", args=(user_story.id,))