US#45: Working the base of the proyect template system

remotes/origin/enhancement/email-actions
Jesús Espino 2014-04-22 16:10:15 +02:00
parent 4887ca55a9
commit ee75818a18
23 changed files with 643 additions and 594 deletions

View File

@ -1,3 +0,0 @@
#!/bin/bash
python ./manage.py dumpdata -n --indent=4 users.Role > taiga/users/fixtures/initial_role.json

View File

@ -15,10 +15,11 @@ echo "-> Load initial domain"
python manage.py loaddata initial_domains --traceback python manage.py loaddata initial_domains --traceback
echo "-> Load initial user" echo "-> Load initial user"
python manage.py loaddata initial_user --traceback python manage.py loaddata initial_user --traceback
echo "-> Load initial project_templates"
python manage.py loaddata initial_project_templates --traceback
echo "-> Load initial roles" echo "-> Load initial roles"
python manage.py loaddata initial_role --traceback python manage.py loaddata initial_role --traceback
echo "-> Generate sample data" echo "-> Generate sample data"
python manage.py sample_data --traceback python manage.py sample_data --traceback
echo "-> Generate initial versions of objects" echo "-> Generate initial versions of objects"
python manage.py createinitialrevisions --traceback python manage.py createinitialrevisions --traceback

View File

@ -293,6 +293,7 @@ REST_FRAMEWORK = {
"MAX_PAGINATE_BY": 1000, "MAX_PAGINATE_BY": 1000,
} }
DEFAULT_PROJECT_TEMPLATE = "scrum"
# NOTE: DON'T INSERT MORE SETTINGS AFTER THIS LINE # NOTE: DON'T INSERT MORE SETTINGS AFTER THIS LINE

View File

@ -56,7 +56,7 @@ urls.urlpatterns += patterns("",
class AuthServicesTests(test.TestCase): class AuthServicesTests(test.TestCase):
fixtures = ["initial_domains.json",] fixtures = ["initial_domains.json", "initial_project_templates.json",]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)
@ -184,7 +184,7 @@ class TokenAuthenticationBackendTests(test.TestCase):
class RegisterApiTests(test.TestCase): class RegisterApiTests(test.TestCase):
fixtures = ["initial_domains.json",] fixtures = ["initial_domains.json", "initial_project_templates.json",]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)

View File

@ -21,6 +21,8 @@ from rest_framework import serializers
from reversion.models import Version from reversion.models import Version
import reversion import reversion
from taiga.domains.base import get_active_domain
class PickleField(serializers.WritableField): class PickleField(serializers.WritableField):
""" """
@ -33,6 +35,27 @@ class PickleField(serializers.WritableField):
return data return data
class JsonField(serializers.WritableField):
"""
Json objects serializer.
"""
def to_native(self, obj):
return obj
def from_native(self, data):
return data
class AutoDomainField(serializers.WritableField):
"""
Automatically set domain field serializer.
"""
def to_native(self, obj):
return obj
def from_native(self, data):
domain = get_active_domain()
return domain.id
class VersionSerializer(serializers.ModelSerializer): class VersionSerializer(serializers.ModelSerializer):
created_date = serializers.SerializerMethodField("get_created_date") created_date = serializers.SerializerMethodField("get_created_date")
content_type = serializers.SerializerMethodField("get_content_type") content_type = serializers.SerializerMethodField("get_content_type")

View File

@ -12,6 +12,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf import settings
from rest_framework import serializers from rest_framework import serializers
from taiga.users.serializers import UserSerializer from taiga.users.serializers import UserSerializer
@ -20,14 +22,18 @@ from .models import Domain, DomainMember
class DomainSerializer(serializers.ModelSerializer): class DomainSerializer(serializers.ModelSerializer):
projects = serializers.SerializerMethodField('get_projects') projects = serializers.SerializerMethodField('get_projects')
default_project_template = serializers.SerializerMethodField('get_default_project_template')
class Meta: class Meta:
model = Domain model = Domain
fields = ('public_register', 'default_language', "projects") fields = ('public_register', 'default_language', "projects", "default_project_template")
def get_projects(self, obj): def get_projects(self, obj):
return map(lambda x: {"id": x.id, "name": x.name, "slug": x.slug, "owner": x.owner.id}, obj.projects.all().order_by('name')) return map(lambda x: {"id": x.id, "name": x.name, "slug": x.slug, "owner": x.owner.id}, obj.projects.all().order_by('name'))
def get_default_project_template(self, obj):
return settings.DEFAULT_PROJECT_TEMPLATE
class DomainMemberSerializer(serializers.ModelSerializer): class DomainMemberSerializer(serializers.ModelSerializer):
user = UserSerializer() user = UserSerializer()

View File

