US #2929: Ability to edit commit and see their history
parent
4e8495a167
commit
81b41529d2
|
@ -1,5 +1,9 @@
|
||||||
# Changelog #
|
# Changelog #
|
||||||
|
|
||||||
|
## 2.2.0 ??? (unreleased)
|
||||||
|
### Features
|
||||||
|
- [API] edit comment endpoint: comment owners and project admins can edit existing comments
|
||||||
|
|
||||||
|
|
||||||
## 2.1.0 Ursus Americanus (2016-05-03)
|
## 2.1.0 Ursus Americanus (2016-05-03)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ from taiga.base import response
|
||||||
from taiga.base.decorators import detail_route
|
from taiga.base.decorators import detail_route
|
||||||
from taiga.base.api import ReadOnlyListViewSet
|
from taiga.base.api import ReadOnlyListViewSet
|
||||||
from taiga.base.api.utils import get_object_or_404
|
from taiga.base.api.utils import get_object_or_404
|
||||||
|
from taiga.mdrender.service import render as mdrender
|
||||||
|
|
||||||
from . import permissions
|
from . import permissions
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
@ -56,42 +57,93 @@ class HistoryViewSet(ReadOnlyListViewSet):
|
||||||
|
|
||||||
return response.Ok(serializer.data)
|
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'])
|
@detail_route(methods=['post'])
|
||||||
def delete_comment(self, request, pk):
|
def delete_comment(self, request, pk):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
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()
|
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")})
|
return response.BadRequest({"error": _("Comment already deleted")})
|
||||||
|
|
||||||
comment.delete_comment_date = timezone.now()
|
history_entry.delete_comment_date = timezone.now()
|
||||||
comment.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
|
history_entry.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
|
||||||
comment.save()
|
history_entry.save()
|
||||||
return response.Ok()
|
return response.Ok()
|
||||||
|
|
||||||
@detail_route(methods=['post'])
|
@detail_route(methods=['post'])
|
||||||
def undelete_comment(self, request, pk):
|
def undelete_comment(self, request, pk):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
history_entry_id = request.QUERY_PARAMS.get('id', None)
|
||||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
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()
|
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")})
|
return response.BadRequest({"error": _("Comment not deleted")})
|
||||||
|
|
||||||
comment.delete_comment_date = None
|
history_entry.delete_comment_date = None
|
||||||
comment.delete_comment_user = None
|
history_entry.delete_comment_user = None
|
||||||
comment.save()
|
history_entry.save()
|
||||||
return response.Ok()
|
return response.Ok()
|
||||||
|
|
||||||
# Just for restframework! Because it raises
|
# 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_date = models.DateTimeField(null=True, blank=True, default=None)
|
||||||
delete_comment_user = JsonField(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
|
# Flag for mark some history entries as
|
||||||
# hidden. Hidden history entries are important
|
# hidden. Hidden history entries are important
|
||||||
# for save but not important to preview.
|
# for save but not important to preview.
|
||||||
|
@ -111,6 +115,20 @@ class HistoryEntry(models.Model):
|
||||||
self._owner = owner
|
self._owner = owner
|
||||||
self._prefetched_owner = True
|
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
|
@cached_property
|
||||||
def values_diff(self):
|
def values_diff(self):
|
||||||
result = {}
|
result = {}
|
||||||
|
|
|
@ -33,32 +33,41 @@ class IsCommentOwner(PermissionComponent):
|
||||||
return obj.user and obj.user.get("pk", "not-pk") == request.user.pk
|
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):
|
def check_permissions(self, request, view, obj=None):
|
||||||
model = get_model_from_key(obj.key)
|
model = get_model_from_key(obj.key)
|
||||||
pk = get_pk_from_key(obj.key)
|
pk = get_pk_from_key(obj.key)
|
||||||
project = model.objects.get(pk=pk)
|
project = model.objects.get(pk=pk)
|
||||||
return is_project_admin(request.user, project)
|
return is_project_admin(request.user, project)
|
||||||
|
|
||||||
|
|
||||||
class UserStoryHistoryPermission(TaigaResourcePermission):
|
class UserStoryHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||||
|
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
|
||||||
|
|
||||||
class TaskHistoryPermission(TaigaResourcePermission):
|
class TaskHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||||
|
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
|
||||||
|
|
||||||
class IssueHistoryPermission(TaigaResourcePermission):
|
class IssueHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
delete_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
undelete_comment_perms = IsCommentProjectAdmin() | IsCommentDeleter()
|
||||||
|
comment_versions_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
|
|
||||||
|
|
||||||
class WikiHistoryPermission(TaigaResourcePermission):
|
class WikiHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
delete_comment_perms = IsCommentProjectOwner() | IsCommentOwner()
|
edit_comment_perms = IsCommentProjectAdmin() | IsCommentOwner()
|
||||||
undelete_comment_perms = IsCommentProjectOwner() | IsCommentDeleter()
|
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)
|
values_diff = I18NJsonField(i18n_fields=HISTORY_ENTRY_I18N_FIELDS)
|
||||||
user = serializers.SerializerMethodField("get_user")
|
user = serializers.SerializerMethodField("get_user")
|
||||||
delete_comment_user = JsonField()
|
delete_comment_user = JsonField()
|
||||||
|
comment_versions = JsonField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.HistoryEntry
|
model = models.HistoryEntry
|
||||||
|
exclude = ("comment_versions",)
|
||||||
|
|
||||||
def get_user(self, entry):
|
def get_user(self, entry):
|
||||||
user = {"pk": None, "username": None, "name": None, "photo": None, "is_active": False}
|
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
|
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):
|
def register_values_implementation(typename:str, fn=None):
|
||||||
"""
|
"""
|
||||||
Register values implementation for specified typename.
|
Register values implementation for specified typename.
|
||||||
|
|
|
@ -44,7 +44,6 @@ def _clean_description_fields(values_diff):
|
||||||
|
|
||||||
|
|
||||||
def on_new_history_entry(sender, instance, created, **kwargs):
|
def on_new_history_entry(sender, instance, created, **kwargs):
|
||||||
|
|
||||||
if instance._importing:
|
if instance._importing:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -81,6 +80,10 @@ def on_new_history_entry(sender, instance, created, **kwargs):
|
||||||
if instance.delete_comment_date:
|
if instance.delete_comment_date:
|
||||||
extra_data["comment_deleted"] = True
|
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
|
created_datetime = instance.created_at
|
||||||
_push_to_timelines(project, user, obj, event_type, created_datetime, extra_data=extra_data)
|
_push_to_timelines(project, user, obj, event_type, created_datetime, extra_data=extra_data)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from taiga.base.utils import json
|
||||||
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_PERMISSIONS
|
from taiga.permissions.permissions import MEMBERS_PERMISSIONS, ANON_PERMISSIONS, USER_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 import factories as f
|
||||||
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
from tests.utils import helper_test_http_method, disconnect_signals, reconnect_signals
|
||||||
|
@ -21,11 +26,11 @@ def teardown_module(module):
|
||||||
def data():
|
def data():
|
||||||
m = type("Models", (object,), {})
|
m = type("Models", (object,), {})
|
||||||
|
|
||||||
m.registered_user = f.UserFactory.create()
|
m.registered_user = f.UserFactory.create(full_name="registered_user")
|
||||||
m.project_member_with_perms = f.UserFactory.create()
|
m.project_member_with_perms = f.UserFactory.create(full_name="project_member_with_perms")
|
||||||
m.project_member_without_perms = f.UserFactory.create()
|
m.project_member_without_perms = f.UserFactory.create(full_name="project_member_without_perms")
|
||||||
m.project_owner = f.UserFactory.create()
|
m.project_owner = f.UserFactory.create(full_name="project_owner")
|
||||||
m.other_user = f.UserFactory.create()
|
m.other_user = f.UserFactory.create(full_name="other_user")
|
||||||
|
|
||||||
m.public_project = f.ProjectFactory(is_private=False,
|
m.public_project = f.ProjectFactory(is_private=False,
|
||||||
anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
anon_permissions=list(map(lambda x: x[0], ANON_PERMISSIONS)),
|
||||||
|
@ -76,39 +81,33 @@ def data():
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################
|
||||||
|
## User stories
|
||||||
|
#########################################################
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def data_us(data):
|
def data_us(data):
|
||||||
m = type("Models", (object,), {})
|
m = type("Models", (object,), {})
|
||||||
m.public_user_story = f.UserStoryFactory(project=data.public_project, ref=1)
|
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_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)
|
m.private_user_story2 = f.UserStoryFactory(project=data.private_project2, ref=9)
|
||||||
return m
|
m.private_history_entry2 = f.HistoryEntryFactory.create(type=HistoryType.change,
|
||||||
|
comment="testing 2",
|
||||||
|
key=make_key_from_model_object(m.private_user_story2),
|
||||||
@pytest.fixture
|
diff={},
|
||||||
def data_task(data):
|
user={"pk": data.project_member_with_perms.pk})
|
||||||
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)
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,6 +132,222 @@ def test_user_story_history_retrieve(client, data, data_us):
|
||||||
assert results == [401, 403, 403, 200, 200]
|
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):
|
def test_task_history_retrieve(client, data, data_task):
|
||||||
public_url = reverse('task-history-detail', kwargs={"pk": data_task.public_task.pk})
|
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})
|
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]
|
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):
|
def test_issue_history_retrieve(client, data, data_issue):
|
||||||
public_url = reverse('issue-history-detail', kwargs={"pk": data_issue.public_issue.pk})
|
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})
|
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]
|
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):
|
def test_wiki_history_retrieve(client, data, data_wiki):
|
||||||
public_url = reverse('wiki-history-detail', kwargs={"pk": data_wiki.public_wiki.pk})
|
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})
|
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]
|
assert results == [200, 200, 200, 200, 200]
|
||||||
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
results = helper_test_http_method(client, 'get', private_url2, None, users)
|
||||||
assert results == [401, 403, 403, 200, 200]
|
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]
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import datetime
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
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)
|
url = "%s?id=%s" % (url, history_entry.id)
|
||||||
response = client.post(url, content_type="application/json")
|
response = client.post(url, content_type="application/json")
|
||||||
assert 200 == response.status_code, response.status_code
|
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
|
||||||
|
|
Loading…
Reference in New Issue