Merge pull request #729 from taigaio/us/4186-2929/add_and_edit_comment_permission
US #4186 #2929: Add and edit comment permissionremotes/origin/issue/4795/notification_even_they_are_disabled
commit
43fafd1f57
|
@ -1,5 +1,14 @@
|
|||
# Changelog #
|
||||
|
||||
## 2.2.0 ??? (unreleased)
|
||||
|
||||
### Features
|
||||
- Now comment owners and project admins can edit existing comments with the history Entry endpoint.
|
||||
- Add a new permissions to allow add comments instead of use the existent modify permission for this purpose.
|
||||
|
||||
### Misc
|
||||
- Lots of small and not so small bugfixes.
|
||||
|
||||
|
||||
## 2.1.0 Ursus Americanus (2016-05-03)
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
python ./manage.py dumpdata --format json \
|
||||
--indent 4 \
|
||||
--output './taiga/projects/fixtures/initial_project_templates.json' \
|
||||
'projects.ProjectTemplate'
|
|
@ -20,11 +20,12 @@ import abc
|
|||
from functools import reduce
|
||||
|
||||
from taiga.base.utils import sequence as sq
|
||||
from taiga.permissions.service import user_has_perm, is_project_admin
|
||||
from taiga.permissions.services import user_has_perm, is_project_admin
|
||||
from django.apps import apps
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
||||
######################################################################
|
||||
# Base permissiones definition
|
||||
######################################################################
|
||||
|
@ -179,33 +180,6 @@ class HasProjectPerm(PermissionComponent):
|
|||
return user_has_perm(request.user, self.project_perm, obj)
|
||||
|
||||
|
||||
class HasProjectParamAndPerm(PermissionComponent):
|
||||
def __init__(self, perm, *components):
|
||||
self.project_perm = perm
|
||||
super().__init__(*components)
|
||||
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
Project = apps.get_model('projects', 'Project')
|
||||
project_id = request.QUERY_PARAMS.get("project", None)
|
||||
try:
|
||||
project = Project.objects.get(pk=project_id)
|
||||
except Project.DoesNotExist:
|
||||
return False
|
||||
return user_has_perm(request.user, self.project_perm, project)
|
||||
|
||||
|
||||
class HasMandatoryParam(PermissionComponent):
|
||||
def __init__(self, param, *components):
|
||||
self.mandatory_param = param
|
||||
super().__init__(*components)
|
||||
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
param = request.GET.get(self.mandatory_param, None)
|
||||
if param:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class IsProjectAdmin(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
return is_project_admin(request.user, obj)
|
||||
|
@ -213,6 +187,9 @@ class IsProjectAdmin(PermissionComponent):
|
|||
|
||||
class IsObjectOwner(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if obj.owner is None:
|
||||
return False
|
||||
|
||||
return obj.owner == request.user
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
ANON_PERMISSIONS = [
|
||||
('view_project', _('View project')),
|
||||
('view_milestones', _('View milestones')),
|
||||
('view_us', _('View user stories')),
|
||||
('view_tasks', _('View tasks')),
|
||||
('view_issues', _('View issues')),
|
||||
('view_wiki_pages', _('View wiki pages')),
|
||||
('view_wiki_links', _('View wiki links')),
|
||||
]
|
||||
MEMBERS_PERMISSIONS = [
|
||||
('view_project', _('View project')),
|
||||
# Milestone permissions
|
||||
('view_milestones', _('View milestones')),
|
||||
('add_milestone', _('Add milestone')),
|
||||
('modify_milestone', _('Modify milestone')),
|
||||
('delete_milestone', _('Delete milestone')),
|
||||
# US permissions
|
||||
('view_us', _('View user story')),
|
||||
('add_us', _('Add user story')),
|
||||
('modify_us', _('Modify user story')),
|
||||
('comment_us', _('Comment user story')),
|
||||
('delete_us', _('Delete user story')),
|
||||
# Task permissions
|
||||
('view_tasks', _('View tasks')),
|
||||
('add_task', _('Add task')),
|
||||
('modify_task', _('Modify task')),
|
||||
('comment_task', _('Comment task')),
|
||||
('delete_task', _('Delete task')),
|
||||
# Issue permissions
|
||||
('view_issues', _('View issues')),
|
||||
('add_issue', _('Add issue')),
|
||||
('modify_issue', _('Modify issue')),
|
||||
('comment_issue', _('Comment issue')),
|
||||
('delete_issue', _('Delete issue')),
|
||||
# Wiki page permissions
|
||||
('view_wiki_pages', _('View wiki pages')),
|
||||
('add_wiki_page', _('Add wiki page')),
|
||||
('modify_wiki_page', _('Modify wiki page')),
|
||||
('comment_wiki_page', _('Comment wiki page')),
|
||||
('delete_wiki_page', _('Delete wiki page')),
|
||||
# Wiki link permissions
|
||||
('view_wiki_links', _('View wiki links')),
|
||||
('add_wiki_link', _('Add wiki link')),
|
||||
('modify_wiki_link', _('Modify wiki link')),
|
||||
('delete_wiki_link', _('Delete wiki link')),
|
||||
]
|
||||
|
||||
ADMINS_PERMISSIONS = [
|
||||
('modify_project', _('Modify project')),
|
||||
('delete_project', _('Delete project')),
|
||||
('add_member', _('Add member')),
|
||||
('remove_member', _('Remove member')),
|
||||
('admin_project_values', _('Admin project values')),
|
||||
('admin_roles', _('Admin roles')),
|
||||
]
|
|
@ -16,77 +16,75 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.apps import apps
|
||||
|
||||
ANON_PERMISSIONS = [
|
||||
('view_project', _('View project')),
|
||||
('view_milestones', _('View milestones')),
|
||||
('view_us', _('View user stories')),
|
||||
('view_tasks', _('View tasks')),
|
||||
('view_issues', _('View issues')),
|
||||
('view_wiki_pages', _('View wiki pages')),
|
||||
('view_wiki_links', _('View wiki links')),
|
||||
]
|
||||
from taiga.base.api.permissions import PermissionComponent
|
||||
|
||||
USER_PERMISSIONS = [
|
||||
('view_project', _('View project')),
|
||||
('view_milestones', _('View milestones')),
|
||||
('view_us', _('View user stories')),
|
||||
('view_issues', _('View issues')),
|
||||
('view_tasks', _('View tasks')),
|
||||
('view_wiki_pages', _('View wiki pages')),
|
||||
('view_wiki_links', _('View wiki links')),
|
||||
('request_membership', _('Request membership')),
|
||||
('add_us_to_project', _('Add user story to project')),
|
||||
('add_comments_to_us', _('Add comments to user stories')),
|
||||
('add_comments_to_task', _('Add comments to tasks')),
|
||||
('add_issue', _('Add issues')),
|
||||
('add_comments_to_issue', _('Add comments to issues')),
|
||||
('add_wiki_page', _('Add wiki page')),
|
||||
('modify_wiki_page', _('Modify wiki page')),
|
||||
('add_wiki_link', _('Add wiki link')),
|
||||
('modify_wiki_link', _('Modify wiki link')),
|
||||
]
|
||||
from . import services
|
||||
|
||||
MEMBERS_PERMISSIONS = [
|
||||
('view_project', _('View project')),
|
||||
# Milestone permissions
|
||||
('view_milestones', _('View milestones')),
|
||||
('add_milestone', _('Add milestone')),
|
||||
('modify_milestone', _('Modify milestone')),
|
||||
('delete_milestone', _('Delete milestone')),
|
||||
# US permissions
|
||||
('view_us', _('View user story')),
|
||||
('add_us', _('Add user story')),
|
||||
('modify_us', _('Modify user story')),
|
||||
('delete_us', _('Delete user story')),
|
||||
# Task permissions
|
||||
('view_tasks', _('View tasks')),
|
||||
('add_task', _('Add task')),
|
||||
('modify_task', _('Modify task')),
|
||||
('delete_task', _('Delete task')),
|
||||
# Issue permissions
|
||||
('view_issues', _('View issues')),
|
||||
('add_issue', _('Add issue')),
|
||||
('modify_issue', _('Modify issue')),
|
||||
('delete_issue', _('Delete issue')),
|
||||
# Wiki page permissions
|
||||
('view_wiki_pages', _('View wiki pages')),
|
||||
('add_wiki_page', _('Add wiki page')),
|
||||
('modify_wiki_page', _('Modify wiki page')),
|
||||
('delete_wiki_page', _('Delete wiki page')),
|
||||
# Wiki link permissions
|
||||
('view_wiki_links', _('View wiki links')),
|
||||
('add_wiki_link', _('Add wiki link')),
|
||||
('modify_wiki_link', _('Modify wiki link')),
|
||||
('delete_wiki_link', _('Delete wiki link')),
|
||||
]
|
||||
|
||||
ADMINS_PERMISSIONS = [
|
||||
('modify_project', _('Modify project')),
|
||||
('add_member', _('Add member')),
|
||||
('remove_member', _('Remove member')),
|
||||
('delete_project', _('Delete project')),
|
||||
('admin_project_values', _('Admin project values')),
|
||||
('admin_roles', _('Admin roles')),
|
||||
]
|
||||
######################################################################
|
||||
# Generic perms
|
||||
######################################################################
|
||||
|
||||
class HasProjectPerm(PermissionComponent):
|
||||
def __init__(self, perm, *components):
|
||||
self.project_perm = perm
|
||||
super().__init__(*components)
|
||||
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
return services.user_has_perm(request.user, self.project_perm, obj)
|
||||
|
||||
|
||||
class IsObjectOwner(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if obj.owner is None:
|
||||
return False
|
||||
|
||||
return obj.owner == request.user
|
||||
|
||||
|
||||
######################################################################
|
||||
# Project Perms
|
||||
######################################################################
|
||||
|
||||
class IsProjectAdmin(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
return services.is_project_admin(request.user, obj)
|
||||
|
||||
|
||||
######################################################################
|
||||
# Common perms for stories, tasks and issues
|
||||
######################################################################
|
||||
|
||||
class CommentAndOrUpdatePerm(PermissionComponent):
|
||||
def __init__(self, update_perm, comment_perm, *components):
|
||||
self.update_perm = update_perm
|
||||
self.comment_perm = comment_perm
|
||||
super().__init__(*components)
|
||||
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if not obj:
|
||||
return False
|
||||
|
||||
project_id = request.DATA.get('project', None)
|
||||
if project_id and obj.project_id != project_id:
|
||||
project = apps.get_model("projects", "Project").objects.get(pk=project_id)
|
||||
else:
|
||||
project = obj.project
|
||||
|
||||
data_keys = request.DATA.keys()
|
||||
|
||||
if (not services.user_has_perm(request.user, self.comment_perm, project) and
|
||||
"comment" in data_keys):
|
||||
# User can't comment but there is a comment in the request
|
||||
#raise exc.PermissionDenied(_("You don't have permissions to comment this."))
|
||||
return False
|
||||
|
||||
if (not services.user_has_perm(request.user, self.update_perm, project) and
|
||||
len(data_keys - "comment")):
|
||||
# User can't update but there is a change in the request
|
||||
#raise exc.PermissionDenied(_("You don't have permissions to update this."))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .permissions import ADMINS_PERMISSIONS, MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from .choices import ADMINS_PERMISSIONS, MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from django.apps import apps
|
||||
|
||||
|
||||
def _get_user_project_membership(user, project, cache="user"):
|
||||
"""
|
||||
cache param determines how memberships are calculated trying to reuse the existing data
|
||||
|
@ -83,10 +84,6 @@ def user_has_perm(user, perm, obj=None, cache="user"):
|
|||
return perm in get_user_project_permissions(user, project, cache=cache)
|
||||
|
||||
|
||||
def role_has_perm(role, perm):
|
||||
return perm in role.permissions
|
||||
|
||||
|
||||
def _get_membership_permissions(membership):
|
||||
if membership and membership.role and membership.role.permissions:
|
||||
return membership.role.permissions
|
||||
|
@ -102,7 +99,7 @@ def get_user_project_permissions(user, project, cache="user"):
|
|||
if user.is_superuser:
|
||||
admins_permissions = list(map(lambda perm: perm[0], ADMINS_PERMISSIONS))
|
||||
members_permissions = list(map(lambda perm: perm[0], MEMBERS_PERMISSIONS))
|
||||
public_permissions = list(map(lambda perm: perm[0], USER_PERMISSIONS))
|
||||
public_permissions = []
|
||||
anon_permissions = list(map(lambda perm: perm[0], ANON_PERMISSIONS))
|
||||
elif membership:
|
||||
if membership.is_admin:
|
|
@ -51,8 +51,8 @@ from taiga.projects.userstories.models import UserStory, RolePoints
|
|||
from taiga.projects.tasks.models import Task
|
||||
from taiga.projects.issues.models import Issue
|
||||
from taiga.projects.likes.mixins.viewsets import LikedResourceMixin, FansViewSetMixin
|
||||
from taiga.permissions import service as permissions_service
|
||||
from taiga.users import services as users_service
|
||||
from taiga.permissions import services as permissions_services
|
||||
from taiga.users import services as users_services
|
||||
|
||||
from . import filters as project_filters
|
||||
from . import models
|
||||
|
@ -147,7 +147,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin,
|
|||
else:
|
||||
project = self.get_object()
|
||||
|
||||
if permissions_service.is_project_admin(self.request.user, project):
|
||||
if permissions_services.is_project_admin(self.request.user, project):
|
||||
serializer_class = self.admin_serializer_class
|
||||
|
||||
return serializer_class
|
||||
|
@ -415,7 +415,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin,
|
|||
update_permissions = True
|
||||
|
||||
if update_permissions:
|
||||
permissions_service.set_base_permissions_for_project(obj)
|
||||
permissions_services.set_base_permissions_for_project(obj)
|
||||
|
||||
def pre_save(self, obj):
|
||||
if not obj.id:
|
||||
|
@ -603,12 +603,12 @@ class MembershipViewSet(BlockedByProjectMixin, ModelCrudViewSet):
|
|||
use_admin_serializer = True
|
||||
|
||||
if self.action == "retrieve":
|
||||
use_admin_serializer = permissions_service.is_project_admin(self.request.user, self.object.project)
|
||||
use_admin_serializer = permissions_services.is_project_admin(self.request.user, self.object.project)
|
||||
|
||||
project_id = self.request.QUERY_PARAMS.get("project", None)
|
||||
if self.action == "list" and project_id is not None:
|
||||
project = get_object_or_404(models.Project, pk=project_id)
|
||||
use_admin_serializer = permissions_service.is_project_admin(self.request.user, project)
|
||||
use_admin_serializer = permissions_services.is_project_admin(self.request.user, project)
|
||||
|
||||
if use_admin_serializer:
|
||||
return self.admin_serializer_class
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
[
|
||||
{
|
||||
"model": "projects.projecttemplate",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"is_issues_activated": true,
|
||||
"task_statuses": "[{\"color\": \"#999999\", \"order\": 1, \"is_closed\": false, \"name\": \"New\", \"slug\": \"new\"}, {\"color\": \"#ff9900\", \"order\": 2, \"is_closed\": false, \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"color\": \"#ffcc00\", \"order\": 3, \"is_closed\": true, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"color\": \"#669900\", \"order\": 4, \"is_closed\": true, \"name\": \"Closed\", \"slug\": \"closed\"}, {\"color\": \"#999999\", \"order\": 5, \"is_closed\": false, \"name\": \"Needs Info\", \"slug\": \"needs-info\"}]",
|
||||
"is_backlog_activated": true,
|
||||
"modified_date": "2014-07-25T10:02:46.479Z",
|
||||
"us_statuses": "[{\"color\": \"#999999\", \"order\": 1, \"is_closed\": false, \"is_archived\": false, \"wip_limit\": null, \"name\": \"New\", \"slug\": \"new\"}, {\"color\": \"#ff8a84\", \"order\": 2, \"is_closed\": false, \"is_archived\": false, \"wip_limit\": null, \"name\": \"Ready\", \"slug\": \"ready\"}, {\"color\": \"#ff9900\", \"order\": 3, \"is_closed\": false, \"is_archived\": false, \"wip_limit\": null, \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"color\": \"#fcc000\", \"order\": 4, \"is_closed\": false, \"is_archived\": false, \"wip_limit\": null, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"color\": \"#669900\", \"order\": 5, \"is_closed\": true, \"is_archived\": false, \"wip_limit\": null, \"name\": \"Done\", \"slug\": \"done\"}, {\"color\": \"#5c3566\", \"order\": 6, \"is_closed\": true, \"is_archived\": true, \"wip_limit\": null, \"name\": \"Archived\", \"slug\": \"archived\"}]",
|
||||
"is_wiki_activated": true,
|
||||
"roles": "[{\"order\": 10, \"slug\": \"ux\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"UX\", \"computable\": true}, {\"order\": 20, \"slug\": \"design\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Design\", \"computable\": true}, {\"order\": 30, \"slug\": \"front\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Front\", \"computable\": true}, {\"order\": 40, \"slug\": \"back\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Back\", \"computable\": true}, {\"order\": 50, \"slug\": \"product-owner\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Product Owner\", \"computable\": false}, {\"order\": 60, \"slug\": \"stakeholder\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"view_milestones\", \"view_project\", \"view_tasks\", \"view_us\", \"modify_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Stakeholder\", \"computable\": false}]",
|
||||
"points": "[{\"value\": null, \"order\": 1, \"name\": \"?\"}, {\"value\": 0.0, \"order\": 2, \"name\": \"0\"}, {\"value\": 0.5, \"order\": 3, \"name\": \"1/2\"}, {\"value\": 1.0, \"order\": 4, \"name\": \"1\"}, {\"value\": 2.0, \"order\": 5, \"name\": \"2\"}, {\"value\": 3.0, \"order\": 6, \"name\": \"3\"}, {\"value\": 5.0, \"order\": 7, \"name\": \"5\"}, {\"value\": 8.0, \"order\": 8, \"name\": \"8\"}, {\"value\": 10.0, \"order\": 9, \"name\": \"10\"}, {\"value\": 13.0, \"order\": 10, \"name\": \"13\"}, {\"value\": 20.0, \"order\": 11, \"name\": \"20\"}, {\"value\": 40.0, \"order\": 12, \"name\": \"40\"}]",
|
||||
"severities": "[{\"color\": \"#666666\", \"order\": 1, \"name\": \"Wishlist\"}, {\"color\": \"#669933\", \"order\": 2, \"name\": \"Minor\"}, {\"color\": \"#0000FF\", \"order\": 3, \"name\": \"Normal\"}, {\"color\": \"#FFA500\", \"order\": 4, \"name\": \"Important\"}, {\"color\": \"#CC0000\", \"order\": 5, \"name\": \"Critical\"}]",
|
||||
"is_kanban_activated": false,
|
||||
"priorities": "[{\"color\": \"#666666\", \"order\": 1, \"name\": \"Low\"}, {\"color\": \"#669933\", \"order\": 3, \"name\": \"Normal\"}, {\"color\": \"#CC0000\", \"order\": 5, \"name\": \"High\"}]",
|
||||
"created_date": "2014-04-22T14:48:43.596Z",
|
||||
"default_options": "{\"us_status\": \"New\", \"task_status\": \"New\", \"priority\": \"Normal\", \"issue_type\": \"Bug\", \"severity\": \"Normal\", \"points\": \"?\", \"issue_status\": \"New\"}",
|
||||
"name": "Scrum",
|
||||
"slug": "scrum",
|
||||
"videoconferences_extra_data": "",
|
||||
"issue_statuses": "[{\"color\": \"#8C2318\", \"order\": 1, \"is_closed\": false, \"name\": \"New\", \"slug\": \"new\"}, {\"color\": \"#5E8C6A\", \"order\": 2, \"is_closed\": false, \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"color\": \"#88A65E\", \"order\": 3, \"is_closed\": true, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"color\": \"#BFB35A\", \"order\": 4, \"is_closed\": true, \"name\": \"Closed\", \"slug\": \"closed\"}, {\"color\": \"#89BAB4\", \"order\": 5, \"is_closed\": false, \"name\": \"Needs Info\", \"slug\": \"needs-info\"}, {\"color\": \"#CC0000\", \"order\": 6, \"is_closed\": true, \"name\": \"Rejected\", \"slug\": \"rejected\"}, {\"color\": \"#666666\", \"order\": 7, \"is_closed\": false, \"name\": \"Postponed\", \"slug\": \"posponed\"}]",
|
||||
"default_owner_role": "product-owner",
|
||||
"issue_types": "[{\"color\": \"#89BAB4\", \"order\": 1, \"name\": \"Bug\"}, {\"color\": \"#ba89a8\", \"order\": 2, \"name\": \"Question\"}, {\"color\": \"#89a8ba\", \"order\": 3, \"name\": \"Enhancement\"}]",
|
||||
"videoconferences": null,
|
||||
"description": "The agile product backlog in Scrum is a prioritized features list, containing short descriptions of all functionality desired in the product. When applying Scrum, it's not necessary to start a project with a lengthy, upfront effort to document all requirements. The Scrum product backlog is then allowed to grow and change as more is learned about the product and its customers",
|
||||
"name": "Scrum"
|
||||
},
|
||||
"pk": 1
|
||||
"created_date": "2014-04-22T14:48:43.596Z",
|
||||
"modified_date": "2014-07-25T10:02:46.479Z",
|
||||
"default_owner_role": "product-owner",
|
||||
"is_backlog_activated": true,
|
||||
"is_kanban_activated": false,
|
||||
"is_wiki_activated": true,
|
||||
"is_issues_activated": true,
|
||||
"videoconferences": null,
|
||||
"videoconferences_extra_data": "",
|
||||
"default_options": "{\"severity\": \"Normal\", \"priority\": \"Normal\", \"task_status\": \"New\", \"points\": \"?\", \"us_status\": \"New\", \"issue_type\": \"Bug\", \"issue_status\": \"New\"}",
|
||||
"us_statuses": "[{\"is_archived\": false, \"slug\": \"new\", \"is_closed\": false, \"wip_limit\": null, \"order\": 1, \"name\": \"New\", \"color\": \"#999999\"}, {\"is_archived\": false, \"slug\": \"ready\", \"is_closed\": false, \"wip_limit\": null, \"order\": 2, \"name\": \"Ready\", \"color\": \"#ff8a84\"}, {\"is_archived\": false, \"slug\": \"in-progress\", \"is_closed\": false, \"wip_limit\": null, \"order\": 3, \"name\": \"In progress\", \"color\": \"#ff9900\"}, {\"is_archived\": false, \"slug\": \"ready-for-test\", \"is_closed\": false, \"wip_limit\": null, \"order\": 4, \"name\": \"Ready for test\", \"color\": \"#fcc000\"}, {\"is_archived\": false, \"slug\": \"done\", \"is_closed\": true, \"wip_limit\": null, \"order\": 5, \"name\": \"Done\", \"color\": \"#669900\"}, {\"is_archived\": true, \"slug\": \"archived\", \"is_closed\": true, \"wip_limit\": null, \"order\": 6, \"name\": \"Archived\", \"color\": \"#5c3566\"}]",
|
||||
"points": "[{\"order\": 1, \"name\": \"?\", \"value\": null}, {\"order\": 2, \"name\": \"0\", \"value\": 0.0}, {\"order\": 3, \"name\": \"1/2\", \"value\": 0.5}, {\"order\": 4, \"name\": \"1\", \"value\": 1.0}, {\"order\": 5, \"name\": \"2\", \"value\": 2.0}, {\"order\": 6, \"name\": \"3\", \"value\": 3.0}, {\"order\": 7, \"name\": \"5\", \"value\": 5.0}, {\"order\": 8, \"name\": \"8\", \"value\": 8.0}, {\"order\": 9, \"name\": \"10\", \"value\": 10.0}, {\"order\": 10, \"name\": \"13\", \"value\": 13.0}, {\"order\": 11, \"name\": \"20\", \"value\": 20.0}, {\"order\": 12, \"name\": \"40\", \"value\": 40.0}]",
|
||||
"task_statuses": "[{\"order\": 1, \"name\": \"New\", \"slug\": \"new\", \"color\": \"#999999\", \"is_closed\": false}, {\"order\": 2, \"name\": \"In progress\", \"slug\": \"in-progress\", \"color\": \"#ff9900\", \"is_closed\": false}, {\"order\": 3, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\", \"color\": \"#ffcc00\", \"is_closed\": true}, {\"order\": 4, \"name\": \"Closed\", \"slug\": \"closed\", \"color\": \"#669900\", \"is_closed\": true}, {\"order\": 5, \"name\": \"Needs Info\", \"slug\": \"needs-info\", \"color\": \"#999999\", \"is_closed\": false}]",
|
||||
"issue_statuses": "[{\"order\": 1, \"name\": \"New\", \"slug\": \"new\", \"color\": \"#8C2318\", \"is_closed\": false}, {\"order\": 2, \"name\": \"In progress\", \"slug\": \"in-progress\", \"color\": \"#5E8C6A\", \"is_closed\": false}, {\"order\": 3, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\", \"color\": \"#88A65E\", \"is_closed\": true}, {\"order\": 4, \"name\": \"Closed\", \"slug\": \"closed\", \"color\": \"#BFB35A\", \"is_closed\": true}, {\"order\": 5, \"name\": \"Needs Info\", \"slug\": \"needs-info\", \"color\": \"#89BAB4\", \"is_closed\": false}, {\"order\": 6, \"name\": \"Rejected\", \"slug\": \"rejected\", \"color\": \"#CC0000\", \"is_closed\": true}, {\"order\": 7, \"name\": \"Postponed\", \"slug\": \"posponed\", \"color\": \"#666666\", \"is_closed\": false}]",
|
||||
"issue_types": "[{\"order\": 1, \"name\": \"Bug\", \"color\": \"#89BAB4\"}, {\"order\": 2, \"name\": \"Question\", \"color\": \"#ba89a8\"}, {\"order\": 3, \"name\": \"Enhancement\", \"color\": \"#89a8ba\"}]",
|
||||
"priorities": "[{\"order\": 1, \"name\": \"Low\", \"color\": \"#666666\"}, {\"order\": 3, \"name\": \"Normal\", \"color\": \"#669933\"}, {\"order\": 5, \"name\": \"High\", \"color\": \"#CC0000\"}]",
|
||||
"severities": "[{\"order\": 1, \"name\": \"Wishlist\", \"color\": \"#666666\"}, {\"order\": 2, \"name\": \"Minor\", \"color\": \"#669933\"}, {\"order\": 3, \"name\": \"Normal\", \"color\": \"#0000FF\"}, {\"order\": 4, \"name\": \"Important\", \"color\": \"#FFA500\"}, {\"order\": 5, \"name\": \"Critical\", \"color\": \"#CC0000\"}]",
|
||||
"roles": "[{\"order\": 10, \"name\": \"UX\", \"slug\": \"ux\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 20, \"name\": \"Design\", \"slug\": \"design\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 30, \"name\": \"Front\", \"slug\": \"front\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 40, \"name\": \"Back\", \"slug\": \"back\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 50, \"name\": \"Product Owner\", \"slug\": \"product-owner\", \"computable\": false, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 60, \"name\": \"Stakeholder\", \"slug\": \"stakeholder\", \"computable\": false, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"view_milestones\", \"view_project\", \"view_tasks\", \"view_us\", \"modify_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "projects.projecttemplate",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"is_issues_activated": false,
|
||||
"task_statuses": "[{\"color\": \"#999999\", \"order\": 1, \"is_closed\": false, \"name\": \"New\", \"slug\": \"new\"}, {\"color\": \"#729fcf\", \"order\": 2, \"is_closed\": false, \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"color\": \"#f57900\", \"order\": 3, \"is_closed\": true, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"color\": \"#4e9a06\", \"order\": 4, \"is_closed\": true, \"name\": \"Closed\", \"slug\": \"closed\"}, {\"color\": \"#cc0000\", \"order\": 5, \"is_closed\": false, \"name\": \"Needs Info\", \"slug\": \"needs-info\"}]",
|
||||
"is_backlog_activated": false,
|
||||
"modified_date": "2014-07-25T13:11:42.754Z",
|
||||
"us_statuses": "[{\"wip_limit\": null, \"order\": 1, \"is_closed\": false, \"is_archived\": false, \"color\": \"#999999\", \"name\": \"New\", \"slug\": \"new\"}, {\"wip_limit\": null, \"order\": 2, \"is_closed\": false, \"is_archived\": false, \"color\": \"#f57900\", \"name\": \"Ready\", \"slug\": \"ready\"}, {\"wip_limit\": null, \"order\": 3, \"is_closed\": false, \"is_archived\": false, \"color\": \"#729fcf\", \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"wip_limit\": null, \"order\": 4, \"is_closed\": false, \"is_archived\": false, \"color\": \"#4e9a06\", \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"wip_limit\": null, \"order\": 5, \"is_closed\": true, \"is_archived\": false, \"color\": \"#cc0000\", \"name\": \"Done\", \"slug\": \"done\"}, {\"wip_limit\": null, \"order\": 6, \"is_closed\": true, \"is_archived\": true, \"color\": \"#5c3566\", \"name\": \"Archived\", \"slug\": \"archived\"}]",
|
||||
"is_wiki_activated": false,
|
||||
"roles": "[{\"order\": 10, \"slug\": \"ux\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"UX\", \"computable\": true}, {\"order\": 20, \"slug\": \"design\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Design\", \"computable\": true}, {\"order\": 30, \"slug\": \"front\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Front\", \"computable\": true}, {\"order\": 40, \"slug\": \"back\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Back\", \"computable\": true}, {\"order\": 50, \"slug\": \"product-owner\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Product Owner\", \"computable\": false}, {\"order\": 60, \"slug\": \"stakeholder\", \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"view_milestones\", \"view_project\", \"view_tasks\", \"view_us\", \"modify_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"], \"name\": \"Stakeholder\", \"computable\": false}]",
|
||||
"points": "[{\"value\": null, \"name\": \"?\", \"order\": 1}, {\"value\": 0.0, \"name\": \"0\", \"order\": 2}, {\"value\": 0.5, \"name\": \"1/2\", \"order\": 3}, {\"value\": 1.0, \"name\": \"1\", \"order\": 4}, {\"value\": 2.0, \"name\": \"2\", \"order\": 5}, {\"value\": 3.0, \"name\": \"3\", \"order\": 6}, {\"value\": 5.0, \"name\": \"5\", \"order\": 7}, {\"value\": 8.0, \"name\": \"8\", \"order\": 8}, {\"value\": 10.0, \"name\": \"10\", \"order\": 9}, {\"value\": 13.0, \"name\": \"13\", \"order\": 10}, {\"value\": 20.0, \"name\": \"20\", \"order\": 11}, {\"value\": 40.0, \"name\": \"40\", \"order\": 12}]",
|
||||
"severities": "[{\"color\": \"#999999\", \"order\": 1, \"name\": \"Wishlist\"}, {\"color\": \"#729fcf\", \"order\": 2, \"name\": \"Minor\"}, {\"color\": \"#4e9a06\", \"order\": 3, \"name\": \"Normal\"}, {\"color\": \"#f57900\", \"order\": 4, \"name\": \"Important\"}, {\"color\": \"#CC0000\", \"order\": 5, \"name\": \"Critical\"}]",
|
||||
"is_kanban_activated": true,
|
||||
"priorities": "[{\"color\": \"#999999\", \"order\": 1, \"name\": \"Low\"}, {\"color\": \"#4e9a06\", \"order\": 3, \"name\": \"Normal\"}, {\"color\": \"#CC0000\", \"order\": 5, \"name\": \"High\"}]",
|
||||
"created_date": "2014-04-22T14:50:19.738Z",
|
||||
"default_options": "{\"us_status\": \"New\", \"task_status\": \"New\", \"priority\": \"Normal\", \"issue_type\": \"Bug\", \"severity\": \"Normal\", \"points\": \"?\", \"issue_status\": \"New\"}",
|
||||
"name": "Kanban",
|
||||
"slug": "kanban",
|
||||
"videoconferences_extra_data": "",
|
||||
"issue_statuses": "[{\"color\": \"#999999\", \"order\": 1, \"is_closed\": false, \"name\": \"New\", \"slug\": \"new\"}, {\"color\": \"#729fcf\", \"order\": 2, \"is_closed\": false, \"name\": \"In progress\", \"slug\": \"in-progress\"}, {\"color\": \"#f57900\", \"order\": 3, \"is_closed\": true, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\"}, {\"color\": \"#4e9a06\", \"order\": 4, \"is_closed\": true, \"name\": \"Closed\", \"slug\": \"closed\"}, {\"color\": \"#cc0000\", \"order\": 5, \"is_closed\": false, \"name\": \"Needs Info\", \"slug\": \"needs-info\"}, {\"color\": \"#d3d7cf\", \"order\": 6, \"is_closed\": true, \"name\": \"Rejected\", \"slug\": \"rejected\"}, {\"color\": \"#75507b\", \"order\": 7, \"is_closed\": false, \"name\": \"Postponed\", \"slug\": \"posponed\"}]",
|
||||
"default_owner_role": "product-owner",
|
||||
"issue_types": "[{\"color\": \"#cc0000\", \"order\": 1, \"name\": \"Bug\"}, {\"color\": \"#729fcf\", \"order\": 2, \"name\": \"Question\"}, {\"color\": \"#4e9a06\", \"order\": 3, \"name\": \"Enhancement\"}]",
|
||||
"videoconferences": null,
|
||||
"description": "Kanban is a method for managing knowledge work with an emphasis on just-in-time delivery while not overloading the team members. In this approach, the process, from definition of a task to its delivery to the customer, is displayed for participants to see and team members pull work from a queue.",
|
||||
"name": "Kanban"
|
||||
},
|
||||
"pk": 2
|
||||
"created_date": "2014-04-22T14:50:19.738Z",
|
||||
"modified_date": "2014-07-25T13:11:42.754Z",
|
||||
"default_owner_role": "product-owner",
|
||||
"is_backlog_activated": false,
|
||||
"is_kanban_activated": true,
|
||||
"is_wiki_activated": false,
|
||||
"is_issues_activated": false,
|
||||
"videoconferences": null,
|
||||
"videoconferences_extra_data": "",
|
||||
"default_options": "{\"severity\": \"Normal\", \"priority\": \"Normal\", \"task_status\": \"New\", \"points\": \"?\", \"us_status\": \"New\", \"issue_type\": \"Bug\", \"issue_status\": \"New\"}",
|
||||
"us_statuses": "[{\"is_archived\": false, \"slug\": \"new\", \"is_closed\": false, \"wip_limit\": null, \"order\": 1, \"name\": \"New\", \"color\": \"#999999\"}, {\"is_archived\": false, \"slug\": \"ready\", \"is_closed\": false, \"wip_limit\": null, \"order\": 2, \"name\": \"Ready\", \"color\": \"#f57900\"}, {\"is_archived\": false, \"slug\": \"in-progress\", \"is_closed\": false, \"wip_limit\": null, \"order\": 3, \"name\": \"In progress\", \"color\": \"#729fcf\"}, {\"is_archived\": false, \"slug\": \"ready-for-test\", \"is_closed\": false, \"wip_limit\": null, \"order\": 4, \"name\": \"Ready for test\", \"color\": \"#4e9a06\"}, {\"is_archived\": false, \"slug\": \"done\", \"is_closed\": true, \"wip_limit\": null, \"order\": 5, \"name\": \"Done\", \"color\": \"#cc0000\"}, {\"is_archived\": true, \"slug\": \"archived\", \"is_closed\": true, \"wip_limit\": null, \"order\": 6, \"name\": \"Archived\", \"color\": \"#5c3566\"}]",
|
||||
"points": "[{\"order\": 1, \"name\": \"?\", \"value\": null}, {\"order\": 2, \"name\": \"0\", \"value\": 0.0}, {\"order\": 3, \"name\": \"1/2\", \"value\": 0.5}, {\"order\": 4, \"name\": \"1\", \"value\": 1.0}, {\"order\": 5, \"name\": \"2\", \"value\": 2.0}, {\"order\": 6, \"name\": \"3\", \"value\": 3.0}, {\"order\": 7, \"name\": \"5\", \"value\": 5.0}, {\"order\": 8, \"name\": \"8\", \"value\": 8.0}, {\"order\": 9, \"name\": \"10\", \"value\": 10.0}, {\"order\": 10, \"name\": \"13\", \"value\": 13.0}, {\"order\": 11, \"name\": \"20\", \"value\": 20.0}, {\"order\": 12, \"name\": \"40\", \"value\": 40.0}]",
|
||||
"task_statuses": "[{\"order\": 1, \"name\": \"New\", \"slug\": \"new\", \"color\": \"#999999\", \"is_closed\": false}, {\"order\": 2, \"name\": \"In progress\", \"slug\": \"in-progress\", \"color\": \"#729fcf\", \"is_closed\": false}, {\"order\": 3, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\", \"color\": \"#f57900\", \"is_closed\": true}, {\"order\": 4, \"name\": \"Closed\", \"slug\": \"closed\", \"color\": \"#4e9a06\", \"is_closed\": true}, {\"order\": 5, \"name\": \"Needs Info\", \"slug\": \"needs-info\", \"color\": \"#cc0000\", \"is_closed\": false}]",
|
||||
"issue_statuses": "[{\"order\": 1, \"name\": \"New\", \"slug\": \"new\", \"color\": \"#999999\", \"is_closed\": false}, {\"order\": 2, \"name\": \"In progress\", \"slug\": \"in-progress\", \"color\": \"#729fcf\", \"is_closed\": false}, {\"order\": 3, \"name\": \"Ready for test\", \"slug\": \"ready-for-test\", \"color\": \"#f57900\", \"is_closed\": true}, {\"order\": 4, \"name\": \"Closed\", \"slug\": \"closed\", \"color\": \"#4e9a06\", \"is_closed\": true}, {\"order\": 5, \"name\": \"Needs Info\", \"slug\": \"needs-info\", \"color\": \"#cc0000\", \"is_closed\": false}, {\"order\": 6, \"name\": \"Rejected\", \"slug\": \"rejected\", \"color\": \"#d3d7cf\", \"is_closed\": true}, {\"order\": 7, \"name\": \"Postponed\", \"slug\": \"posponed\", \"color\": \"#75507b\", \"is_closed\": false}]",
|
||||
"issue_types": "[{\"order\": 1, \"name\": \"Bug\", \"color\": \"#cc0000\"}, {\"order\": 2, \"name\": \"Question\", \"color\": \"#729fcf\"}, {\"order\": 3, \"name\": \"Enhancement\", \"color\": \"#4e9a06\"}]",
|
||||
"priorities": "[{\"order\": 1, \"name\": \"Low\", \"color\": \"#999999\"}, {\"order\": 3, \"name\": \"Normal\", \"color\": \"#4e9a06\"}, {\"order\": 5, \"name\": \"High\", \"color\": \"#CC0000\"}]",
|
||||
"severities": "[{\"order\": 1, \"name\": \"Wishlist\", \"color\": \"#999999\"}, {\"order\": 2, \"name\": \"Minor\", \"color\": \"#729fcf\"}, {\"order\": 3, \"name\": \"Normal\", \"color\": \"#4e9a06\"}, {\"order\": 4, \"name\": \"Important\", \"color\": \"#f57900\"}, {\"order\": 5, \"name\": \"Critical\", \"color\": \"#CC0000\"}]",
|
||||
"roles": "[{\"order\": 10, \"name\": \"UX\", \"slug\": \"ux\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 20, \"name\": \"Design\", \"slug\": \"design\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 30, \"name\": \"Front\", \"slug\": \"front\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 40, \"name\": \"Back\", \"slug\": \"back\", \"computable\": true, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 50, \"name\": \"Product Owner\", \"slug\": \"product-owner\", \"computable\": false, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"add_milestone\", \"modify_milestone\", \"delete_milestone\", \"view_milestones\", \"view_project\", \"add_task\", \"modify_task\", \"delete_task\", \"view_tasks\", \"add_us\", \"modify_us\", \"delete_us\", \"view_us\", \"add_wiki_page\", \"modify_wiki_page\", \"delete_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}, {\"order\": 60, \"name\": \"Stakeholder\", \"slug\": \"stakeholder\", \"computable\": false, \"permissions\": [\"add_issue\", \"modify_issue\", \"delete_issue\", \"view_issues\", \"view_milestones\", \"view_project\", \"view_tasks\", \"view_us\", \"modify_wiki_page\", \"view_wiki_pages\", \"add_wiki_link\", \"delete_wiki_link\", \"view_wiki_links\"]}]"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -23,6 +23,7 @@ from taiga.base import response
|
|||
from taiga.base.decorators import detail_route
|
||||
from taiga.base.api import ReadOnlyListViewSet
|
||||
from taiga.base.api.utils import get_object_or_404
|
||||
from taiga.mdrender.service import render as mdrender
|
||||
|
||||
from . import permissions
|
||||
from . import serializers
|
||||
|
@ -56,42 +57,93 @@ class HistoryViewSet(ReadOnlyListViewSet):
|
|||
|
||||
return response.Ok(serializer.data)
|
||||
|
||||
@detail_route(methods=['get'])
|
||||
def comment_versions(self, request, pk):
|
||||
obj = self.get_object()
|
||||
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
|
||||
|
||||
self.check_permissions(request, 'comment_versions', history_entry)
|
||||
|
||||
if history_entry is None:
|
||||
return response.NotFound()
|
||||
|
||||
history_entry.attach_user_info_to_comment_versions()
|
||||
return response.Ok(history_entry.comment_versions)
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def edit_comment(self, request, pk):
|
||||
obj = self.get_object()
|
||||
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
|
||||
obj = services.get_instance_from_key(history_entry.key)
|
||||
comment = request.DATA.get("comment", None)
|
||||
|
||||
self.check_permissions(request, 'edit_comment', history_entry)
|
||||
|
||||
if history_entry is None:
|
||||
return response.NotFound()
|
||||
|
||||
if comment is None:
|
||||
return response.BadRequest({"error": _("comment is required")})
|
||||
|
||||
if history_entry.delete_comment_date or history_entry.delete_comment_user:
|
||||
return response.BadRequest({"error": _("deleted comments can't be edited")})
|
||||
|
||||
# comment_versions can be None if there are no historic versions of the comment
|
||||
comment_versions = history_entry.comment_versions or []
|
||||
comment_versions.append({
|
||||
"date": history_entry.created_at,
|
||||
"comment": history_entry.comment,
|
||||
"comment_html": history_entry.comment_html,
|
||||
"user": {
|
||||
"id": request.user.pk,
|
||||
}
|
||||
})
|
||||
|
||||
history_entry.edit_comment_date = timezone.now()
|
||||
history_entry.comment = comment
|
||||
history_entry.comment_html = mdrender(obj.project, comment)
|
||||
history_entry.comment_versions = comment_versions
|
||||
history_entry.save()
|
||||
return response.Ok()
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def delete_comment(self, request, pk):
|
||||
obj = self.get_object()
|
||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
||||
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
|
||||
|
||||
self.check_permissions(request, 'delete_comment', comment)
|
||||
self.check_permissions(request, 'delete_comment', history_entry)
|
||||
|
||||
if comment is None:
|
||||
if history_entry is None:
|
||||
return response.NotFound()
|
||||
|
||||
if comment.delete_comment_date or comment.delete_comment_user:
|
||||
if history_entry.delete_comment_date or history_entry.delete_comment_user:
|
||||
return response.BadRequest({"error": _("Comment already deleted")})
|
||||
|
||||
comment.delete_comment_date = timezone.now()
|
||||
comment.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
|
||||
comment.save()
|
||||
history_entry.delete_comment_date = timezone.now()
|
||||
history_entry.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
|
||||
history_entry.save()
|
||||
return response.Ok()
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def undelete_comment(self, request, pk):
|
||||
obj = self.get_object()
|
||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
||||
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
|
||||
|
||||
self.check_permissions(request, 'undelete_comment', comment)
|
||||
self.check_permissions(request, 'undelete_comment', history_entry)
|
||||
|
||||
if comment is None:
|
||||
if history_entry is None:
|
||||
return response.NotFound()
|
||||
|
||||
if not comment.delete_comment_date and not comment.delete_comment_user:
|
||||
if not history_entry.delete_comment_date and not history_entry.delete_comment_user:
|
||||
return response.BadRequest({"error": _("Comment not deleted")})
|
||||
|
||||
comment.delete_comment_date = None
|
||||
comment.delete_comment_user = None
|
||||
comment.save()
|
||||
history_entry.delete_comment_date = None
|
||||
history_entry.delete_comment_user = None
|
||||
history_entry.save()
|
||||
return response.Ok()
|
||||
|
||||
# Just for restframework! Because it raises
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-05-12 11:10
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django_pgjson.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('history', '0008_auto_20150508_1028'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='historyentry',
|
||||
name='comment_versions',
|
||||
field=django_pgjson.fields.JsonField(blank=True, default=None, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historyentry',
|
||||
name='edit_comment_date',
|
||||
field=models.DateTimeField(blank=True, default=None, null=True),
|
||||
),
|
||||
]
|
|
@ -67,6 +67,10 @@ class HistoryEntry(models.Model):
|
|||
delete_comment_date = models.DateTimeField(null=True, blank=True, default=None)
|
||||
delete_comment_user = JsonField(null=True, blank=True, default=None)
|
||||
|
||||
# Historic version of comments
|
||||
comment_versions = JsonField(null=True, blank=True, default=None)
|
||||
edit_comment_date = models.DateTimeField(null=True, blank=True, default=None)
|
||||
|
||||
# Flag for mark some history entries as
|
||||
# hidden. Hidden history entries are important
|
||||
# for save but not important to preview.
|
||||
|
@ -111,6 +115,20 @@ class HistoryEntry(models.Model):
|
|||
self._owner = owner
|
||||
self._prefetched_owner = True
|
||||
|
||||
def attach_user_info_to_comment_versions(self):
|
||||
if not self.comment_versions:
|
||||
return
|
||||
|
||||
from taiga.users.serializers import UserSerializer
|
||||
|
||||
user_ids = [v["user"]["id"] for v in self.comment_versions if "user" in v and "id" in v["user"]]
|
||||
users_by_id = {u.id: u for u in get_user_model().objects.filter(id__in=user_ids)}
|
||||
|
||||
for version in self.comment_versions:
|
||||
user = users_by_id.get(version["user"]["id"], None)
|
||||
if user:
|
||||
version["user"] = UserSerializer(user).data
|
||||
|
||||
@cached_property
|
||||
def values_diff(self):
|
||||
result = {}
|
||||
|
|
|
@ -19,7 +19,7 @@ from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
|||
IsProjectAdmin, AllowAny,
|
||||
IsObjectOwner, PermissionComponent)
|
||||
|
||||
from taiga.permissions.service import is_project_admin
|
||||
from taiga.permissions.services import is_project_admin
|
||||
from taiga.projects.history.services import get_model_from_key, get_pk_from_key
|
||||
|
||||
|
||||
|
@ -33,32 +33,41 @@ class IsCommentOwner(PermissionComponent):
|
|||
return obj.user and obj.user.get("pk", "not-pk") == request.user.pk
|
||||
|
||||
|
||||
class IsCommentProjectOwner(PermissionComponent):
|
||||
class IsCommentProjectAdmin(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
model = get_model_from_key(obj.key)
|
||||
pk = get_pk_from_key(obj.key)
|
||||
project = model.objects.get(pk=pk)
|
||||
return is_project_admin(request.user, project)
|
||||
|
||||
|
||||
class UserStoryHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
||||
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
|
||||
|
||||
class TaskHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
||||
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
|
||||
|
||||
class IssueHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
||||
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
|
||||
|
||||
class WikiHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
||||
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||
|
|
|
@ -33,9 +33,11 @@ class HistoryEntrySerializer(serializers.ModelSerializer):
|
|||
values_diff = I18NJsonField(i18n_fields=HISTORY_ENTRY_I18N_FIELDS)
|
||||
user = serializers.SerializerMethodField("get_user")
|
||||
delete_comment_user = JsonField()
|
||||
comment_versions = JsonField()
|
||||
|
||||
class Meta:
|
||||
model = models.HistoryEntry
|
||||
exclude = ("comment_versions",)
|
||||
|
||||
def get_user(self, entry):
|
||||
user = {"pk": None, "username": None, "name": None, "photo": None, "is_active": False}
|
||||
|
|
|
@ -91,6 +91,20 @@ def get_pk_from_key(key:str) -> object:
|
|||
return pk
|
||||
|
||||
|
||||
def get_instance_from_key(key:str) -> object:
|
||||
"""
|
||||
Get instance from key
|
||||
"""
|
||||
model = get_model_from_key(key)
|
||||
pk = get_pk_from_key(key)
|
||||
try:
|
||||
obj = model.objects.get(pk=pk)
|
||||
return obj
|
||||
except model.DoesNotExist:
|
||||
# Catch simultaneous DELETE request
|
||||
return None
|
||||
|
||||
|
||||
def register_values_implementation(typename:str, fn=None):
|
||||
"""
|
||||
Register values implementation for specified typename.
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
IsProjectAdmin, PermissionComponent,
|
||||
AllowAny, IsAuthenticated, IsSuperUser)
|
||||
from taiga.base.api.permissions import TaigaResourcePermission, AllowAny, IsAuthenticated, IsSuperUser
|
||||
from taiga.permissions.permissions import HasProjectPerm, IsProjectAdmin
|
||||
|
||||
from taiga.permissions.permissions import CommentAndOrUpdatePerm
|
||||
|
||||
|
||||
class IssuePermission(TaigaResourcePermission):
|
||||
|
@ -26,8 +27,8 @@ class IssuePermission(TaigaResourcePermission):
|
|||
global_perms = None
|
||||
retrieve_perms = HasProjectPerm('view_issues')
|
||||
create_perms = HasProjectPerm('add_issue')
|
||||
update_perms = HasProjectPerm('modify_issue')
|
||||
partial_update_perms = HasProjectPerm('modify_issue')
|
||||
update_perms = CommentAndOrUpdatePerm('modify_issue', 'comment_issue')
|
||||
partial_update_perms = CommentAndOrUpdatePerm('modify_issue', 'comment_issue')
|
||||
destroy_perms = HasProjectPerm('delete_issue')
|
||||
list_perms = AllowAny()
|
||||
filters_data_perms = AllowAny()
|
||||
|
@ -40,14 +41,6 @@ class IssuePermission(TaigaResourcePermission):
|
|||
unwatch_perms = IsAuthenticated() & HasProjectPerm('view_issues')
|
||||
|
||||
|
||||
class HasIssueIdUrlParam(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
param = view.kwargs.get('issue_id', None)
|
||||
if param:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class IssueVotersPermission(TaigaResourcePermission):
|
||||
enought_perms = IsProjectAdmin() | IsSuperUser()
|
||||
global_perms = None
|
||||
|
|
|
@ -29,7 +29,7 @@ from django.contrib.contenttypes.models import ContentType
|
|||
from sampledatahelper.helper import SampleDataHelper
|
||||
|
||||
from taiga.users.models import *
|
||||
from taiga.permissions.permissions import ANON_PERMISSIONS
|
||||
from taiga.permissions.choices import ANON_PERMISSIONS
|
||||
from taiga.projects.choices import BLOCKED_BY_STAFF
|
||||
from taiga.projects.models import *
|
||||
from taiga.projects.milestones.models import *
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-05-19 10:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import djorm_pgarray.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('projects', '0040_remove_memberships_of_cancelled_users_acounts'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='project',
|
||||
name='public_permissions',
|
||||
field=djorm_pgarray.fields.TextArrayField(choices=[('view_project', 'View project'), ('view_milestones', 'View milestones'), ('add_milestone', 'Add milestone'), ('modify_milestone', 'Modify milestone'), ('delete_milestone', 'Delete milestone'), ('view_us', 'View user story'), ('add_us', 'Add user story'), ('modify_us', 'Modify user story'), ('comment_us', 'Comment user story'), ('delete_us', 'Delete user story'), ('view_tasks', 'View tasks'), ('add_task', 'Add task'), ('modify_task', 'Modify task'), ('comment_task', 'Comment task'), ('delete_task', 'Delete task'), ('view_issues', 'View issues'), ('add_issue', 'Add issue'), ('modify_issue', 'Modify issue'), ('comment_issue', 'Comment issue'), ('delete_issue', 'Delete issue'), ('view_wiki_pages', 'View wiki pages'), ('add_wiki_page', 'Add wiki page'), ('modify_wiki_page', 'Modify wiki page'), ('comment_wiki_page', 'Comment wiki page'), ('delete_wiki_page', 'Delete wiki page'), ('view_wiki_links', 'View wiki links'), ('add_wiki_link', 'Add wiki link'), ('modify_wiki_link', 'Modify wiki link'), ('delete_wiki_link', 'Delete wiki link')], dbtype='text', default=[], verbose_name='user permissions'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-05-25 09:11
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
UPDATE_PROJECTS_ANON_PERMISSIONS_SQL = """
|
||||
UPDATE projects_project
|
||||
SET
|
||||
ANON_PERMISSIONS = array_append(ANON_PERMISSIONS, '{comment_permission}')
|
||||
WHERE
|
||||
'{base_permission}' = ANY(ANON_PERMISSIONS)
|
||||
AND
|
||||
NOT '{comment_permission}' = ANY(ANON_PERMISSIONS)
|
||||
"""
|
||||
|
||||
UPDATE_PROJECTS_PUBLIC_PERMISSIONS_SQL = """
|
||||
UPDATE projects_project
|
||||
SET
|
||||
PUBLIC_PERMISSIONS = array_append(PUBLIC_PERMISSIONS, '{comment_permission}')
|
||||
WHERE
|
||||
'{base_permission}' = ANY(PUBLIC_PERMISSIONS)
|
||||
AND
|
||||
NOT '{comment_permission}' = ANY(PUBLIC_PERMISSIONS)
|
||||
"""
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('projects', '0041_auto_20160519_1058'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
# user stories
|
||||
migrations.RunSQL(UPDATE_PROJECTS_ANON_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_us",
|
||||
comment_permission="comment_us")
|
||||
),
|
||||
|
||||
migrations.RunSQL(UPDATE_PROJECTS_PUBLIC_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_us",
|
||||
comment_permission="comment_us")
|
||||
),
|
||||
|
||||
# tasks
|
||||
migrations.RunSQL(UPDATE_PROJECTS_ANON_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_task",
|
||||
comment_permission="comment_task")
|
||||
),
|
||||
|
||||
migrations.RunSQL(UPDATE_PROJECTS_PUBLIC_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_task",
|
||||
comment_permission="comment_task")
|
||||
),
|
||||
|
||||
# issues
|
||||
migrations.RunSQL(UPDATE_PROJECTS_ANON_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_issue",
|
||||
comment_permission="comment_issue")
|
||||
),
|
||||
|
||||
migrations.RunSQL(UPDATE_PROJECTS_PUBLIC_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_issue",
|
||||
comment_permission="comment_issue")
|
||||
)
|
||||
]
|
|
@ -40,7 +40,7 @@ from taiga.base.utils.sequence import arithmetic_progression
|
|||
from taiga.base.utils.slug import slugify_uniquely
|
||||
from taiga.base.utils.slug import slugify_uniquely_for_queryset
|
||||
|
||||
from taiga.permissions.permissions import ANON_PERMISSIONS, MEMBERS_PERMISSIONS
|
||||
from taiga.permissions.choices import ANON_PERMISSIONS, MEMBERS_PERMISSIONS
|
||||
|
||||
from taiga.projects.notifications.choices import NotifyLevel
|
||||
from taiga.projects.notifications.services import (
|
||||
|
@ -366,7 +366,8 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
|
|||
|
||||
@cached_property
|
||||
def cached_memberships(self):
|
||||
return {m.user.id: m for m in self.memberships.exclude(user__isnull=True).select_related("user", "project", "role")}
|
||||
return {m.user.id: m for m in self.memberships.exclude(user__isnull=True)
|
||||
.select_related("user", "project", "role")}
|
||||
|
||||
def cached_memberships_for_user(self, user):
|
||||
return self.cached_memberships.get(user.id, None)
|
||||
|
@ -966,9 +967,11 @@ class ProjectTemplate(models.Model):
|
|||
project=project)
|
||||
|
||||
if self.priorities:
|
||||
project.default_priority = Priority.objects.get(name=self.default_options["priority"], project=project)
|
||||
project.default_priority = Priority.objects.get(name=self.default_options["priority"],
|
||||
project=project)
|
||||
|
||||
if self.severities:
|
||||
project.default_severity = Severity.objects.get(name=self.default_options["severity"], project=project)
|
||||
project.default_severity = Severity.objects.get(name=self.default_options["severity"],
|
||||
project=project)
|
||||
|
||||
return project
|
||||
|
|
|
@ -35,7 +35,7 @@ from taiga.projects.history.choices import HistoryType
|
|||
from taiga.projects.history.services import (make_key_from_model_object,
|
||||
get_last_snapshot_for_key,
|
||||
get_model_from_key)
|
||||
from taiga.permissions.service import user_has_perm
|
||||
from taiga.permissions.services import user_has_perm
|
||||
|
||||
from .models import HistoryChangeNotification, Watched
|
||||
|
||||
|
|
|
@ -18,18 +18,21 @@
|
|||
from django.utils.translation import ugettext as _
|
||||
|
||||
from taiga.base.api.permissions import TaigaResourcePermission
|
||||
from taiga.base.api.permissions import HasProjectPerm
|
||||
from taiga.base.api.permissions import IsAuthenticated
|
||||
from taiga.base.api.permissions import IsProjectAdmin
|
||||
from taiga.base.api.permissions import AllowAny
|
||||
from taiga.base.api.permissions import IsSuperUser
|
||||
from taiga.base.api.permissions import IsObjectOwner
|
||||
from taiga.base.api.permissions import PermissionComponent
|
||||
|
||||
from taiga.base import exceptions as exc
|
||||
from taiga.projects.models import Membership
|
||||
|
||||
from taiga.permissions.permissions import HasProjectPerm
|
||||
from taiga.permissions.permissions import IsProjectAdmin
|
||||
|
||||
from . import models
|
||||
from . import services
|
||||
|
||||
|
||||
class CanLeaveProject(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if not obj or not request.user.is_authenticated():
|
||||
|
@ -37,20 +40,12 @@ class CanLeaveProject(PermissionComponent):
|
|||
|
||||
try:
|
||||
if not services.can_user_leave_project(request.user, obj):
|
||||
raise exc.PermissionDenied(_("You can't leave the project if you are the owner or there are no more admins"))
|
||||
raise exc.PermissionDenied(_("You can't leave the project if you are the owner or there are "
|
||||
"no more admins"))
|
||||
return True
|
||||
except Membership.DoesNotExist:
|
||||
except models.Membership.DoesNotExist:
|
||||
return False
|
||||
|
||||
class IsMainOwner(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if not obj or not request.user.is_authenticated():
|
||||
return False
|
||||
|
||||
if obj.owner is None:
|
||||
return False
|
||||
|
||||
return obj.owner == request.user
|
||||
|
||||
class ProjectPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
|
@ -79,7 +74,7 @@ class ProjectPermission(TaigaResourcePermission):
|
|||
leave_perms = CanLeaveProject()
|
||||
transfer_validate_token_perms = IsAuthenticated() & HasProjectPerm('view_project')
|
||||
transfer_request_perms = IsProjectAdmin()
|
||||
transfer_start_perms = IsMainOwner()
|
||||
transfer_start_perms = IsObjectOwner()
|
||||
transfer_reject_perms = IsAuthenticated() & HasProjectPerm('view_project')
|
||||
transfer_accept_perms = IsAuthenticated() & HasProjectPerm('view_project')
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from taiga.base import exceptions as exc
|
|||
from taiga.base import response
|
||||
from taiga.base.api import viewsets
|
||||
from taiga.base.api.utils import get_object_or_404
|
||||
from taiga.permissions.service import user_has_perm
|
||||
from taiga.permissions.services import user_has_perm
|
||||
|
||||
from .serializers import ResolverSerializer
|
||||
from . import permissions
|
||||
|
|
|
@ -32,8 +32,8 @@ from taiga.users.serializers import UserBasicInfoSerializer
|
|||
from taiga.users.serializers import ProjectRoleSerializer
|
||||
from taiga.users.validators import RoleExistsValidator
|
||||
|
||||
from taiga.permissions.service import get_user_project_permissions
|
||||
from taiga.permissions.service import is_project_admin, is_project_owner
|
||||
from taiga.permissions.services import get_user_project_permissions
|
||||
from taiga.permissions.services import is_project_admin, is_project_owner
|
||||
from taiga.projects.mixins.serializers import ValidateDuplicatedNameInProjectMixin
|
||||
|
||||
from . import models
|
||||
|
|
|
@ -67,7 +67,6 @@ def project_post_save(sender, instance, created, **kwargs):
|
|||
if instance._importing:
|
||||
return
|
||||
|
||||
|
||||
template = getattr(instance, "creation_template", None)
|
||||
if template is None:
|
||||
ProjectTemplate = apps.get_model("projects", "ProjectTemplate")
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
IsAuthenticated, IsProjectAdmin, AllowAny,
|
||||
IsSuperUser)
|
||||
from taiga.base.api.permissions import TaigaResourcePermission, AllowAny, IsAuthenticated, IsSuperUser
|
||||
from taiga.permissions.permissions import HasProjectPerm, IsProjectAdmin
|
||||
|
||||
from taiga.permissions.permissions import CommentAndOrUpdatePerm
|
||||
|
||||
|
||||
class TaskPermission(TaigaResourcePermission):
|
||||
|
@ -25,8 +26,8 @@ class TaskPermission(TaigaResourcePermission):
|
|||
global_perms = None
|
||||
retrieve_perms = HasProjectPerm('view_tasks')
|
||||
create_perms = HasProjectPerm('add_task')
|
||||
update_perms = HasProjectPerm('modify_task')
|
||||
partial_update_perms = HasProjectPerm('modify_task')
|
||||
update_perms = CommentAndOrUpdatePerm('modify_task', 'comment_task')
|
||||
partial_update_perms = CommentAndOrUpdatePerm('modify_task', 'comment_task')
|
||||
destroy_perms = HasProjectPerm('delete_task')
|
||||
list_perms = AllowAny()
|
||||
csv_perms = AllowAny()
|
||||
|
|
|
@ -112,7 +112,6 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi
|
|||
|
||||
return super().update(request, *args, **kwargs)
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
qs = qs.prefetch_related("role_points",
|
||||
|
|
|
@ -15,16 +15,19 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
IsAuthenticated, IsProjectAdmin,
|
||||
AllowAny, IsSuperUser)
|
||||
from taiga.base.api.permissions import TaigaResourcePermission, AllowAny, IsAuthenticated, IsSuperUser
|
||||
from taiga.permissions.permissions import HasProjectPerm, IsProjectAdmin
|
||||
|
||||
from taiga.permissions.permissions import CommentAndOrUpdatePerm
|
||||
|
||||
|
||||
class UserStoryPermission(TaigaResourcePermission):
|
||||
enought_perms = IsProjectAdmin() | IsSuperUser()
|
||||
global_perms = None
|
||||
retrieve_perms = HasProjectPerm('view_us')
|
||||
create_perms = HasProjectPerm('add_us_to_project') | HasProjectPerm('add_us')
|
||||
update_perms = HasProjectPerm('modify_us')
|
||||
partial_update_perms = HasProjectPerm('modify_us')
|
||||
update_perms = CommentAndOrUpdatePerm('modify_us', 'comment_us')
|
||||
partial_update_perms = CommentAndOrUpdatePerm('modify_us', 'comment_us')
|
||||
destroy_perms = HasProjectPerm('delete_us')
|
||||
list_perms = AllowAny()
|
||||
filters_data_perms = AllowAny()
|
||||
|
|
|
@ -19,6 +19,8 @@ from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
|||
IsAuthenticated, IsProjectAdmin, AllowAny,
|
||||
IsSuperUser)
|
||||
|
||||
from taiga.permissions.permissions import CommentAndOrUpdatePerm
|
||||
|
||||
|
||||
class WikiPagePermission(TaigaResourcePermission):
|
||||
enought_perms = IsProjectAdmin() | IsSuperUser()
|
||||
|
@ -26,8 +28,8 @@ class WikiPagePermission(TaigaResourcePermission):
|
|||
retrieve_perms = HasProjectPerm('view_wiki_pages')
|
||||
by_slug_perms = HasProjectPerm('view_wiki_pages')
|
||||
create_perms = HasProjectPerm('add_wiki_page')
|
||||
update_perms = HasProjectPerm('modify_wiki_page')
|
||||
partial_update_perms = HasProjectPerm('modify_wiki_page')
|
||||
update_perms = CommentAndOrUpdatePerm('modify_wiki_page', 'comment_wiki_page')
|
||||
partial_update_perms = CommentAndOrUpdatePerm('modify_wiki_page', 'comment_wiki_page')
|
||||
destroy_perms = HasProjectPerm('delete_wiki_page')
|
||||
list_perms = AllowAny()
|
||||
render_perms = AllowAny()
|
||||
|
|
|
@ -21,7 +21,7 @@ from taiga.base.api import viewsets
|
|||
|
||||
from taiga.base import response
|
||||
from taiga.base.api.utils import get_object_or_404
|
||||
from taiga.permissions.service import user_has_perm
|
||||
from taiga.permissions.services import user_has_perm
|
||||
|
||||
from . import services
|
||||
from . import serializers
|
||||
|
|
|
@ -15,13 +15,17 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
AllowAny)
|
||||
from taiga.base.api.permissions import TaigaResourcePermission, AllowAny, IsSuperUser
|
||||
from taiga.permissions.permissions import HasProjectPerm, IsProjectAdmin
|
||||
|
||||
|
||||
class UserTimelinePermission(TaigaResourcePermission):
|
||||
enought_perms = IsSuperUser()
|
||||
global_perms = None
|
||||
retrieve_perms = AllowAny()
|
||||
|
||||
|
||||
class ProjectTimelinePermission(TaigaResourcePermission):
|
||||
enought_perms = IsProjectAdmin() | IsSuperUser()
|
||||
global_perms = None
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
|
|
|
@ -44,7 +44,6 @@ def _clean_description_fields(values_diff):
|
|||
|
||||
|
||||
def on_new_history_entry(sender, instance, created, **kwargs):
|
||||
|
||||
if instance._importing:
|
||||
return
|
||||
|
||||
|
@ -81,6 +80,10 @@ def on_new_history_entry(sender, instance, created, **kwargs):
|
|||
if instance.delete_comment_date:
|
||||
extra_data["comment_deleted"] = True
|
||||
|
||||
# Detect edited comment
|
||||
if instance.comment_versions is not None and len(instance.comment_versions)>0:
|
||||
extra_data["comment_edited"] = True
|
||||
|
||||
created_datetime = instance.created_at
|
||||
_push_to_timelines(project, user, obj, event_type, created_datetime, extra_data=extra_data)
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-05-19 10:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import djorm_pgarray.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0018_remove_vote_issues_in_roles_permissions_field'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='role',
|
||||
name='permissions',
|
||||
field=djorm_pgarray.fields.TextArrayField(choices=[('view_project', 'View project'), ('view_milestones', 'View milestones'), ('add_milestone', 'Add milestone'), ('modify_milestone', 'Modify milestone'), ('delete_milestone', 'Delete milestone'), ('view_us', 'View user story'), ('add_us', 'Add user story'), ('modify_us', 'Modify user story'), ('comment_us', 'Comment user story'), ('delete_us', 'Delete user story'), ('view_tasks', 'View tasks'), ('add_task', 'Add task'), ('modify_task', 'Modify task'), ('comment_task', 'Comment task'), ('delete_task', 'Delete task'), ('view_issues', 'View issues'), ('add_issue', 'Add issue'), ('modify_issue', 'Modify issue'), ('comment_issue', 'Comment issue'), ('delete_issue', 'Delete issue'), ('view_wiki_pages', 'View wiki pages'), ('add_wiki_page', 'Add wiki page'), ('modify_wiki_page', 'Modify wiki page'), ('comment_wiki_page', 'Comment wiki page'), ('delete_wiki_page', 'Delete wiki page'), ('view_wiki_links', 'View wiki links'), ('add_wiki_link', 'Add wiki link'), ('modify_wiki_link', 'Modify wiki link'), ('delete_wiki_link', 'Delete wiki link')], dbtype='text', default=[], verbose_name='permissions'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-05-25 12:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
UPDATE_ROLES_PERMISSIONS_SQL = """
|
||||
UPDATE users_role
|
||||
SET
|
||||
PERMISSIONS = array_append(PERMISSIONS, '{comment_permission}')
|
||||
WHERE
|
||||
'{base_permission}' = ANY(PERMISSIONS)
|
||||
AND
|
||||
NOT '{comment_permission}' = ANY(PERMISSIONS)
|
||||
"""
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0019_auto_20160519_1058'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
# user stories
|
||||
migrations.RunSQL(UPDATE_ROLES_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_us",
|
||||
comment_permission="comment_us")
|
||||
),
|
||||
|
||||
# tasks
|
||||
migrations.RunSQL(UPDATE_ROLES_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_task",
|
||||
comment_permission="comment_task")
|
||||
),
|
||||
|
||||
# issues
|
||||
migrations.RunSQL(UPDATE_ROLES_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_issue",
|
||||
comment_permission="comment_issue")
|
||||
),
|
||||
|
||||
# issues
|
||||
migrations.RunSQL(UPDATE_ROLES_PERMISSIONS_SQL.format(
|
||||
base_permission="modify_issue",
|
||||
comment_permission="comment_issue")
|
||||
)
|
||||
]
|
|
@ -38,7 +38,7 @@ from djorm_pgarray.fields import TextArrayField
|
|||
from taiga.auth.tokens import get_token_for_user
|
||||
from taiga.base.utils.slug import slugify_uniquely
|
||||
from taiga.base.utils.files import get_file_path
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
from taiga.projects.choices import BLOCKED_BY_OWNER_LEAVING
|
||||
from taiga.projects.notifications.choices import NotifyLevel
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
from taiga.base.api.permissions import (TaigaResourcePermission, IsProjectAdmin,
|
||||
AllowAny, PermissionComponent)
|
||||
|
||||
from taiga.permissions.service import is_project_admin
|
||||
from taiga.permissions.services import is_project_admin
|
||||
|
||||
|
||||
class IsWebhookProjectAdmin(PermissionComponent):
|
||||
|
|
|
@ -26,7 +26,7 @@ from .utils import DUMMY_BMP_DATA
|
|||
|
||||
import factory
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,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.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects import choices as project_choices
|
||||
from taiga.projects.attachments.serializers import AttachmentSerializer
|
||||
|
||||
|
@ -38,11 +38,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
@ -491,9 +491,9 @@ def test_wiki_attachment_patch(client, data, data_wiki):
|
|||
attachment_data = json.dumps(attachment_data)
|
||||
|
||||
results = helper_test_http_method(client, 'patch', public_url, attachment_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'patch', private_url1, attachment_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
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)
|
||||
|
@ -583,9 +583,9 @@ def test_wiki_attachment_delete(client, data, data_wiki):
|
|||
]
|
||||
|
||||
results = helper_test_http_method(client, 'delete', public_url, None, [None, data.registered_user])
|
||||
assert results == [401, 204]
|
||||
assert results == [401, 403]
|
||||
results = helper_test_http_method(client, 'delete', private_url1, None, [None, data.registered_user])
|
||||
assert results == [401, 204]
|
||||
assert results == [401, 403]
|
||||
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)
|
||||
|
@ -721,7 +721,7 @@ def test_wiki_attachment_create(client, data, data_wiki):
|
|||
content_type=MULTIPART_CONTENT,
|
||||
after_each_request=_after_each_request_hook)
|
||||
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
assert results == [401, 403, 403, 201, 201]
|
||||
|
||||
attachment_data = {"description": "test",
|
||||
"object_id": data_wiki.blocked_wiki_attachment.object_id,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.base.utils import json
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects.history.models import HistoryEntry
|
||||
from taiga.projects.history.choices import HistoryType
|
||||
from taiga.projects.history.services import make_key_from_model_object
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
||||
|
@ -21,19 +26,19 @@ def teardown_module(module):
|
|||
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.registered_user = f.UserFactory.create(full_name="registered_user")
|
||||
m.project_member_with_perms = f.UserFactory.create(full_name="project_member_with_perms")
|
||||
m.project_member_without_perms = f.UserFactory.create(full_name="project_member_without_perms")
|
||||
m.project_owner = f.UserFactory.create(full_name="project_owner")
|
||||
m.other_user = f.UserFactory.create(full_name="other_user")
|
||||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
@ -76,39 +81,33 @@ def data():
|
|||
return m
|
||||
|
||||
|
||||
#########################################################
|
||||
## User stories
|
||||
#########################################################
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_us(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_user_story = f.UserStoryFactory(project=data.public_project, ref=1)
|
||||
m.public_history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing public",
|
||||
key=make_key_from_model_object(m.public_user_story),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
|
||||
m.private_user_story1 = f.UserStoryFactory(project=data.private_project1, ref=5)
|
||||
m.private_history_entry1 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 1",
|
||||
key=make_key_from_model_object(m.private_user_story1),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
m.private_user_story2 = f.UserStoryFactory(project=data.private_project2, ref=9)
|
||||
return m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_task(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_task = f.TaskFactory(project=data.public_project, ref=2)
|
||||
m.private_task1 = f.TaskFactory(project=data.private_project1, ref=6)
|
||||
m.private_task2 = f.TaskFactory(project=data.private_project2, ref=10)
|
||||
return m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_issue(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_issue = f.IssueFactory(project=data.public_project, ref=3)
|
||||
m.private_issue1 = f.IssueFactory(project=data.private_project1, ref=7)
|
||||
m.private_issue2 = f.IssueFactory(project=data.private_project2, ref=11)
|
||||
return m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_wiki(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_wiki = f.WikiPageFactory(project=data.public_project, slug=4)
|
||||
m.private_wiki1 = f.WikiPageFactory(project=data.private_project1, slug=8)
|
||||
m.private_wiki2 = f.WikiPageFactory(project=data.private_project2, slug=12)
|
||||
m.private_history_entry2 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 2",
|
||||
key=make_key_from_model_object(m.private_user_story2),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
return m
|
||||
|
||||
|
||||
|
@ -133,6 +132,222 @@ def test_user_story_history_retrieve(client, data, data_us):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_user_story_action_edit_comment(client, data, data_us):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('userstory-history-edit-comment', kwargs={"pk": data_us.public_user_story.pk}),
|
||||
data_us.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('userstory-history-edit-comment', kwargs={"pk": data_us.private_user_story1.pk}),
|
||||
data_us.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('userstory-history-edit-comment', kwargs={"pk": data_us.private_user_story2.pk}),
|
||||
data_us.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
data = json.dumps({"comment": "testing update comment"})
|
||||
|
||||
results = helper_test_http_method(client, 'post', public_url, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url1, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url2, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_user_story_action_delete_comment(client, data, data_us):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('userstory-history-delete-comment', kwargs={"pk": data_us.public_user_story.pk}),
|
||||
data_us.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('userstory-history-delete-comment', kwargs={"pk": data_us.private_user_story1.pk}),
|
||||
data_us.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('userstory-history-delete-comment', kwargs={"pk": data_us.private_user_story2.pk}),
|
||||
data_us.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.public_history_entry.delete_comment_date = None
|
||||
data_us.public_history_entry.delete_comment_user = None
|
||||
data_us.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.private_history_entry1.delete_comment_date = None
|
||||
data_us.private_history_entry1.delete_comment_user = None
|
||||
data_us.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.private_history_entry2.delete_comment_date = None
|
||||
data_us.private_history_entry2.delete_comment_user = None
|
||||
data_us.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_user_story_action_undelete_comment(client, data, data_us):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('userstory-history-undelete-comment', kwargs={"pk": data_us.public_user_story.pk}),
|
||||
data_us.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('userstory-history-undelete-comment', kwargs={"pk": data_us.private_user_story1.pk}),
|
||||
data_us.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('userstory-history-undelete-comment', kwargs={"pk": data_us.private_user_story2.pk}),
|
||||
data_us.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.public_history_entry.delete_comment_date = timezone.now()
|
||||
data_us.public_history_entry.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_us.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.private_history_entry1.delete_comment_date = timezone.now()
|
||||
data_us.private_history_entry1.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_us.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_us.private_history_entry2.delete_comment_date = timezone.now()
|
||||
data_us.private_history_entry2.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_us.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_user_story_action_comment_versions(client, data, data_us):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('userstory-history-comment-versions', kwargs={"pk": data_us.public_user_story.pk}),
|
||||
data_us.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('userstory-history-comment-versions', kwargs={"pk": data_us.private_user_story1.pk}),
|
||||
data_us.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('userstory-history-comment-versions', kwargs={"pk": data_us.private_user_story2.pk}),
|
||||
data_us.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner,
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
#########################################################
|
||||
## Tasks
|
||||
#########################################################
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_task(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_task = f.TaskFactory(project=data.public_project, ref=2)
|
||||
m.public_history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing public",
|
||||
key=make_key_from_model_object(m.public_task),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
|
||||
m.private_task1 = f.TaskFactory(project=data.private_project1, ref=6)
|
||||
m.private_history_entry1 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 1",
|
||||
key=make_key_from_model_object(m.private_task1),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
m.private_task2 = f.TaskFactory(project=data.private_project2, ref=10)
|
||||
m.private_history_entry2 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 2",
|
||||
key=make_key_from_model_object(m.private_task2),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
return m
|
||||
|
||||
|
||||
def test_task_history_retrieve(client, data, data_task):
|
||||
public_url = reverse('task-history-detail', kwargs={"pk": data_task.public_task.pk})
|
||||
private_url1 = reverse('task-history-detail', kwargs={"pk": data_task.private_task1.pk})
|
||||
|
@ -154,6 +369,222 @@ def test_task_history_retrieve(client, data, data_task):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_task_action_edit_comment(client, data, data_task):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('task-history-edit-comment', kwargs={"pk": data_task.public_task.pk}),
|
||||
data_task.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('task-history-edit-comment', kwargs={"pk": data_task.private_task1.pk}),
|
||||
data_task.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('task-history-edit-comment', kwargs={"pk": data_task.private_task2.pk}),
|
||||
data_task.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
data = json.dumps({"comment": "testing update comment"})
|
||||
|
||||
results = helper_test_http_method(client, 'post', public_url, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url1, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url2, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_task_action_delete_comment(client, data, data_task):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('task-history-delete-comment', kwargs={"pk": data_task.public_task.pk}),
|
||||
data_task.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('task-history-delete-comment', kwargs={"pk": data_task.private_task1.pk}),
|
||||
data_task.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('task-history-delete-comment', kwargs={"pk": data_task.private_task2.pk}),
|
||||
data_task.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.public_history_entry.delete_comment_date = None
|
||||
data_task.public_history_entry.delete_comment_user = None
|
||||
data_task.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.private_history_entry1.delete_comment_date = None
|
||||
data_task.private_history_entry1.delete_comment_user = None
|
||||
data_task.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.private_history_entry2.delete_comment_date = None
|
||||
data_task.private_history_entry2.delete_comment_user = None
|
||||
data_task.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_task_action_undelete_comment(client, data, data_task):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('task-history-undelete-comment', kwargs={"pk": data_task.public_task.pk}),
|
||||
data_task.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('task-history-undelete-comment', kwargs={"pk": data_task.private_task1.pk}),
|
||||
data_task.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('task-history-undelete-comment', kwargs={"pk": data_task.private_task2.pk}),
|
||||
data_task.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.public_history_entry.delete_comment_date = timezone.now()
|
||||
data_task.public_history_entry.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_task.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.private_history_entry1.delete_comment_date = timezone.now()
|
||||
data_task.private_history_entry1.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_task.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_task.private_history_entry2.delete_comment_date = timezone.now()
|
||||
data_task.private_history_entry2.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_task.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_task_action_comment_versions(client, data, data_task):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('task-history-comment-versions', kwargs={"pk": data_task.public_task.pk}),
|
||||
data_task.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('task-history-comment-versions', kwargs={"pk": data_task.private_task1.pk}),
|
||||
data_task.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('task-history-comment-versions', kwargs={"pk": data_task.private_task2.pk}),
|
||||
data_task.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner,
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
#########################################################
|
||||
## Issues
|
||||
#########################################################
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_issue(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_issue = f.IssueFactory(project=data.public_project, ref=3)
|
||||
m.public_history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing public",
|
||||
key=make_key_from_model_object(m.public_issue),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
|
||||
m.private_issue1 = f.IssueFactory(project=data.private_project1, ref=7)
|
||||
m.private_history_entry1 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 1",
|
||||
key=make_key_from_model_object(m.private_issue1),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
m.private_issue2 = f.IssueFactory(project=data.private_project2, ref=11)
|
||||
m.private_history_entry2 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 2",
|
||||
key=make_key_from_model_object(m.private_issue2),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
return m
|
||||
|
||||
|
||||
def test_issue_history_retrieve(client, data, data_issue):
|
||||
public_url = reverse('issue-history-detail', kwargs={"pk": data_issue.public_issue.pk})
|
||||
private_url1 = reverse('issue-history-detail', kwargs={"pk": data_issue.private_issue1.pk})
|
||||
|
@ -175,6 +606,222 @@ def test_issue_history_retrieve(client, data, data_issue):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_issue_action_edit_comment(client, data, data_issue):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('issue-history-edit-comment', kwargs={"pk": data_issue.public_issue.pk}),
|
||||
data_issue.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('issue-history-edit-comment', kwargs={"pk": data_issue.private_issue1.pk}),
|
||||
data_issue.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('issue-history-edit-comment', kwargs={"pk": data_issue.private_issue2.pk}),
|
||||
data_issue.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
data = json.dumps({"comment": "testing update comment"})
|
||||
|
||||
results = helper_test_http_method(client, 'post', public_url, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url1, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url2, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_issue_action_delete_comment(client, data, data_issue):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('issue-history-delete-comment', kwargs={"pk": data_issue.public_issue.pk}),
|
||||
data_issue.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('issue-history-delete-comment', kwargs={"pk": data_issue.private_issue1.pk}),
|
||||
data_issue.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('issue-history-delete-comment', kwargs={"pk": data_issue.private_issue2.pk}),
|
||||
data_issue.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.public_history_entry.delete_comment_date = None
|
||||
data_issue.public_history_entry.delete_comment_user = None
|
||||
data_issue.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.private_history_entry1.delete_comment_date = None
|
||||
data_issue.private_history_entry1.delete_comment_user = None
|
||||
data_issue.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.private_history_entry2.delete_comment_date = None
|
||||
data_issue.private_history_entry2.delete_comment_user = None
|
||||
data_issue.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_issue_action_undelete_comment(client, data, data_issue):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('issue-history-undelete-comment', kwargs={"pk": data_issue.public_issue.pk}),
|
||||
data_issue.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('issue-history-undelete-comment', kwargs={"pk": data_issue.private_issue1.pk}),
|
||||
data_issue.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('issue-history-undelete-comment', kwargs={"pk": data_issue.private_issue2.pk}),
|
||||
data_issue.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.public_history_entry.delete_comment_date = timezone.now()
|
||||
data_issue.public_history_entry.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_issue.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.private_history_entry1.delete_comment_date = timezone.now()
|
||||
data_issue.private_history_entry1.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_issue.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_issue.private_history_entry2.delete_comment_date = timezone.now()
|
||||
data_issue.private_history_entry2.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_issue.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_issue_action_comment_versions(client, data, data_issue):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('issue-history-comment-versions', kwargs={"pk": data_issue.public_issue.pk}),
|
||||
data_issue.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('issue-history-comment-versions', kwargs={"pk": data_issue.private_issue1.pk}),
|
||||
data_issue.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('issue-history-comment-versions', kwargs={"pk": data_issue.private_issue2.pk}),
|
||||
data_issue.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner,
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
#########################################################
|
||||
## Wiki pages
|
||||
#########################################################
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_wiki(data):
|
||||
m = type("Models", (object,), {})
|
||||
m.public_wiki = f.WikiPageFactory(project=data.public_project, slug=4)
|
||||
m.public_history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing public",
|
||||
key=make_key_from_model_object(m.public_wiki),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
|
||||
m.private_wiki1 = f.WikiPageFactory(project=data.private_project1, slug=8)
|
||||
m.private_history_entry1 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 1",
|
||||
key=make_key_from_model_object(m.private_wiki1),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
m.private_wiki2 = f.WikiPageFactory(project=data.private_project2, slug=12)
|
||||
m.private_history_entry2 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing 2",
|
||||
key=make_key_from_model_object(m.private_wiki2),
|
||||
diff={},
|
||||
user={"pk": data.project_member_with_perms.pk})
|
||||
return m
|
||||
|
||||
|
||||
def test_wiki_history_retrieve(client, data, data_wiki):
|
||||
public_url = reverse('wiki-history-detail', kwargs={"pk": data_wiki.public_wiki.pk})
|
||||
private_url1 = reverse('wiki-history-detail', kwargs={"pk": data_wiki.private_wiki1.pk})
|
||||
|
@ -194,3 +841,189 @@ def test_wiki_history_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]
|
||||
|
||||
|
||||
def test_wiki_action_edit_comment(client, data, data_wiki):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('wiki-history-edit-comment', kwargs={"pk": data_wiki.public_wiki.pk}),
|
||||
data_wiki.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('wiki-history-edit-comment', kwargs={"pk": data_wiki.private_wiki1.pk}),
|
||||
data_wiki.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('wiki-history-edit-comment', kwargs={"pk": data_wiki.private_wiki2.pk}),
|
||||
data_wiki.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
data = json.dumps({"comment": "testing update comment"})
|
||||
|
||||
results = helper_test_http_method(client, 'post', public_url, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url1, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'post', private_url2, data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_wiki_action_delete_comment(client, data, data_wiki):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('wiki-history-delete-comment', kwargs={"pk": data_wiki.public_wiki.pk}),
|
||||
data_wiki.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('wiki-history-delete-comment', kwargs={"pk": data_wiki.private_wiki1.pk}),
|
||||
data_wiki.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('wiki-history-delete-comment', kwargs={"pk": data_wiki.private_wiki2.pk}),
|
||||
data_wiki.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.public_history_entry.delete_comment_date = None
|
||||
data_wiki.public_history_entry.delete_comment_user = None
|
||||
data_wiki.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.private_history_entry1.delete_comment_date = None
|
||||
data_wiki.private_history_entry1.delete_comment_user = None
|
||||
data_wiki.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.private_history_entry2.delete_comment_date = None
|
||||
data_wiki.private_history_entry2.delete_comment_user = None
|
||||
data_wiki.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_wiki_action_undelete_comment(client, data, data_wiki):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('wiki-history-undelete-comment', kwargs={"pk": data_wiki.public_wiki.pk}),
|
||||
data_wiki.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('wiki-history-undelete-comment', kwargs={"pk": data_wiki.private_wiki1.pk}),
|
||||
data_wiki.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('wiki-history-undelete-comment', kwargs={"pk": data_wiki.private_wiki2.pk}),
|
||||
data_wiki.private_history_entry2.id
|
||||
)
|
||||
|
||||
users_and_statuses = [
|
||||
(None, 401),
|
||||
(data.registered_user, 403),
|
||||
(data.project_member_without_perms, 403),
|
||||
(data.project_member_with_perms, 200),
|
||||
(data.project_owner, 200),
|
||||
]
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.public_history_entry.delete_comment_date = timezone.now()
|
||||
data_wiki.public_history_entry.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_wiki.public_history_entry.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(public_url)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.private_history_entry1.delete_comment_date = timezone.now()
|
||||
data_wiki.private_history_entry1.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_wiki.private_history_entry1.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url1)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
for user, status_code in users_and_statuses:
|
||||
data_wiki.private_history_entry2.delete_comment_date = timezone.now()
|
||||
data_wiki.private_history_entry2.delete_comment_user = {"pk": data.project_member_with_perms.pk}
|
||||
data_wiki.private_history_entry2.save()
|
||||
|
||||
if user:
|
||||
client.login(user)
|
||||
else:
|
||||
client.logout()
|
||||
response = client.json.post(private_url2)
|
||||
error_mesage = "{} != {} for {}".format(response.status_code, status_code, user)
|
||||
assert response.status_code == status_code, error_mesage
|
||||
|
||||
|
||||
def test_wiki_action_comment_versions(client, data, data_wiki):
|
||||
public_url = "{}?id={}".format(
|
||||
reverse('wiki-history-comment-versions', kwargs={"pk": data_wiki.public_wiki.pk}),
|
||||
data_wiki.public_history_entry.id
|
||||
)
|
||||
private_url1 = "{}?id={}".format(
|
||||
reverse('wiki-history-comment-versions', kwargs={"pk": data_wiki.private_wiki1.pk}),
|
||||
data_wiki.private_history_entry1.id
|
||||
)
|
||||
private_url2 = "{}?id={}".format(
|
||||
reverse('wiki-history-comment-versions', kwargs={"pk": data_wiki.private_wiki2.pk}),
|
||||
data_wiki.private_history_entry2.id
|
||||
)
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner,
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
|
|
@ -21,8 +21,8 @@ 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)
|
||||
from taiga.permissions.choices import (MEMBERS_PERMISSIONS,
|
||||
ANON_PERMISSIONS)
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method
|
||||
|
@ -43,11 +43,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -4,7 +4,7 @@ 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.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.base.utils import json
|
||||
|
||||
from tests import factories as f
|
||||
|
@ -39,12 +39,12 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
issues_csv_uuid=uuid.uuid4().hex)
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
issues_csv_uuid=uuid.uuid4().hex)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
|
@ -132,6 +132,55 @@ def data():
|
|||
return m
|
||||
|
||||
|
||||
def test_issue_list(client, data):
|
||||
url = reverse('issues-list')
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(issues_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(issues_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_issue_list_filter_by_project_ok(client, data):
|
||||
url = "{}?project={}".format(reverse("issues-list"), data.public_project.pk)
|
||||
|
||||
client.login(data.project_owner)
|
||||
response = client.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert len(response.data) == 1
|
||||
|
||||
|
||||
def test_issue_list_filter_by_project_error(client, data):
|
||||
url = "{}?project={}".format(reverse("issues-list"), "-ERROR-")
|
||||
|
||||
client.login(data.project_owner)
|
||||
response = client.get(url)
|
||||
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
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})
|
||||
|
@ -156,7 +205,67 @@ def test_issue_retrieve(client, data):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_issue_update(client, data):
|
||||
def test_issue_create(client, data):
|
||||
url = reverse('issues-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 1,
|
||||
"project": data.public_project.pk,
|
||||
"severity": data.public_project.severities.all()[0].pk,
|
||||
"priority": data.public_project.priorities.all()[0].pk,
|
||||
"status": data.public_project.issue_statuses.all()[0].pk,
|
||||
"type": data.public_project.issue_types.all()[0].pk,
|
||||
})
|
||||
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": 2,
|
||||
"project": data.private_project1.pk,
|
||||
"severity": data.private_project1.severities.all()[0].pk,
|
||||
"priority": data.private_project1.priorities.all()[0].pk,
|
||||
"status": data.private_project1.issue_statuses.all()[0].pk,
|
||||
"type": data.private_project1.issue_types.all()[0].pk,
|
||||
})
|
||||
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.private_project2.pk,
|
||||
"severity": data.private_project2.severities.all()[0].pk,
|
||||
"priority": data.private_project2.priorities.all()[0].pk,
|
||||
"status": data.private_project2.issue_statuses.all()[0].pk,
|
||||
"type": data.private_project2.issue_types.all()[0].pk,
|
||||
})
|
||||
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_put_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})
|
||||
|
@ -171,32 +280,116 @@ def test_issue_update(client, data):
|
|||
]
|
||||
|
||||
with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"):
|
||||
issue_data = IssueSerializer(data.public_issue).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
issue_data = IssueSerializer(data.public_issue).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue1).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
issue_data = IssueSerializer(data.private_issue1).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue2).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', private_url2, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
issue_data = IssueSerializer(data.private_issue2).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data = json.dumps(issue_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]
|
||||
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):
|
||||
def test_issue_put_comment(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,
|
||||
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"):
|
||||
issue_data = IssueSerializer(data.public_issue).data
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue1).data
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue2).data
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_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["comment"] = "test comment"
|
||||
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_put_update_and_comment(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,
|
||||
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"):
|
||||
issue_data = IssueSerializer(data.public_issue).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue1).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, issue_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
issue_data = IssueSerializer(data.private_issue2).data
|
||||
issue_data["subject"] = "test"
|
||||
issue_data["comment"] = "test comment"
|
||||
issue_data = json.dumps(issue_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["comment"] = "test comment"
|
||||
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_put_update_with_project_change(client):
|
||||
user1 = f.UserFactory.create()
|
||||
user2 = f.UserFactory.create()
|
||||
user3 = f.UserFactory.create()
|
||||
|
@ -309,6 +502,118 @@ def test_issue_update_with_project_change(client):
|
|||
issue.save()
|
||||
|
||||
|
||||
def test_issue_patch_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,
|
||||
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({"subject": "test", "version": data.public_issue.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "version": data.private_issue1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "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({"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_patch_comment(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,
|
||||
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({"comment": "test comment", "version": data.public_issue.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "version": data.private_issue1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "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({"comment": "test comment", "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_patch_update_and_comment(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,
|
||||
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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.public_issue.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.private_issue1.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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_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})
|
||||
|
@ -332,148 +637,7 @@ def test_issue_delete(client, data):
|
|||
assert results == [401, 403, 403, 451]
|
||||
|
||||
|
||||
def test_issue_list(client, data):
|
||||
url = reverse('issues-list')
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(issues_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(issues_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
issues_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_issue_list_filter_by_project_ok(client, data):
|
||||
url = "{}?project={}".format(reverse("issues-list"), data.public_project.pk)
|
||||
|
||||
client.login(data.project_owner)
|
||||
response = client.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert len(response.data) == 1
|
||||
|
||||
|
||||
def test_issue_list_filter_by_project_error(client, data):
|
||||
url = "{}?project={}".format(reverse("issues-list"), "-ERROR-")
|
||||
|
||||
client.login(data.project_owner)
|
||||
response = client.get(url)
|
||||
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
def test_issue_create(client, data):
|
||||
url = reverse('issues-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 1,
|
||||
"project": data.public_project.pk,
|
||||
"severity": data.public_project.severities.all()[0].pk,
|
||||
"priority": data.public_project.priorities.all()[0].pk,
|
||||
"status": data.public_project.issue_statuses.all()[0].pk,
|
||||
"type": data.public_project.issue_types.all()[0].pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users)
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 2,
|
||||
"project": data.private_project1.pk,
|
||||
"severity": data.private_project1.severities.all()[0].pk,
|
||||
"priority": data.private_project1.priorities.all()[0].pk,
|
||||
"status": data.private_project1.issue_statuses.all()[0].pk,
|
||||
"type": data.private_project1.issue_types.all()[0].pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users)
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 3,
|
||||
"project": data.private_project2.pk,
|
||||
"severity": data.private_project2.severities.all()[0].pk,
|
||||
"priority": data.private_project2.priorities.all()[0].pk,
|
||||
"status": data.private_project2.issue_statuses.all()[0].pk,
|
||||
"type": data.private_project2.issue_types.all()[0].pk,
|
||||
})
|
||||
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,
|
||||
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({"subject": "test", "version": data.public_issue.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "version": data.private_issue1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "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({"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):
|
||||
def test_issue_action_bulk_create(client, data):
|
||||
data.public_issue.project.default_issue_status = f.IssueStatusFactory()
|
||||
data.public_issue.project.default_issue_type = f.IssueTypeFactory()
|
||||
data.public_issue.project.default_priority = f.PriorityFactory()
|
||||
|
@ -511,12 +675,12 @@ def test_issue_bulk_create(client, data):
|
|||
bulk_data = json.dumps({"bulk_issues": "test1\ntest2",
|
||||
"project_id": data.public_issue.project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, bulk_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
bulk_data = json.dumps({"bulk_issues": "test1\ntest2",
|
||||
"project_id": data.private_issue1.project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, bulk_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
bulk_data = json.dumps({"bulk_issues": "test1\ntest2",
|
||||
"project_id": data.private_issue2.project.pk})
|
||||
|
@ -633,34 +797,6 @@ def test_issue_voters_retrieve(client, data):
|
|||
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_project2.issues_csv_uuid
|
||||
csv_blocked_uuid = data.blocked_project.issues_csv_uuid
|
||||
|
||||
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', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
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})
|
||||
|
@ -762,3 +898,31 @@ def test_issue_watchers_retrieve(client, data):
|
|||
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_project2.issues_csv_uuid
|
||||
csv_blocked_uuid = data.blocked_project.issues_csv_uuid
|
||||
|
||||
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', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
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]
|
||||
|
|
|
@ -6,7 +6,7 @@ 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
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
||||
|
@ -35,11 +35,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -2,7 +2,7 @@ import uuid
|
|||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.base.utils import json
|
||||
|
||||
from tests import factories as f
|
||||
|
@ -38,11 +38,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -4,7 +4,7 @@ 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
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method
|
||||
|
|
|
@ -4,7 +4,7 @@ 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
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method, helper_test_http_method_and_count
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
||||
|
@ -29,12 +29,12 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
slug="public")
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
slug="private1")
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method_and_keys, disconnect_signals, reconnect_signals
|
||||
|
@ -29,11 +29,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -21,8 +21,8 @@ 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)
|
||||
from taiga.permissions.choices import (MEMBERS_PERMISSIONS,
|
||||
ANON_PERMISSIONS)
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method
|
||||
|
@ -43,11 +43,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects.occ import OCCResourceMixin
|
||||
|
||||
from tests import factories as f
|
||||
|
@ -39,12 +39,12 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
tasks_csv_uuid=uuid.uuid4().hex)
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
tasks_csv_uuid=uuid.uuid4().hex)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
|
@ -142,6 +142,36 @@ def data():
|
|||
return m
|
||||
|
||||
|
||||
def test_task_list(client, data):
|
||||
url = reverse('tasks-list')
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(tasks_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(tasks_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
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})
|
||||
|
@ -166,7 +196,55 @@ def test_task_retrieve(client, data):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_task_update(client, data):
|
||||
def test_task_create(client, data):
|
||||
url = reverse('tasks-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 1,
|
||||
"project": data.public_project.pk,
|
||||
"status": data.public_project.task_statuses.all()[0].pk,
|
||||
})
|
||||
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": 2,
|
||||
"project": data.private_project1.pk,
|
||||
"status": data.private_project1.task_statuses.all()[0].pk,
|
||||
})
|
||||
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.private_project2.pk,
|
||||
"status": data.private_project2.task_statuses.all()[0].pk,
|
||||
})
|
||||
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_put_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})
|
||||
|
@ -181,32 +259,116 @@ def test_task_update(client, data):
|
|||
]
|
||||
|
||||
with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"):
|
||||
task_data = TaskSerializer(data.public_task).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
task_data = TaskSerializer(data.public_task).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task1).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
task_data = TaskSerializer(data.private_task1).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task2).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', private_url2, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
task_data = TaskSerializer(data.private_task2).data
|
||||
task_data["subject"] = "test"
|
||||
task_data = json.dumps(task_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]
|
||||
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):
|
||||
def test_task_put_comment(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,
|
||||
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"):
|
||||
task_data = TaskSerializer(data.public_task).data
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task1).data
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task2).data
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_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["comment"] = "test comment"
|
||||
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_put_update_and_comment(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,
|
||||
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"):
|
||||
task_data = TaskSerializer(data.public_task).data
|
||||
task_data["subject"] = "test"
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task1).data
|
||||
task_data["subject"] = "test"
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, task_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
task_data = TaskSerializer(data.private_task2).data
|
||||
task_data["subject"] = "test"
|
||||
task_data["comment"] = "test comment"
|
||||
task_data = json.dumps(task_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["comment"] = "test comment"
|
||||
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_put_update_with_project_change(client):
|
||||
user1 = f.UserFactory.create()
|
||||
user2 = f.UserFactory.create()
|
||||
user3 = f.UserFactory.create()
|
||||
|
@ -301,107 +463,7 @@ def test_task_update_with_project_change(client):
|
|||
task.save()
|
||||
|
||||
|
||||
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,
|
||||
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 == [401, 403, 403, 204]
|
||||
results = helper_test_http_method(client, 'delete', private_url1, None, users)
|
||||
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):
|
||||
url = reverse('tasks-list')
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(tasks_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(tasks_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
tasks_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_task_create(client, data):
|
||||
url = reverse('tasks-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"subject": "test",
|
||||
"ref": 1,
|
||||
"project": data.public_project.pk,
|
||||
"status": data.public_project.task_statuses.all()[0].pk,
|
||||
})
|
||||
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": 2,
|
||||
"project": data.private_project1.pk,
|
||||
"status": data.private_project1.task_statuses.all()[0].pk,
|
||||
})
|
||||
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.private_project2.pk,
|
||||
"status": data.private_project2.task_statuses.all()[0].pk,
|
||||
})
|
||||
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):
|
||||
def test_task_patch_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})
|
||||
|
@ -433,6 +495,108 @@ def test_task_patch(client, data):
|
|||
assert results == [401, 403, 403, 451, 451]
|
||||
|
||||
|
||||
def test_task_patch_comment(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,
|
||||
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({"comment": "test comment", "version": data.public_task.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "version": data.private_task1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "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({"comment": "test comment", "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_patch_update_and_comment(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,
|
||||
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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.public_task.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.private_task1.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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_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,
|
||||
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 == [401, 403, 403, 204]
|
||||
results = helper_test_http_method(client, 'delete', private_url1, None, users)
|
||||
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_action_bulk_create(client, data):
|
||||
url = reverse('tasks-bulk-create')
|
||||
|
||||
|
@ -586,34 +750,6 @@ def test_task_voters_retrieve(client, data):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_tasks_csv(client, data):
|
||||
url = reverse('tasks-csv')
|
||||
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,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
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})
|
||||
|
@ -716,3 +852,31 @@ def test_task_watchers_retrieve(client, data):
|
|||
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):
|
||||
url = reverse('tasks-csv')
|
||||
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,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
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]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from tests import factories as f
|
||||
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
||||
|
@ -29,11 +29,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -21,8 +21,8 @@ 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)
|
||||
from taiga.permissions.choices import (MEMBERS_PERMISSIONS,
|
||||
ANON_PERMISSIONS)
|
||||
|
||||
|
||||
from tests import factories as f
|
||||
|
@ -44,11 +44,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects.occ import OCCResourceMixin
|
||||
|
||||
from tests import factories as f
|
||||
|
@ -39,12 +39,12 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
userstories_csv_uuid=uuid.uuid4().hex)
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner,
|
||||
userstories_csv_uuid=uuid.uuid4().hex)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
|
@ -138,6 +138,36 @@ def data():
|
|||
return m
|
||||
|
||||
|
||||
def test_user_story_list(client, data):
|
||||
url = reverse('userstories-list')
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(userstories_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(userstories_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
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})
|
||||
|
@ -162,7 +192,35 @@ def test_user_story_retrieve(client, data):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_user_story_update(client, data):
|
||||
def test_user_story_create(client, data):
|
||||
url = reverse('userstories-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({"subject": "test", "ref": 1, "project": data.public_project.pk})
|
||||
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": 2, "project": data.private_project1.pk})
|
||||
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.private_project2.pk})
|
||||
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_put_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})
|
||||
|
@ -177,31 +235,116 @@ def test_user_story_update(client, data):
|
|||
]
|
||||
|
||||
with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"):
|
||||
user_story_data = UserStorySerializer(data.public_user_story).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
user_story_data = UserStorySerializer(data.public_user_story).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story1).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
user_story_data = UserStorySerializer(data.private_user_story1).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story2).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_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.private_user_story2).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data = json.dumps(user_story_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]
|
||||
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):
|
||||
|
||||
def test_user_story_put_comment(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,
|
||||
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"):
|
||||
user_story_data = UserStorySerializer(data.public_user_story).data
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story1).data
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story2).data
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_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["comment"] = "test comment"
|
||||
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_put_update_and_comment(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,
|
||||
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"):
|
||||
user_story_data = UserStorySerializer(data.public_user_story).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story1).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, user_story_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
user_story_data = UserStorySerializer(data.private_user_story2).data
|
||||
user_story_data["subject"] = "test"
|
||||
user_story_data["comment"] = "test comment"
|
||||
user_story_data = json.dumps(user_story_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["comment"] = "test comment"
|
||||
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_put_update_with_project_change(client):
|
||||
user1 = f.UserFactory.create()
|
||||
user2 = f.UserFactory.create()
|
||||
user3 = f.UserFactory.create()
|
||||
|
@ -296,6 +439,118 @@ def test_user_story_update_with_project_change(client):
|
|||
us.save()
|
||||
|
||||
|
||||
def test_user_story_patch_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,
|
||||
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({"subject": "test", "version": data.public_user_story.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "version": data.private_user_story1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "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({"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_patch_comment(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,
|
||||
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({"comment": "test comment", "version": data.public_user_story.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "version": data.private_user_story1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "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({"comment": "test comment", "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_patch_update_and_comment(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,
|
||||
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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.public_user_story.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.private_user_story1.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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({
|
||||
"subject": "test",
|
||||
"comment": "test comment",
|
||||
"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_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})
|
||||
|
@ -318,95 +573,6 @@ def test_user_story_delete(client, data):
|
|||
assert results == [401, 403, 403, 451]
|
||||
|
||||
|
||||
def test_user_story_list(client, data):
|
||||
url = reverse('userstories-list')
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(userstories_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(userstories_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
userstories_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_user_story_create(client, data):
|
||||
url = reverse('userstories-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({"subject": "test", "ref": 1, "project": data.public_project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users)
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({"subject": "test", "ref": 2, "project": data.private_project1.pk})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users)
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({"subject": "test", "ref": 3, "project": data.private_project2.pk})
|
||||
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,
|
||||
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({"subject": "test", "version": data.public_user_story.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "version": data.private_user_story1.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"subject": "test", "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({"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')
|
||||
|
@ -421,11 +587,11 @@ def test_user_story_action_bulk_create(client, data):
|
|||
|
||||
bulk_data = json.dumps({"bulk_stories": "test1\ntest2", "project_id": data.public_user_story.project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, bulk_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
bulk_data = json.dumps({"bulk_stories": "test1\ntest2", "project_id": data.private_user_story1.project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, bulk_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
bulk_data = json.dumps({"bulk_stories": "test1\ntest2", "project_id": data.private_user_story2.project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, bulk_data, users)
|
||||
|
@ -580,30 +746,6 @@ def test_user_story_voters_retrieve(client, data):
|
|||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
|
||||
def test_user_stories_csv(client, data):
|
||||
url = reverse('userstories-csv')
|
||||
csv_public_uuid = data.public_project.userstories_csv_uuid
|
||||
csv_private1_uuid = data.private_project1.userstories_csv_uuid
|
||||
csv_private2_uuid = data.private_project1.userstories_csv_uuid
|
||||
|
||||
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', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private2_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
|
||||
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})
|
||||
|
@ -706,3 +848,27 @@ def test_userstory_watchers_retrieve(client, data):
|
|||
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_action_csv(client, data):
|
||||
url = reverse('userstories-csv')
|
||||
csv_public_uuid = data.public_project.userstories_csv_uuid
|
||||
csv_private1_uuid = data.private_project1.userstories_csv_uuid
|
||||
csv_private2_uuid = data.private_project1.userstories_csv_uuid
|
||||
|
||||
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', "{}?uuid={}".format(url, csv_public_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private1_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
results = helper_test_http_method(client, 'get', "{}?uuid={}".format(url, csv_private2_uuid), None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
|
|
@ -1,7 +1,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.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects import choices as project_choices
|
||||
from taiga.projects.notifications.services import add_watcher
|
||||
from taiga.projects.occ import OCCResourceMixin
|
||||
|
@ -37,11 +37,11 @@ def data():
|
|||
|
||||
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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_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)),
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
owner=m.project_owner)
|
||||
m.private_project2 = f.ProjectFactory(is_private=True,
|
||||
anon_permissions=[],
|
||||
|
@ -111,91 +111,9 @@ def data():
|
|||
return m
|
||||
|
||||
|
||||
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,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
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,
|
||||
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"):
|
||||
wiki_page_data = WikiPageSerializer(data.public_wiki_page).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_page_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page1).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_page_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page2).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_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,
|
||||
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 == [401, 403, 403, 204]
|
||||
results = helper_test_http_method(client, 'delete', private_url1, None, users)
|
||||
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]
|
||||
|
||||
##############################################
|
||||
## WIKI PAGES
|
||||
##############################################
|
||||
|
||||
def test_wiki_page_list(client, data):
|
||||
url = reverse('wiki-list')
|
||||
|
@ -227,50 +145,7 @@ def test_wiki_page_list(client, data):
|
|||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_wiki_page_create(client, data):
|
||||
url = reverse('wiki-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"content": "test",
|
||||
"slug": "test",
|
||||
"project": data.public_project.pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiPage.objects.all().delete())
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"content": "test",
|
||||
"slug": "test",
|
||||
"project": data.private_project1.pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiPage.objects.all().delete())
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"content": "test",
|
||||
"slug": "test",
|
||||
"project": data.private_project2.pk,
|
||||
})
|
||||
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):
|
||||
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})
|
||||
|
@ -284,54 +159,6 @@ def test_wiki_page_patch(client, data):
|
|||
data.project_owner
|
||||
]
|
||||
|
||||
with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"):
|
||||
patch_data = json.dumps({"content": "test", "version": data.public_wiki_page.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"content": "test", "version": data.private_wiki_page2.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"content": "test", "version": data.private_wiki_page2.version})
|
||||
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')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
post_data = json.dumps({"content": "test", "project_id": data.public_project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, post_data, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
|
||||
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,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
|
@ -342,11 +169,55 @@ def test_wiki_link_retrieve(client, data):
|
|||
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})
|
||||
def test_wiki_page_create(client, data):
|
||||
url = reverse('wiki-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"content": "test",
|
||||
"slug": "test",
|
||||
"project": data.public_project.pk,
|
||||
})
|
||||
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.private_project1.pk,
|
||||
})
|
||||
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.private_project2.pk,
|
||||
})
|
||||
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_put_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,
|
||||
|
@ -357,35 +228,318 @@ def test_wiki_link_update(client, data):
|
|||
]
|
||||
|
||||
with mock.patch.object(OCCResourceMixin, "_validate_and_update_version"):
|
||||
wiki_link_data = WikiLinkSerializer(data.public_wiki_link).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_link_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
wiki_page_data = WikiPageSerializer(data.public_wiki_page).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_link_data = WikiLinkSerializer(data.private_wiki_link1).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_link_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page1).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_link_data = WikiLinkSerializer(data.private_wiki_link2).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_data)
|
||||
results = helper_test_http_method(client, 'put', private_url2, wiki_link_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page2).data
|
||||
wiki_page_data["content"] = "test"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', private_url2, wiki_page_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]
|
||||
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_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})
|
||||
|
||||
def test_wiki_page_put_comment(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,
|
||||
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"):
|
||||
wiki_page_data = WikiPageSerializer(data.public_wiki_page).data
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page1).data
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page2).data
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_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["comment"] = "test comment"
|
||||
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_put_update_and_comment(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,
|
||||
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"):
|
||||
wiki_page_data = WikiPageSerializer(data.public_wiki_page).data
|
||||
wiki_page_data["slug"] = "test"
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page1).data
|
||||
wiki_page_data["slug"] = "test"
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_page_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_page_data = WikiPageSerializer(data.private_wiki_page2).data
|
||||
wiki_page_data["slug"] = "test"
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
wiki_page_data = json.dumps(wiki_page_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["slug"] = "test"
|
||||
wiki_page_data["comment"] = "test comment"
|
||||
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_put_update_with_project_change(client):
|
||||
user1 = f.UserFactory.create()
|
||||
user2 = f.UserFactory.create()
|
||||
user3 = f.UserFactory.create()
|
||||
user4 = f.UserFactory.create()
|
||||
project1 = f.ProjectFactory()
|
||||
project2 = f.ProjectFactory()
|
||||
|
||||
membership1 = f.MembershipFactory(project=project1,
|
||||
user=user1,
|
||||
role__project=project1,
|
||||
role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS)))
|
||||
membership2 = f.MembershipFactory(project=project2,
|
||||
user=user1,
|
||||
role__project=project2,
|
||||
role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS)))
|
||||
membership3 = f.MembershipFactory(project=project1,
|
||||
user=user2,
|
||||
role__project=project1,
|
||||
role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS)))
|
||||
membership4 = f.MembershipFactory(project=project2,
|
||||
user=user3,
|
||||
role__project=project2,
|
||||
role__permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS)))
|
||||
|
||||
wiki_page = f.WikiPageFactory.create(project=project1)
|
||||
|
||||
url = reverse('wiki-detail', kwargs={"pk": wiki_page.pk})
|
||||
|
||||
# Test user with permissions in both projects
|
||||
client.login(user1)
|
||||
|
||||
wiki_page_data = WikiPageSerializer(wiki_page).data
|
||||
wiki_page_data["project"] = project2.id
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
|
||||
response = client.put(url, data=wiki_page_data, content_type="application/json")
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
wiki_page.project = project1
|
||||
wiki_page.save()
|
||||
|
||||
# Test user with permissions in only origin project
|
||||
client.login(user2)
|
||||
|
||||
wiki_page_data = WikiPageSerializer(wiki_page).data
|
||||
wiki_page_data["project"] = project2.id
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
|
||||
response = client.put(url, data=wiki_page_data, content_type="application/json")
|
||||
|
||||
assert response.status_code == 403
|
||||
|
||||
wiki_page.project = project1
|
||||
wiki_page.save()
|
||||
|
||||
# Test user with permissions in only destionation project
|
||||
client.login(user3)
|
||||
|
||||
wiki_page_data = WikiPageSerializer(wiki_page).data
|
||||
wiki_page_data["project"] = project2.id
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
|
||||
response = client.put(url, data=wiki_page_data, content_type="application/json")
|
||||
|
||||
assert response.status_code == 403
|
||||
|
||||
wiki_page.project = project1
|
||||
wiki_page.save()
|
||||
|
||||
# Test user without permissions in the projects
|
||||
client.login(user4)
|
||||
|
||||
wiki_page_data = WikiPageSerializer(wiki_page).data
|
||||
wiki_page_data["project"] = project2.id
|
||||
wiki_page_data = json.dumps(wiki_page_data)
|
||||
|
||||
response = client.put(url, data=wiki_page_data, content_type="application/json")
|
||||
|
||||
assert response.status_code == 403
|
||||
|
||||
wiki_page.project = project1
|
||||
wiki_page.save()
|
||||
|
||||
|
||||
def test_wiki_page_patch_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,
|
||||
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({"content": "test", "version": data.public_wiki_page.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"content": "test", "version": data.private_wiki_page2.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"content": "test", "version": data.private_wiki_page2.version})
|
||||
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_patch_comment(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,
|
||||
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({"comment": "test comment", "version": data.public_wiki_page.version})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "version": data.private_wiki_page2.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "version": data.private_wiki_page2.version})
|
||||
results = helper_test_http_method(client, 'patch', private_url2, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"comment": "test comment", "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_patch_update_and_comment(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,
|
||||
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({
|
||||
"content": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.public_wiki_page.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"content": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.private_wiki_page2.version
|
||||
})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({
|
||||
"content": "test",
|
||||
"comment": "test comment",
|
||||
"version": data.private_wiki_page2.version
|
||||
})
|
||||
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",
|
||||
"comment": "test comment",
|
||||
"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_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,
|
||||
|
@ -403,38 +557,8 @@ def test_wiki_link_delete(client, data):
|
|||
assert results == [401, 403, 403, 451]
|
||||
|
||||
|
||||
def test_wiki_link_list(client, data):
|
||||
url = reverse('wiki-links-list')
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(wiki_links_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(wiki_links_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_wiki_link_create(client, data):
|
||||
url = reverse('wiki-links-list')
|
||||
def test_wiki_page_action_render(client, data):
|
||||
url = reverse('wiki-render')
|
||||
|
||||
users = [
|
||||
None,
|
||||
|
@ -444,69 +568,9 @@ def test_wiki_link_create(client, data):
|
|||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"title": "test",
|
||||
"href": "test",
|
||||
"project": data.public_project.pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiLink.objects.all().delete())
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"title": "test",
|
||||
"href": "test",
|
||||
"project": data.private_project1.pk,
|
||||
})
|
||||
results = helper_test_http_method(client, 'post', url, create_data, users, lambda: WikiLink.objects.all().delete())
|
||||
assert results == [401, 201, 201, 201, 201]
|
||||
|
||||
create_data = json.dumps({
|
||||
"title": "test",
|
||||
"href": "test",
|
||||
"project": data.private_project2.pk,
|
||||
})
|
||||
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,
|
||||
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({"title": "test"})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"title": "test"})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 200, 200, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"title": "test"})
|
||||
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]
|
||||
post_data = json.dumps({"content": "test", "project_id": data.public_project.pk})
|
||||
results = helper_test_http_method(client, 'post', url, post_data, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
|
||||
|
||||
def test_wikipage_action_watch(client, data):
|
||||
|
@ -610,3 +674,199 @@ def test_wikipage_watchers_retrieve(client, data):
|
|||
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]
|
||||
|
||||
|
||||
##############################################
|
||||
## WIKI LINKS
|
||||
##############################################
|
||||
|
||||
def test_wiki_link_list(client, data):
|
||||
url = reverse('wiki-links-list')
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(wiki_links_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.registered_user)
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
assert len(wiki_links_data) == 2
|
||||
assert response.status_code == 200
|
||||
|
||||
client.login(data.project_member_with_perms)
|
||||
|
||||
response = client.get(url)
|
||||
wiki_links_data = json.loads(response.content.decode('utf-8'))
|
||||
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) == 4
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
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,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
results = helper_test_http_method(client, 'get', public_url, None, users)
|
||||
assert results == [200, 200, 200, 200, 200]
|
||||
results = helper_test_http_method(client, 'get', private_url1, None, users)
|
||||
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_create(client, data):
|
||||
url = reverse('wiki-links-list')
|
||||
|
||||
users = [
|
||||
None,
|
||||
data.registered_user,
|
||||
data.project_member_without_perms,
|
||||
data.project_member_with_perms,
|
||||
data.project_owner
|
||||
]
|
||||
|
||||
create_data = json.dumps({
|
||||
"title": "test",
|
||||
"href": "test",
|
||||
"project": data.public_project.pk,
|
||||
})
|
||||
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.private_project1.pk,
|
||||
})
|
||||
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.private_project2.pk,
|
||||
})
|
||||
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_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,
|
||||
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"):
|
||||
wiki_link_data = WikiLinkSerializer(data.public_wiki_link).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_data)
|
||||
results = helper_test_http_method(client, 'put', public_url, wiki_link_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_link_data = WikiLinkSerializer(data.private_wiki_link1).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_data)
|
||||
results = helper_test_http_method(client, 'put', private_url1, wiki_link_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
wiki_link_data = WikiLinkSerializer(data.private_wiki_link2).data
|
||||
wiki_link_data["title"] = "test"
|
||||
wiki_link_data = json.dumps(wiki_link_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_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,
|
||||
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({"title": "test"})
|
||||
results = helper_test_http_method(client, 'patch', public_url, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"title": "test"})
|
||||
results = helper_test_http_method(client, 'patch', private_url1, patch_data, users)
|
||||
assert results == [401, 403, 403, 200, 200]
|
||||
|
||||
patch_data = json.dumps({"title": "test"})
|
||||
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_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,
|
||||
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 == [401, 403, 403, 204]
|
||||
results = helper_test_http_method(client, 'delete', private_url1, None, users)
|
||||
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]
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
import datetime
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
@ -235,3 +237,84 @@ def test_delete_comment_by_project_owner(client):
|
|||
url = "%s?id=%s" % (url, history_entry.id)
|
||||
response = client.post(url, content_type="application/json")
|
||||
assert 200 == response.status_code, response.status_code
|
||||
|
||||
|
||||
def test_edit_comment(client):
|
||||
project = f.create_project()
|
||||
us = f.create_userstory(project=project)
|
||||
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
|
||||
key = make_key_from_model_object(us)
|
||||
history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||
comment="testing",
|
||||
key=key,
|
||||
diff={},
|
||||
user={"pk": project.owner.id})
|
||||
|
||||
history_entry_created_at = history_entry.created_at
|
||||
assert history_entry.comment_versions == None
|
||||
assert history_entry.edit_comment_date == None
|
||||
|
||||
client.login(project.owner)
|
||||
url = reverse("userstory-history-edit-comment", args=(us.id,))
|
||||
url = "%s?id=%s" % (url, history_entry.id)
|
||||
|
||||
data = json.dumps({"comment": "testing update comment"})
|
||||
response = client.post(url, data, content_type="application/json")
|
||||
assert 200 == response.status_code, response.status_code
|
||||
|
||||
|
||||
history_entry = HistoryEntry.objects.get(id=history_entry.id)
|
||||
assert len(history_entry.comment_versions) == 1
|
||||
assert history_entry.comment == "testing update comment"
|
||||
assert history_entry.comment_versions[0]["comment"] == "testing"
|
||||
assert history_entry.edit_comment_date != None
|
||||
assert history_entry.comment_versions[0]["user"]["id"] == project.owner.id
|
||||
|
||||
|
||||
def test_get_comment_versions(client):
|
||||
project = f.create_project()
|
||||
us = f.create_userstory(project=project)
|
||||
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
|
||||
key = make_key_from_model_object(us)
|
||||
history_entry = f.HistoryEntryFactory.create(
|
||||
type=HistoryType.change,
|
||||
comment="testing",
|
||||
key=key,
|
||||
diff={},
|
||||
user={"pk": project.owner.id},
|
||||
edit_comment_date=datetime.datetime.now(),
|
||||
comment_versions = [{
|
||||
"comment_html": "<p>test</p>",
|
||||
"date": "2016-05-09T09:34:27.221Z",
|
||||
"comment": "test",
|
||||
"user": {
|
||||
"id": project.owner.id,
|
||||
}}])
|
||||
|
||||
client.login(project.owner)
|
||||
url = reverse("userstory-history-comment-versions", args=(us.id,))
|
||||
url = "%s?id=%s" % (url, history_entry.id)
|
||||
|
||||
response = client.get(url, content_type="application/json")
|
||||
assert 200 == response.status_code, response.status_code
|
||||
assert response.data[0]["user"]["username"] == project.owner.username
|
||||
|
||||
|
||||
def test_get_comment_versions_from_history_entry_without_comment(client):
|
||||
project = f.create_project()
|
||||
us = f.create_userstory(project=project)
|
||||
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
|
||||
key = make_key_from_model_object(us)
|
||||
history_entry = f.HistoryEntryFactory.create(
|
||||
type=HistoryType.change,
|
||||
key=key,
|
||||
diff={},
|
||||
user={"pk": project.owner.id})
|
||||
|
||||
client.login(project.owner)
|
||||
url = reverse("userstory-history-comment-versions", args=(us.id,))
|
||||
url = "%s?id=%s" % (url, history_entry.id)
|
||||
|
||||
response = client.get(url, content_type="application/json")
|
||||
assert 200 == response.status_code, response.status_code
|
||||
assert response.data == None
|
||||
|
|
|
@ -41,7 +41,7 @@ from taiga.projects.history.services import take_snapshot
|
|||
from taiga.projects.issues.serializers import IssueSerializer
|
||||
from taiga.projects.userstories.serializers import UserStorySerializer
|
||||
from taiga.projects.tasks.serializers import TaskSerializer
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from taiga.permissions import service, permissions
|
||||
from taiga.permissions import services, choices
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
|
||||
from .. import factories
|
||||
|
@ -15,15 +15,15 @@ def test_get_user_project_role():
|
|||
role = factories.RoleFactory()
|
||||
membership = factories.MembershipFactory(user=user1, project=project, role=role)
|
||||
|
||||
assert service._get_user_project_membership(user1, project) == membership
|
||||
assert service._get_user_project_membership(user2, project) is None
|
||||
assert services._get_user_project_membership(user1, project) == membership
|
||||
assert services._get_user_project_membership(user2, project) is None
|
||||
|
||||
|
||||
def test_anon_get_user_project_permissions():
|
||||
project = factories.ProjectFactory()
|
||||
project.anon_permissions = ["test1"]
|
||||
project.public_permissions = ["test2"]
|
||||
assert service.get_user_project_permissions(AnonymousUser(), project) == set(["test1"])
|
||||
assert services.get_user_project_permissions(AnonymousUser(), project) == set(["test1"])
|
||||
|
||||
|
||||
def test_user_get_user_project_permissions_on_public_project():
|
||||
|
@ -31,7 +31,7 @@ def test_user_get_user_project_permissions_on_public_project():
|
|||
project = factories.ProjectFactory()
|
||||
project.anon_permissions = ["test1"]
|
||||
project.public_permissions = ["test2"]
|
||||
assert service.get_user_project_permissions(user1, project) == set(["test1", "test2"])
|
||||
assert services.get_user_project_permissions(user1, project) == set(["test1", "test2"])
|
||||
|
||||
|
||||
def test_user_get_user_project_permissions_on_private_project():
|
||||
|
@ -40,7 +40,7 @@ def test_user_get_user_project_permissions_on_private_project():
|
|||
project.anon_permissions = ["test1"]
|
||||
project.public_permissions = ["test2"]
|
||||
project.is_private = True
|
||||
assert service.get_user_project_permissions(user1, project) == set(["test1", "test2"])
|
||||
assert services.get_user_project_permissions(user1, project) == set(["test1", "test2"])
|
||||
|
||||
|
||||
def test_owner_get_user_project_permissions():
|
||||
|
@ -55,7 +55,7 @@ def test_owner_get_user_project_permissions():
|
|||
expected_perms = set(
|
||||
["test1", "test2", "view_us"]
|
||||
)
|
||||
assert service.get_user_project_permissions(user1, project) == expected_perms
|
||||
assert services.get_user_project_permissions(user1, project) == expected_perms
|
||||
|
||||
|
||||
def test_owner_member_get_user_project_permissions():
|
||||
|
@ -68,10 +68,10 @@ def test_owner_member_get_user_project_permissions():
|
|||
|
||||
expected_perms = set(
|
||||
["test1", "test2", "test3"] +
|
||||
[x[0] for x in permissions.ADMINS_PERMISSIONS] +
|
||||
[x[0] for x in permissions.MEMBERS_PERMISSIONS]
|
||||
[x[0] for x in choices.ADMINS_PERMISSIONS] +
|
||||
[x[0] for x in choices.MEMBERS_PERMISSIONS]
|
||||
)
|
||||
assert service.get_user_project_permissions(user1, project) == expected_perms
|
||||
assert services.get_user_project_permissions(user1, project) == expected_perms
|
||||
|
||||
|
||||
def test_member_get_user_project_permissions():
|
||||
|
@ -82,22 +82,22 @@ def test_member_get_user_project_permissions():
|
|||
role = factories.RoleFactory(permissions=["test3"])
|
||||
factories.MembershipFactory(user=user1, project=project, role=role)
|
||||
|
||||
assert service.get_user_project_permissions(user1, project) == set(["test1", "test2", "test3"])
|
||||
assert services.get_user_project_permissions(user1, project) == set(["test1", "test2", "test3"])
|
||||
|
||||
|
||||
def test_anon_user_has_perm():
|
||||
project = factories.ProjectFactory()
|
||||
project.anon_permissions = ["test"]
|
||||
assert service.user_has_perm(AnonymousUser(), "test", project) is True
|
||||
assert service.user_has_perm(AnonymousUser(), "fail", project) is False
|
||||
assert services.user_has_perm(AnonymousUser(), "test", project) is True
|
||||
assert services.user_has_perm(AnonymousUser(), "fail", project) is False
|
||||
|
||||
|
||||
def test_authenticated_user_has_perm_on_project():
|
||||
user1 = factories.UserFactory()
|
||||
project = factories.ProjectFactory()
|
||||
project.public_permissions = ["test"]
|
||||
assert service.user_has_perm(user1, "test", project) is True
|
||||
assert service.user_has_perm(user1, "fail", project) is False
|
||||
assert services.user_has_perm(user1, "test", project) is True
|
||||
assert services.user_has_perm(user1, "fail", project) is False
|
||||
|
||||
|
||||
def test_authenticated_user_has_perm_on_project_related_object():
|
||||
|
@ -106,10 +106,10 @@ def test_authenticated_user_has_perm_on_project_related_object():
|
|||
project.public_permissions = ["test"]
|
||||
us = factories.UserStoryFactory(project=project)
|
||||
|
||||
assert service.user_has_perm(user1, "test", us) is True
|
||||
assert service.user_has_perm(user1, "fail", us) is False
|
||||
assert services.user_has_perm(user1, "test", us) is True
|
||||
assert services.user_has_perm(user1, "fail", us) is False
|
||||
|
||||
|
||||
def test_authenticated_user_has_perm_on_invalid_object():
|
||||
user1 = factories.UserFactory()
|
||||
assert service.user_has_perm(user1, "test", user1) is False
|
||||
assert services.user_has_perm(user1, "test", user1) is False
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.core import signing
|
|||
from taiga.base.utils import json
|
||||
from taiga.projects.services import stats as stats_services
|
||||
from taiga.projects.history.services import take_snapshot
|
||||
from taiga.permissions.permissions import ANON_PERMISSIONS
|
||||
from taiga.permissions.choices import ANON_PERMISSIONS
|
||||
from taiga.projects.models import Project
|
||||
|
||||
from .. import factories as f
|
||||
|
|
|
@ -22,7 +22,7 @@ from django.core.urlresolvers import reverse
|
|||
|
||||
from .. import factories as f
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS
|
||||
from tests.utils import disconnect_signals, reconnect_signals
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from taiga.base.utils.thumbnails import get_thumbnail_url
|
|||
from taiga.users import models
|
||||
from taiga.users.serializers import LikedObjectSerializer, VotedObjectSerializer
|
||||
from taiga.auth.tokens import get_token_for_user
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
from taiga.projects import choices as project_choices
|
||||
from taiga.users.services import get_watched_list, get_voted_list, get_liked_list
|
||||
from taiga.projects.notifications.choices import NotifyLevel
|
||||
|
@ -340,7 +340,7 @@ def test_list_contacts_no_projects(client):
|
|||
def test_list_contacts_public_projects(client):
|
||||
project = f.ProjectFactory.create(is_private=False,
|
||||
anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
public_permissions=list(map(lambda x: x[0], USER_PERMISSIONS)))
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)))
|
||||
|
||||
user_1 = f.UserFactory.create()
|
||||
user_2 = f.UserFactory.create()
|
||||
|
|
|
@ -20,7 +20,7 @@ import pytest
|
|||
import json
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
||||
from taiga.permissions.choices import MEMBERS_PERMISSIONS, ANON_PERMISSIONS
|
||||
|
||||
from .. import factories as f
|
||||
|
||||
|
@ -129,7 +129,7 @@ def test_get_project_is_watcher(client):
|
|||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory.create(is_private=False,
|
||||
anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||
public_permissions=list(map(lambda x: x[0], USER_PERMISSIONS)))
|
||||
public_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)))
|
||||
|
||||
url_detail = reverse("projects-detail", args=(project.id,))
|
||||
url_watch = reverse("projects-watch", args=(project.id,))
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from taiga.permissions import service
|
||||
from taiga.users.models import Role
|
||||
|
||||
|
||||
def test_role_has_perm():
|
||||
role = Role()
|
||||
role.permissions = ["test"]
|
||||
assert service.role_has_perm(role, "test")
|
||||
assert service.role_has_perm(role, "false") is False
|
Loading…
Reference in New Issue