@ -51,7 +51,7 @@ from unittest.mock import MagicMock
from unittest.mock import patch from unittest.mock import patch
class ChangesTest(test.TestCase): class ChangesTest(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def test_emit_change_for_model(self): def test_emit_change_for_model(self):
user = create_user(1) # Project owner user = create_user(1) # Project owner

View File

@ -298,3 +298,12 @@ class QuestionStatusViewSet(ModelCrudViewSet, BulkUpdateOrderMixin):
bulk_update_param = "bulk_question_statuses" bulk_update_param = "bulk_question_statuses"
bulk_update_perm = "change_questionstatus" bulk_update_perm = "change_questionstatus"
bulk_update_order = services.bulk_update_question_status_order bulk_update_order = services.bulk_update_question_status_order
class ProjectTemplateViewSet(ModelCrudViewSet):
model = models.ProjectTemplate
serializer_class = serializers.ProjectTemplateSerializer
permission_classes = (IsAuthenticated, permissions.ProjectTemplatePermission)
def get_queryset(self):
domain = get_active_domain()
return models.ProjectTemplate.objects.filter(Q(domain=domain) | Q(domain__isnull=True))

View File

@ -14,463 +14,7 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
VIDEOCONFERENCES_CHOICES = ( VIDEOCONFERENCES_CHOICES = (
("appear-in", "AppearIn"), ("appear-in", "AppearIn"),
("talky", "Talky"), ("talky", "Talky"),
) )
US_STATUSES = (
(1, _("Open"), False, True, "#669933"),
(2, _("Closed"), True, False, "#999999"),
)
TASK_STATUSES = (
(1, _("New"), False, True, "#999999"),
(2, _("In progress"), False, False, "#ff9900"),
(3, _("Ready for test"), True, False, "#ffcc00"),
(4, _("Closed"), True, False, "#669900"),
(5, _("Needs Info"), False, False, "#999999"),
)
POINTS_CHOICES = (
(1, u"?", None, True),
(2, u"0", 0, False),
(3, u"1/2", 0.5, False),
(4, u"1", 1, False),
(5, u"2", 2, False),
(6, u"3", 3, False),
(7, u"5", 5, False),
(8, u"8", 8, False),
(9, u"10", 10, False),
(10, u"15", 15, False),
(11, u"20", 20, False),
(12, u"40", 40, False),
)
PRIORITY_CHOICES = (
(1, _(u"Low"), "#666666", False),
(3, _(u"Normal"), "#669933", True),
(5, _(u"High"), "#CC0000", False),
)
SEVERITY_CHOICES = (
(1, _(u"Wishlist"), "#666666", False),
(2, _(u"Minor"), "#669933", False),
(3, _(u"Normal"), "#0000FF", True),
(4, _(u"Important"), "#FFA500", False),
(5, _(u"Critical"), "#CC0000", False),
)
ISSUE_STATUSES = (
(1, _("New"), False, "#8C2318", True),
(2, _("In progress"), False, "#5E8C6A", False),
(3, _("Ready for test"), True, "#88A65E", False),
(4, _("Closed"), True, "#BFB35A", False),
(5, _("Needs Info"), False, "#89BAB4", False),
(6, _("Rejected"), True, "#CC0000", False),
(7, _("Postponed"), False, "#666666", False),
)
ISSUE_TYPES = (
(1, _(u"Bug"), "#89BAB4", True),
)
QUESTION_STATUS = (
(1, _("Pending"), False, "#FFA500", True),
(2, _("Answered"), False, "#669933", False),
(3, _("Closed"), True,"#BFB35A", False),
)
ROLES = (
(10, "ux", "UX", True, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "add_milestone", "milestones", "milestone" ],
[ "change_milestone", "milestones", "milestone" ],
[ "delete_milestone", "milestones", "milestone" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "add_issuestatus", "projects", "issuestatus" ],
[ "change_issuestatus", "projects", "issuestatus" ],
[ "delete_issuestatus", "projects", "issuestatus" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "add_issuetype", "projects", "issuetype" ],
[ "change_issuetype", "projects", "issuetype" ],
[ "delete_issuetype", "projects", "issuetype" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "add_membership", "projects", "membership" ],
[ "change_membership", "projects", "membership" ],
[ "delete_membership", "projects", "membership" ],
[ "view_membership", "projects", "membership" ],
[ "add_points", "projects", "points" ],
[ "change_points", "projects", "points" ],
[ "delete_points", "projects", "points" ],
[ "view_points", "projects", "points" ],
[ "add_priority", "projects", "priority" ],
[ "change_priority", "projects", "priority" ],
[ "delete_priority", "projects", "priority" ],
[ "view_priority", "projects", "priority" ],
[ "add_project", "projects", "project" ],
[ "change_project", "projects", "project" ],
[ "delete_project", "projects", "project" ],
[ "view_project", "projects", "project" ],
[ "add_severity", "projects", "severity" ],
[ "change_severity", "projects", "severity" ],
[ "delete_severity", "projects", "severity" ],
[ "view_severity", "projects", "severity" ],
[ "add_taskstatus", "projects", "taskstatus" ],
[ "change_taskstatus", "projects", "taskstatus" ],
[ "delete_taskstatus", "projects", "taskstatus" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "add_userstorystatus", "projects", "userstorystatus" ],
[ "change_userstorystatus", "projects", "userstorystatus" ],
[ "delete_userstorystatus", "projects", "userstorystatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "add_task", "tasks", "task" ],
[ "change_task", "tasks", "task" ],
[ "delete_task", "tasks", "task" ],
[ "view_task", "tasks", "task" ],
[ "add_role", "users", "role" ],
[ "change_role", "users", "role" ],
[ "delete_role", "users", "role" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "add_rolepoints", "userstories", "rolepoints" ],
[ "change_rolepoints", "userstories", "rolepoints" ],
[ "delete_rolepoints", "userstories", "rolepoints" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "add_userstory", "userstories", "userstory" ],
[ "change_userstory", "userstories", "userstory" ],
[ "delete_userstory", "userstories", "userstory" ],
[ "view_userstory", "userstories", "userstory" ],
[ "add_wikipage", "wiki", "wikipage" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "delete_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
]),
(20, "design", "Design", True, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "add_milestone", "milestones", "milestone" ],
[ "change_milestone", "milestones", "milestone" ],
[ "delete_milestone", "milestones", "milestone" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "add_issuestatus", "projects", "issuestatus" ],
[ "change_issuestatus", "projects", "issuestatus" ],
[ "delete_issuestatus", "projects", "issuestatus" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "add_issuetype", "projects", "issuetype" ],
[ "change_issuetype", "projects", "issuetype" ],
[ "delete_issuetype", "projects", "issuetype" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "add_membership", "projects", "membership" ],
[ "change_membership", "projects", "membership" ],
[ "delete_membership", "projects", "membership" ],
[ "view_membership", "projects", "membership" ],
[ "add_points", "projects", "points" ],
[ "change_points", "projects", "points" ],
[ "delete_points", "projects", "points" ],
[ "view_points", "projects", "points" ],
[ "add_priority", "projects", "priority" ],
[ "change_priority", "projects", "priority" ],
[ "delete_priority", "projects", "priority" ],
[ "view_priority", "projects", "priority" ],
[ "add_project", "projects", "project" ],
[ "change_project", "projects", "project" ],
[ "delete_project", "projects", "project" ],
[ "view_project", "projects", "project" ],
[ "add_severity", "projects", "severity" ],
[ "change_severity", "projects", "severity" ],
[ "delete_severity", "projects", "severity" ],
[ "view_severity", "projects", "severity" ],
[ "add_taskstatus", "projects", "taskstatus" ],
[ "change_taskstatus", "projects", "taskstatus" ],
[ "delete_taskstatus", "projects", "taskstatus" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "add_userstorystatus", "projects", "userstorystatus" ],
[ "change_userstorystatus", "projects", "userstorystatus" ],
[ "delete_userstorystatus", "projects", "userstorystatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "add_task", "tasks", "task" ],
[ "change_task", "tasks", "task" ],
[ "delete_task", "tasks", "task" ],
[ "view_task", "tasks", "task" ],
[ "add_role", "users", "role" ],
[ "change_role", "users", "role" ],
[ "delete_role", "users", "role" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "add_rolepoints", "userstories", "rolepoints" ],
[ "change_rolepoints", "userstories", "rolepoints" ],
[ "delete_rolepoints", "userstories", "rolepoints" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "add_userstory", "userstories", "userstory" ],
[ "change_userstory", "userstories", "userstory" ],
[ "delete_userstory", "userstories", "userstory" ],
[ "view_userstory", "userstories", "userstory" ],
[ "add_wikipage", "wiki", "wikipage" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "delete_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
]),
(30, "front", "Front", True, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "add_milestone", "milestones", "milestone" ],
[ "change_milestone", "milestones", "milestone" ],
[ "delete_milestone", "milestones", "milestone" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "add_issuestatus", "projects", "issuestatus" ],
[ "change_issuestatus", "projects", "issuestatus" ],
[ "delete_issuestatus", "projects", "issuestatus" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "add_issuetype", "projects", "issuetype" ],
[ "change_issuetype", "projects", "issuetype" ],
[ "delete_issuetype", "projects", "issuetype" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "add_membership", "projects", "membership" ],
[ "change_membership", "projects", "membership" ],
[ "delete_membership", "projects", "membership" ],
[ "view_membership", "projects", "membership" ],
[ "add_points", "projects", "points" ],
[ "change_points", "projects", "points" ],
[ "delete_points", "projects", "points" ],
[ "view_points", "projects", "points" ],
[ "add_priority", "projects", "priority" ],
[ "change_priority", "projects", "priority" ],
[ "delete_priority", "projects", "priority" ],
[ "view_priority", "projects", "priority" ],
[ "add_project", "projects", "project" ],
[ "change_project", "projects", "project" ],
[ "delete_project", "projects", "project" ],
[ "view_project", "projects", "project" ],
[ "add_severity", "projects", "severity" ],
[ "change_severity", "projects", "severity" ],
[ "delete_severity", "projects", "severity" ],
[ "view_severity", "projects", "severity" ],
[ "add_taskstatus", "projects", "taskstatus" ],
[ "change_taskstatus", "projects", "taskstatus" ],
[ "delete_taskstatus", "projects", "taskstatus" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "add_userstorystatus", "projects", "userstorystatus" ],
[ "change_userstorystatus", "projects", "userstorystatus" ],
[ "delete_userstorystatus", "projects", "userstorystatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "add_task", "tasks", "task" ],
[ "change_task", "tasks", "task" ],
[ "delete_task", "tasks", "task" ],
[ "view_task", "tasks", "task" ],
[ "add_role", "users", "role" ],
[ "change_role", "users", "role" ],
[ "delete_role", "users", "role" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "add_rolepoints", "userstories", "rolepoints" ],
[ "change_rolepoints", "userstories", "rolepoints" ],
[ "delete_rolepoints", "userstories", "rolepoints" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "add_userstory", "userstories", "userstory" ],
[ "change_userstory", "userstories", "userstory" ],
[ "delete_userstory", "userstories", "userstory" ],
[ "view_userstory", "userstories", "userstory" ],
[ "add_wikipage", "wiki", "wikipage" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "delete_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
]),
(40, "back", "Back", True, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "add_milestone", "milestones", "milestone" ],
[ "change_milestone", "milestones", "milestone" ],
[ "delete_milestone", "milestones", "milestone" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "add_issuestatus", "projects", "issuestatus" ],
[ "change_issuestatus", "projects", "issuestatus" ],
[ "delete_issuestatus", "projects", "issuestatus" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "add_issuetype", "projects", "issuetype" ],
[ "change_issuetype", "projects", "issuetype" ],
[ "delete_issuetype", "projects", "issuetype" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "add_membership", "projects", "membership" ],
[ "change_membership", "projects", "membership" ],
[ "delete_membership", "projects", "membership" ],
[ "view_membership", "projects", "membership" ],
[ "add_points", "projects", "points" ],
[ "change_points", "projects", "points" ],
[ "delete_points", "projects", "points" ],
[ "view_points", "projects", "points" ],
[ "add_priority", "projects", "priority" ],
[ "change_priority", "projects", "priority" ],
[ "delete_priority", "projects", "priority" ],
[ "view_priority", "projects", "priority" ],
[ "add_project", "projects", "project" ],
[ "change_project", "projects", "project" ],
[ "delete_project", "projects", "project" ],
[ "view_project", "projects", "project" ],
[ "add_severity", "projects", "severity" ],
[ "change_severity", "projects", "severity" ],
[ "delete_severity", "projects", "severity" ],
[ "view_severity", "projects", "severity" ],
[ "add_taskstatus", "projects", "taskstatus" ],
[ "change_taskstatus", "projects", "taskstatus" ],
[ "delete_taskstatus", "projects", "taskstatus" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "add_userstorystatus", "projects", "userstorystatus" ],
[ "change_userstorystatus", "projects", "userstorystatus" ],
[ "delete_userstorystatus", "projects", "userstorystatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "add_task", "tasks", "task" ],
[ "change_task", "tasks", "task" ],
[ "delete_task", "tasks", "task" ],
[ "view_task", "tasks", "task" ],
[ "add_role", "users", "role" ],
[ "change_role", "users", "role" ],
[ "delete_role", "users", "role" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "add_rolepoints", "userstories", "rolepoints" ],
[ "change_rolepoints", "userstories", "rolepoints" ],
[ "delete_rolepoints", "userstories", "rolepoints" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "add_userstory", "userstories", "userstory" ],
[ "change_userstory", "userstories", "userstory" ],
[ "delete_userstory", "userstories", "userstory" ],
[ "view_userstory", "userstories", "userstory" ],
[ "add_wikipage", "wiki", "wikipage" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "delete_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
]),
(50, "product-ouner", "Product Owner", False, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "add_milestone", "milestones", "milestone" ],
[ "change_milestone", "milestones", "milestone" ],
[ "delete_milestone", "milestones", "milestone" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "add_issuestatus", "projects", "issuestatus" ],
[ "change_issuestatus", "projects", "issuestatus" ],
[ "delete_issuestatus", "projects", "issuestatus" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "add_issuetype", "projects", "issuetype" ],
[ "change_issuetype", "projects", "issuetype" ],
[ "delete_issuetype", "projects", "issuetype" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "add_membership", "projects", "membership" ],
[ "change_membership", "projects", "membership" ],
[ "delete_membership", "projects", "membership" ],
[ "view_membership", "projects", "membership" ],
[ "add_points", "projects", "points" ],
[ "change_points", "projects", "points" ],
[ "delete_points", "projects", "points" ],
[ "view_points", "projects", "points" ],
[ "add_priority", "projects", "priority" ],
[ "change_priority", "projects", "priority" ],
[ "delete_priority", "projects", "priority" ],
[ "view_priority", "projects", "priority" ],
[ "add_project", "projects", "project" ],
[ "change_project", "projects", "project" ],
[ "delete_project", "projects", "project" ],
[ "view_project", "projects", "project" ],
[ "add_severity", "projects", "severity" ],
[ "change_severity", "projects", "severity" ],
[ "delete_severity", "projects", "severity" ],
[ "view_severity", "projects", "severity" ],
[ "add_taskstatus", "projects", "taskstatus" ],
[ "change_taskstatus", "projects", "taskstatus" ],
[ "delete_taskstatus", "projects", "taskstatus" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "add_userstorystatus", "projects", "userstorystatus" ],
[ "change_userstorystatus", "projects", "userstorystatus" ],
[ "delete_userstorystatus", "projects", "userstorystatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "add_task", "tasks", "task" ],
[ "change_task", "tasks", "task" ],
[ "delete_task", "tasks", "task" ],
[ "view_task", "tasks", "task" ],
[ "add_role", "users", "role" ],
[ "change_role", "users", "role" ],
[ "delete_role", "users", "role" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "add_rolepoints", "userstories", "rolepoints" ],
[ "change_rolepoints", "userstories", "rolepoints" ],
[ "delete_rolepoints", "userstories", "rolepoints" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "add_userstory", "userstories", "userstory" ],
[ "change_userstory", "userstories", "userstory" ],
[ "delete_userstory", "userstories", "userstory" ],
[ "view_userstory", "userstories", "userstory" ],
[ "add_wikipage", "wiki", "wikipage" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "delete_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
]),
(60, "stakeholder", "Stakeholder", False, [
[ "add_issue", "issues", "issue" ],
[ "change_issue", "issues", "issue" ],
[ "delete_issue", "issues", "issue" ],
[ "view_issue", "issues", "issue" ],
[ "view_milestone", "milestones", "milestone" ],
[ "add_attachment", "projects", "attachment" ],
[ "change_attachment", "projects", "attachment" ],
[ "delete_attachment", "projects", "attachment" ],
[ "view_attachment", "projects", "attachment" ],
[ "view_issuestatus", "projects", "issuestatus" ],
[ "view_issuetype", "projects", "issuetype" ],
[ "view_membership", "projects", "membership" ],
[ "view_points", "projects", "points" ],
[ "view_priority", "projects", "priority" ],
[ "view_project", "projects", "project" ],
[ "view_severity", "projects", "severity" ],
[ "view_taskstatus", "projects", "taskstatus" ],
[ "view_userstorystatus", "projects", "userstorystatus" ],
[ "view_task", "tasks", "task" ],
[ "view_role", "users", "role" ],
[ "change_user", "users", "user" ],
[ "view_user", "users", "user" ],
[ "view_rolepoints", "userstories", "rolepoints" ],
[ "view_userstory", "userstories", "userstory" ],
[ "change_wikipage", "wiki", "wikipage" ],
[ "view_wikipage", "wiki", "wikipage" ]
])
)

File diff suppressed because one or more lines are too long

View File

@ -15,7 +15,7 @@ from . import create_issue
class IssuesTestCase(test.TestCase): class IssuesTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) # Project owner self.user1 = create_user(1) # Project owner

View File

@ -30,7 +30,7 @@ from . import create_milestone
class MilestonesTestCase(test.TestCase): class MilestonesTestCase(test.TestCase):
fixtures = ["initial_domains.json",] fixtures = ["initial_domains.json", "initial_project_templates.json",]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)

View File

@ -31,6 +31,7 @@ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from picklefield.fields import PickledObjectField from picklefield.fields import PickledObjectField
from django_pgjson.fields import JsonField
from taiga.users.models import Role from taiga.users.models import Role
from taiga.domains.models import DomainMember from taiga.domains.models import DomainMember
@ -520,6 +521,241 @@ class QuestionStatus(models.Model):
return self.name return self.name
class ProjectTemplate(models.Model):
name = models.CharField(max_length=250, unique=True, null=False, blank=False,
verbose_name=_("name"))
slug = models.SlugField(max_length=250, unique=True, null=False, blank=True,
verbose_name=_("slug"))
description = models.TextField(null=False, blank=False,
verbose_name=_("description"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
verbose_name=_("modified date"))
domain = models.ForeignKey("domains.Domain", related_name="templates", null=True, blank=True,
default=None, verbose_name=_("domain"))
is_backlog_activated = models.BooleanField(default=True, null=False, blank=True,
verbose_name=_("active backlog panel"))
is_kanban_activated = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("active kanban panel"))
is_wiki_activated = models.BooleanField(default=True, null=False, blank=True,
verbose_name=_("active wiki panel"))
is_issues_activated = models.BooleanField(default=True, null=False, blank=True,
verbose_name=_("active issues panel"))
videoconferences = models.CharField(max_length=250, null=True, blank=True,
choices=choices.VIDEOCONFERENCES_CHOICES,
verbose_name=_("videoconference system"))
videoconferences_salt = models.CharField(max_length=250, null=True, blank=True,
verbose_name=_("videoconference room salt"))
default_options = JsonField(null=True, blank=True, default=None, verbose_name=_("default options"))
us_statuses = JsonField(null=True, blank=True, default=None, verbose_name=_("us statuses"))
points = JsonField(null=True, blank=True, default=None, verbose_name=_("us points"))
task_statuses = JsonField(null=True, blank=True, default=None, verbose_name=_("task statuses"))
issue_statuses = JsonField(null=True, blank=True, default=None, verbose_name=_("issue statuses"))
issue_types = JsonField(null=True, blank=True, default=None, verbose_name=_("issue types"))
priorities = JsonField(null=True, blank=True, default=None, verbose_name=_("issue types"))
severities = JsonField(null=True, blank=True, default=None, verbose_name=_("issue types"))
roles = JsonField(null=True, blank=True, default=None, verbose_name=_("roles"))
class Meta:
verbose_name = "project template"
verbose_name_plural = "project templates"
ordering = ["name"]
def __str__(self):
return self.name
def __repr__(self):
return "<Project Template {0}>".format(self.slug)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
def load_data_from_project(self, project):
self.is_backlog_activated = project.is_backlog_activated
self.is_kanban_activated = project.is_kanban_activated
self.is_wiki_activated = project.is_wiki_activated
self.is_issues_activated = project.is_issues_activated
self.videoconferences = project.videoconferences
self.videoconferences_salt = project.videoconferences_salt
self.default_options = {
"points": project.default_points.name,
"us_status": project.default_us_status.name,
"task_status": project.default_task_status.name,
"issue_status": project.default_issue_status.name,
"issue_type": project.default_issue_type.name,
"priority": project.default_priority.name,
"severity": project.default_severity.name
}
self.us_statuses = []
for us_status in project.us_statuses.all():
self.us_statuses.append({
"name": us_status.name,
"is_closed": us_status.is_closed,
"color": us_status.color,
"wip_limit": us_status.wip_limit,
"order": us_status.order,
})
self.points = []
for us_point in project.points.all():
self.points.append({
"name": us_point.name,
"value": us_point.value,
"order": us_point.order,
})
self.task_statuses = []
for task_status in project.task_statuses.all():
self.task_statuses.append({
"name": task_status.name,
"is_closed": task_status.is_closed,
"color": task_status.color,
"order": task_status.order,
})
self.issue_statuses = []
for issue_status in project.issue_statuses.all():
self.issue_statuses.append({
"name": issue_status.name,
"is_closed": issue_status.is_closed,
"color": issue_status.color,
"order": issue_status.order,
})
self.issue_types = []
for issue_type in project.issue_types.all():
self.issue_types.append({
"name": issue_type.name,
"color": issue_type.color,
"order": issue_type.order,
})
self.priorities = []
for priority in project.priorities.all():
self.priorities.append({
"name": priority.name,
"color": priority.color,
"order": priority.order,
})
self.severities = []
for severity in project.severities.all():
self.severities.append({
"name": severity.name,
"color": severity.color,
"order": severity.order,
})
self.roles = []
for role in project.roles.all():
permissions = [p.codename for p in role.permissions.all()]
self.roles.append({
"name": role.name,
"slug": role.slug,
"permissions": permissions,
"order": role.order,
"computable": role.computable
})
def apply_to_project(self, project):
if project.id is None:
raise "Project need an id (must be a saved project)"
project.is_backlog_activated = self.is_backlog_activated
project.is_kanban_activated = self.is_kanban_activated
project.is_wiki_activated = self.is_wiki_activated
project.is_issues_activated = self.is_issues_activated
project.videoconferences = self.videoconferences
project.videoconferences_salt = self.videoconferences_salt
for us_status in self.us_statuses:
UserStoryStatus.objects.create(
name=us_status["name"],
is_closed=us_status["is_closed"],
color=us_status["color"],
wip_limit=us_status["wip_limit"],
order=us_status["order"],
project=project
)
for point in self.points:
Points.objects.create(
name=point["name"],
value=point["value"],
order=point["order"],
project=project
)
for task_status in self.task_statuses:
TaskStatus.objects.create(
name=task_status["name"],
is_closed=task_status["is_closed"],
color=task_status["color"],
order=task_status["order"],
project=project
)
for issue_status in self.issue_statuses:
IssueStatus.objects.create(
name=issue_status["name"],
is_closed=issue_status["is_closed"],
color=issue_status["color"],
order=issue_status["order"],
project=project
)
for issue_type in self.issue_types:
IssueType.objects.create(
name=issue_type["name"],
color=issue_type["color"],
order=issue_type["order"],
project=project
)
for priority in self.priorities:
Priority.objects.create(
name=priority["name"],
color=priority["color"],
order=priority["order"],
project=project
)
for severity in self.severities:
Severity.objects.create(
name=severity["name"],
color=severity["color"],
order=severity["order"],
project=project
)
for role in self.roles:
newRoleInstance = Role.objects.create(
name=role["name"],
slug=role["slug"],
order=role["order"],
computable=role["computable"],
project=project
)
permissions = [Permission.objects.get(codename=codename) for codename in role["permissions"]]
for permission in permissions:
newRoleInstance.permissions.add(permission)
project.default_points = Points.objects.get(name=self.default_options["points"], project=project)
project.default_us_status = UserStoryStatus.objects.get(name=self.default_options["us_status"], project=project)
project.default_task_status = TaskStatus.objects.get(name=self.default_options["task_status"], project=project)
project.default_issue_status = IssueStatus.objects.get(name=self.default_options["issue_status"], project=project)
project.default_issue_type = IssueType.objects.get(name=self.default_options["issue_type"], project=project)
project.default_priority = Priority.objects.get(name=self.default_options["priority"], project=project)
project.default_severity = Severity.objects.get(name=self.default_options["severity"], project=project)
return project
# Reversion registration (usufull for base.notification and for meke a historical) # Reversion registration (usufull for base.notification and for meke a historical)
reversion.register(Project) reversion.register(Project)
reversion.register(Attachment) reversion.register(Attachment)
@ -570,67 +806,7 @@ def project_post_save(sender, instance, created, **kwargs):
if not created: if not created:
return return
# USs template_slug = getattr(instance, "template", settings.DEFAULT_PROJECT_TEMPLATE)
for order, name, value, is_default in choices.POINTS_CHOICES: template = ProjectTemplate.objects.get(slug=template_slug, domain__isnull=True)
obj = Points.objects.create(project=instance, name=name, order=order, value=value) template.apply_to_project(instance)
if is_default:
instance.default_points = obj
for order, name, is_closed, is_default, color in choices.US_STATUSES:
obj = UserStoryStatus.objects.create(name=name, order=order, color=color,
is_closed=is_closed, project=instance)
if is_default:
instance.default_us_status = obj
# Tasks
for order, name, is_closed, is_default, color in choices.TASK_STATUSES:
obj = TaskStatus.objects.create(name=name, order=order, color=color,
is_closed=is_closed, project=instance)
if is_default:
instance.default_task_status = obj
# Issues
for order, name, color, is_default in choices.PRIORITY_CHOICES:
obj = Priority.objects.create(project=instance, name=name, order=order, color=color)
if is_default:
instance.default_priority = obj
for order, name, color, is_default in choices.SEVERITY_CHOICES:
obj = Severity.objects.create(project=instance, name=name, order=order, color=color)
if is_default:
instance.default_severity = obj
for order, name, is_closed, color, is_default in choices.ISSUE_STATUSES:
obj = IssueStatus.objects.create(name=name, order=order,
is_closed=is_closed, project=instance, color=color)
if is_default:
instance.default_issue_status = obj
for order, name, color, is_default in choices.ISSUE_TYPES:
obj = IssueType.objects.create(project=instance, name=name, order=order, color=color)
if is_default:
instance.default_issue_type = obj
# Questions
for order, name, is_closed, color, is_default in choices.QUESTION_STATUS:
obj = QuestionStatus.objects.create(name=name, order=order,
is_closed=is_closed, project=instance, color=color)
if is_default:
instance.default_question_status = obj
# Permissions
for order, slug, name, computable, permissions in choices.ROLES:
obj = Role.objects.create(slug=slug, name=name, order=order, computable=computable, project=instance)
for permission in permissions:
try:
perm = Permission.objects.get(codename=permission[0], content_type__app_label=permission[1], content_type__model=permission[2])
obj.permissions.add(perm)
except Permission.DoesNotExist:
pass
instance.save() instance.save()
from taiga.projects.template_manager import ProjectTemplateManager
if hasattr(instance, "template"):
template_manager = ProjectTemplateManager()
template_manager.apply(instance.template, instance)

View File

@ -168,3 +168,12 @@ class QuestionStatusPermission(BasePermission):
delete_permission = "delete_questionstatus" delete_permission = "delete_questionstatus"
safe_methods = ["HEAD", "OPTIONS"] safe_methods = ["HEAD", "OPTIONS"]
path_to_project = ["project"] path_to_project = ["project"]
class ProjectTemplatePermission(BasePermission):
def has_permission(self, request, view):
domain = get_active_domain()
return domain.user_is_owner(request.user)
def has_object_permission(self, request, view, obj):
domain = get_active_domain()
return domain.user_is_owner(request.user)

View File

@ -17,7 +17,7 @@
from os import path from os import path
from rest_framework import serializers from rest_framework import serializers
from taiga.base.serializers import PickleField from taiga.base.serializers import PickleField, JsonField, AutoDomainField
from taiga.users.models import Role from taiga.users.models import Role
from . import models from . import models
@ -182,3 +182,20 @@ class RoleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Role model = Role
fields = ('id', 'name', 'permissions', 'computable', 'project', 'order') fields = ('id', 'name', 'permissions', 'computable', 'project', 'order')
class ProjectTemplateSerializer(serializers.ModelSerializer):
domain = AutoDomainField()
default_options = JsonField()
us_statuses = JsonField()
points = JsonField()
task_statuses = JsonField()
issue_statuses = JsonField()
issue_types = JsonField()
priorities = JsonField()
severities = JsonField()
roles = JsonField()
class Meta:
model = models.ProjectTemplate

View File

@ -34,7 +34,7 @@ from . import create_task
class TasksTestCase(test.TestCase): class TasksTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) # Project owner self.user1 = create_user(1) # Project owner

View File

@ -1,54 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from taiga.projects.models import UserStoryStatus
class ProjectTemplateManager(object):
def apply(self, template, project):
if not hasattr(self, "template"):
return False
template = getattr(self, "template")
template(project)
def legal(self, project):
pass
def pure_kanban(self, project):
project.is_backlog_activated = False
project.is_kanban_activated = True
project.is_wiki_activated = False
project.is_issues_activated = False
project.save()
us_status = project.us_statuses.get(order=1)
us_status.name = "To do"
us_status.color = "#999999"
us_status.save()
us_status = project.us_statuses.get(order=2)
us_status.name = "Doing"
us_status.color = "#ff9900"
us_status.is_closed = False
us_status.save()
us_status = UserStoryStatus()
us_status.order = 3
us_status.name = "Done"
us_status.color = "#ffcc00"
us_status.project = project
us_status.is_closed = True
us_status.save()

View File

@ -24,14 +24,15 @@ from django.core import mail
from django.db.models import get_model from django.db.models import get_model
from taiga.users.tests import create_user from taiga.users.tests import create_user
from taiga.projects.models import Project, Membership from taiga.projects.models import Project, Membership, ProjectTemplate
from taiga.domains.models import Domain
from . import create_project from . import create_project
from . import add_membership from . import add_membership
class ProfileTestCase(test.TestCase): class ProfileTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1, is_superuser=True) self.user1 = create_user(1, is_superuser=True)
@ -182,7 +183,7 @@ class ProfileTestCase(test.TestCase):
class ProjectsTestCase(test.TestCase): class ProjectsTestCase(test.TestCase):
fixtures = ["initial_role.json", "initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)
@ -462,3 +463,264 @@ class ProjectsTestCase(test.TestCase):
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
self.assertEqual(Project.objects.all().count(), 4) self.assertEqual(Project.objects.all().count(), 4)
self.client.logout() self.client.logout()
class ProjectTemplatesTestCase(test.TestCase):
fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self):
self.user1 = create_user(1)
self.user2 = create_user(2)
self.domain = Domain.objects.all()[0]
self.domain.owner = self.user1
def test_list_project_templates_by_anon(self):
response = self.client.get(reverse("project-templates-list"))
self.assertEqual(response.status_code, 401)
def test_list_project_templates_by_domain_owner(self):
response = self.client.login(username=self.user1.username,
password=self.user1.username)
self.assertTrue(response)
response = self.client.get(reverse("project-templates-list"))
self.assertEqual(response.status_code, 200)
projects_list = response.data
self.assertEqual(len(projects_list), 2)
self.client.logout()
def test_list_projects_by_not_domain_owner(self):
response = self.client.login(username=self.user2.username,
password=self.user2.username)
self.assertTrue(response)
response = self.client.get(reverse("project-templates-list"))
self.assertEqual(response.status_code, 403)
def test_view_project_template_by_anon(self):
response = self.client.get(reverse("project-templates-detail", args=(1,)))
self.assertEqual(response.status_code, 401)
def test_view_project_template_by_domain_owner(self):
response = self.client.login(username=self.user1.username,
password=self.user1.username)
self.assertTrue(response)
response = self.client.get(reverse("project-templates-detail", args=(1,)))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("project-templates-detail", args=(2,)))
self.assertEqual(response.status_code, 200)
self.client.logout()
def test_view_project_template_by_not_domain_owner(self):
response = self.client.login(username=self.user2.username,
password=self.user2.username)
self.assertTrue(response)
response = self.client.get(reverse("project-templates-detail", args=(1,)))
self.assertEqual(response.status_code, 403)
response = self.client.get(reverse("project-templates-detail", args=(2,)))
self.assertEqual(response.status_code, 403)
self.client.logout()
def test_create_project_template_by_anon(self):
data = {
"name": "Test Project Template",
"slug": "test-project-template",
"description": "A new Test Project Template",
}
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
response = self.client.post(
reverse("project-templates-list"),
json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 401)
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
data = {
"name": "Test Project Template 2",
"slug": "test-project-template-2",
"description": "A new Test Project Template",
"domain": 100,
}
response = self.client.post(
reverse("project-templates-list"),
json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 401)
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
def test_create_project_template_by_domain_owner(self):
data = {
"name": "Test Project Template",
"slug": "test-project-template",
"description": "A new Test Project Template",
}
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
response = self.client.login(username=self.user1.username,
password=self.user1.username)
self.assertTrue(response)
response = self.client.post(reverse("project-templates-list"), json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 201)
self.assertEqual(ProjectTemplate.objects.all().count(), 3)
data = {
"name": "Test Project Template 2",
"slug": "test-project-template-2",
"description": "A new Test Project Template",
"domain": 100,
}
response = self.client.login(username=self.user1.username,
password=self.user1.username)
self.assertTrue(response)
response = self.client.post(reverse("project-templates-list"), json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 201)
self.assertEqual(ProjectTemplate.objects.all().count(), 4)
template = ProjectTemplate.objects.order_by('-created_date')[0]
self.assertEqual(template.domain.id, 1)
self.client.logout()
ProjectTemplate.objects.order_by("created_date")[0:2].delete()
def test_create_project_template_by_not_domain_owner(self):
data = {
"name": "Test Project Template",
"slug": "test-project-template",
"description": "A new Test Project Template",
}
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
response = self.client.login(username=self.user1.username,
password=self.user1.username)
self.assertTrue(response)
response = self.client.post(
reverse("project-templates-list"),
json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 401)
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
data = {
"name": "Test Project Template 2",
"slug": "test-project-template-2",
"description": "A new Test Project Template",
"domain": 100
}
response = self.client.post(
reverse("project-templates-list"),
json.dumps(data),
content_type="application/json")
self.assertEqual(response.status_code, 401)
self.assertEqual(ProjectTemplate.objects.all().count(), 2)
self.client.logout()
# def test_edit_project_by_anon(self):
# data = {
# "description": "Edited project description",
# }
# self.assertEqual(Project.objects.all().count(), 4)
# self.assertNotEqual(data["description"], self.project1.description)
# response = self.client.patch(
# reverse("projects-detail", args=(self.project1.id,)),
# json.dumps(data),
# content_type="application/json")
# self.assertEqual(response.status_code, 401)
# self.assertEqual(Project.objects.all().count(), 4)
# def test_edit_project_by_owner(self):
# data = {
# "description": "Modified project description",
# }
# self.assertEqual(Project.objects.all().count(), 4)
# self.assertNotEqual(data["description"], self.project1.description)
# response = self.client.login(username=self.user1.username,
# password=self.user1.username)
# self.assertTrue(response)
# response = self.client.patch(
# reverse("projects-detail", args=(self.project1.id,)),
# json.dumps(data),
# content_type="application/json")
# self.assertEqual(response.status_code, 200)
# self.assertEqual(data["description"], response.data["description"])
# self.assertEqual(Project.objects.all().count(), 4)
# self.client.logout()
# def test_edit_project_by_membership(self):
# data = {
# "description": "Edited project description",
# }
# self.assertEqual(Project.objects.all().count(), 4)
# self.assertNotEqual(data["description"], self.project1.description)
# response = self.client.login(username=self.user3.username,
# password=self.user3.username)
# self.assertTrue(response)
# response = self.client.patch(
# reverse("projects-detail", args=(self.project1.id,)),
# json.dumps(data),
# content_type="application/json")
# self.assertEqual(response.status_code, 200)
# self.assertEqual(data["description"], response.data["description"])
# self.assertEqual(Project.objects.all().count(), 4)
# self.client.logout()
# def test_edit_project_by_not_membership(self):
# data = {
# "description": "Edited project description",
# }
# self.assertEqual(Project.objects.all().count(), 4)
# self.assertNotEqual(data["description"], self.project1.description)
# response = self.client.login(username=self.user2.username,
# password=self.user2.username)
# self.assertTrue(response)
# response = self.client.patch(
# reverse("projects-detail", args=(self.project1.id,)),
# json.dumps(data),
# content_type="application/json")
# self.assertEqual(response.status_code, 404)
# self.assertEqual(Project.objects.all().count(), 4)
# self.client.logout()
# def test_delete_project_by_anon(self):
# self.assertEqual(Project.objects.all().count(), 4)
# response = self.client.delete(reverse("projects-detail", args=(self.project1.id,)))
# self.assertEqual(response.status_code, 401)
# self.assertEqual(Project.objects.all().count(), 4)
# def test_delete_project_by_owner(self):
# self.assertEqual(Project.objects.all().count(), 4)
# response = self.client.login(username=self.user1.username,
# password=self.user1.username)
# self.assertTrue(response)
# response = self.client.delete(reverse("projects-detail", args=(self.project1.id,)))
# self.assertEqual(response.status_code, 204)
# self.assertEqual(Project.objects.all().count(), 3)
# self.client.logout()
# def test_delete_project_by_membership(self):
# self.assertEqual(Project.objects.all().count(), 4)
# response = self.client.login(username=self.user3.username,
# password=self.user3.username)
# self.assertTrue(response)
# response = self.client.delete(reverse("projects-detail", args=(self.project1.id,)))
# self.assertEqual(response.status_code, 403)
# self.assertEqual(Project.objects.all().count(), 4)
# self.client.logout()
# def test_delete_project_by_not_membership(self):
# self.assertEqual(Project.objects.all().count(), 4)
# response = self.client.login(username=self.user1.username,
# password=self.user1.username)
# self.assertTrue(response)
# response = self.client.delete(reverse("projects-detail", args=(self.project3.id,)))
# self.assertEqual(response.status_code, 404)
# self.assertEqual(Project.objects.all().count(), 4)
# self.client.logout()

View File

@ -32,7 +32,7 @@ from . import create_project
from . import add_membership from . import add_membership
class AllProjectEventsNotificationsTestCase(test.TestCase): class AllProjectEventsNotificationsTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)
@ -82,7 +82,7 @@ class AllProjectEventsNotificationsTestCase(test.TestCase):
self.user1.save() self.user1.save()
class OnlyAssigendNotificationsTestCase(test.TestCase): class OnlyAssigendNotificationsTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)
@ -153,7 +153,7 @@ class OnlyAssigendNotificationsTestCase(test.TestCase):
self.user1.save() self.user1.save()
class OnlyOwnerNotificationsTestCase(test.TestCase): class OnlyOwnerNotificationsTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)

View File

@ -33,7 +33,7 @@ import reversion
class UserStoriesTestCase(test.TestCase): class UserStoriesTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) # Project owner self.user1 = create_user(1) # Project owner

View File

@ -26,7 +26,7 @@ from . import create_userstory
class UserStoriesServiceTestCase(test.TestCase): class UserStoriesServiceTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) # Project owner self.user1 = create_user(1) # Project owner

View File

@ -30,7 +30,7 @@ from . import create_wiki_page
class WikiPagesTestCase(test.TestCase): class WikiPagesTestCase(test.TestCase):
fixtures = ["initial_domains.json"] fixtures = ["initial_domains.json", "initial_project_templates.json"]
def setUp(self): def setUp(self):
self.user1 = create_user(1) self.user1 = create_user(1)

View File

@ -64,9 +64,11 @@ from taiga.projects.api import IssueStatusViewSet
from taiga.projects.api import IssueTypeViewSet from taiga.projects.api import IssueTypeViewSet
from taiga.projects.api import PriorityViewSet from taiga.projects.api import PriorityViewSet
from taiga.projects.api import SeverityViewSet from taiga.projects.api import SeverityViewSet
from taiga.projects.api import ProjectTemplateViewSet
router.register(r"roles", RolesViewSet, base_name="roles") router.register(r"roles", RolesViewSet, base_name="roles")
router.register(r"projects", ProjectViewSet, base_name="projects") router.register(r"projects", ProjectViewSet, base_name="projects")
router.register(r"project-templates", ProjectTemplateViewSet, base_name="project-templates")
router.register(r"memberships", MembershipViewSet, base_name="memberships") router.register(r"memberships", MembershipViewSet, base_name="memberships")
router.register(r"invitations", InvitationViewSet, base_name="invitations") router.register(r"invitations", InvitationViewSet, base_name="invitations")
router.register(r"userstory-statuses", UserStoryStatusViewSet, base_name="userstory-statuses") router.register(r"userstory-statuses", UserStoryStatusViewSet, base_name="userstory-statuses")