mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-17 07:41:26 +00:00
[api] Add file comment endpoints
This commit is contained in:
51
seahub/api2/endpoints/file_comment.py
Normal file
51
seahub/api2/endpoints/file_comment.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
from seahub.api2.permissions import IsRepoAccessible
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentView(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated, IsRepoAccessible)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, repo_id, pk, format=None):
|
||||||
|
"""Get a comment.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
o = FileComment.objects.get(pk=pk)
|
||||||
|
except FileComment.DoesNotExist:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id')
|
||||||
|
|
||||||
|
return Response(o.to_dict())
|
||||||
|
|
||||||
|
def delete(self, request, repo_id, pk, format=None):
|
||||||
|
"""Delete a comment, only comment author or repo owner can perform
|
||||||
|
this op.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
o = FileComment.objects.get(pk=pk)
|
||||||
|
except FileComment.DoesNotExist:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id')
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
if username != o.author and \
|
||||||
|
not seafile_api.is_repo_owner(username, repo_id):
|
||||||
|
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
|
||||||
|
|
||||||
|
o.delete()
|
||||||
|
|
||||||
|
return Response(status=204)
|
64
seahub/api2/endpoints/file_comments.py
Normal file
64
seahub/api2/endpoints/file_comments.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
from seahub.api2.permissions import IsRepoAccessible
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentsView(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated, IsRepoAccessible)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, repo_id, format=None):
|
||||||
|
"""List all comments of a file.
|
||||||
|
"""
|
||||||
|
path = request.GET.get('p', '/').rstrip('/')
|
||||||
|
if not path:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')
|
||||||
|
|
||||||
|
comments = []
|
||||||
|
for o in FileComment.objects.get_by_file_path(repo_id, path):
|
||||||
|
comments.append(o.to_dict())
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
"comments": comments,
|
||||||
|
})
|
||||||
|
|
||||||
|
def post(self, request, repo_id, format=None):
|
||||||
|
"""Post a comments of a file.
|
||||||
|
"""
|
||||||
|
path = request.GET.get('p', '/').rstrip('/')
|
||||||
|
if not path:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = seafile_api.get_file_id_by_path(repo_id,
|
||||||
|
path)
|
||||||
|
except SearpcError as e:
|
||||||
|
logger.error(e)
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
'Internal error.')
|
||||||
|
if not obj_id:
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, 'File not found.')
|
||||||
|
|
||||||
|
comment = request.data.get('comment', '')
|
||||||
|
if not comment:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.')
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
o = FileComment.objects.add_by_file_path(
|
||||||
|
repo_id=repo_id, file_path=path, author=username, comment=comment)
|
||||||
|
return Response(o.to_dict(), status=201)
|
50
seahub/api2/endpoints/file_comments_counts.py
Normal file
50
seahub/api2/endpoints/file_comments_counts.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
from seahub.api2.permissions import IsRepoAccessible
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentsCounts(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated, IsRepoAccessible)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, repo_id, format=None):
|
||||||
|
"""Count all comments of all file under certain parent dir.
|
||||||
|
"""
|
||||||
|
path = request.GET.get('p', '/')
|
||||||
|
if not path:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = seafile_api.get_dir_id_by_path(repo_id,
|
||||||
|
path)
|
||||||
|
except SearpcError as e:
|
||||||
|
logger.error(e)
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
'Internal error.')
|
||||||
|
if not obj_id:
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, 'Parent dir not found.')
|
||||||
|
|
||||||
|
d = {}
|
||||||
|
for o in FileComment.objects.get_by_parent_path(repo_id, path):
|
||||||
|
d[o.item_name] = d.get(o.item_name, 0) + 1
|
||||||
|
|
||||||
|
ret = []
|
||||||
|
for k, v in d.iteritems():
|
||||||
|
ret.append({k: v})
|
||||||
|
|
||||||
|
return Response(ret)
|
@@ -7,6 +7,9 @@ from .endpoints.dir_shared_items import DirSharedItemsEndpoint
|
|||||||
from .endpoints.account import Account
|
from .endpoints.account import Account
|
||||||
from .endpoints.shared_upload_links import SharedUploadLinksView
|
from .endpoints.shared_upload_links import SharedUploadLinksView
|
||||||
from .endpoints.be_shared_repo import BeSharedReposView
|
from .endpoints.be_shared_repo import BeSharedReposView
|
||||||
|
from .endpoints.file_comment import FileCommentView
|
||||||
|
from .endpoints.file_comments import FileCommentsView
|
||||||
|
from .endpoints.file_comments_counts import FileCommentsCounts
|
||||||
from .endpoints.search_user import SearchUser
|
from .endpoints.search_user import SearchUser
|
||||||
from .endpoints.group_discussions import GroupDiscussions
|
from .endpoints.group_discussions import GroupDiscussions
|
||||||
from .endpoints.group_discussion import GroupDiscussion
|
from .endpoints.group_discussion import GroupDiscussion
|
||||||
@@ -49,6 +52,9 @@ urlpatterns = patterns('',
|
|||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/owa-file/$', OwaFileView.as_view(), name='api2-owa-file-view'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/owa-file/$', OwaFileView.as_view(), name='api2-owa-file-view'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/files/(?P<file_id>[0-9a-f]{40})/blks/(?P<block_id>[0-9a-f]{40})/download-link/$', FileBlockDownloadLinkView.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/files/(?P<file_id>[0-9a-f]{40})/blks/(?P<block_id>[0-9a-f]{40})/download-link/$', FileBlockDownloadLinkView.as_view()),
|
||||||
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/$', FileCommentsView.as_view(), name='api2-file-comments'),
|
||||||
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/counts/$', FileCommentsCounts.as_view(), name='api2-file-comments-counts'),
|
||||||
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<pk>\d+)/$', FileCommentView.as_view(), name='api2-file-comment'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/detail/$', FileDetailView.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/detail/$', FileDetailView.as_view()),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/history/$', FileHistory.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/history/$', FileHistory.as_view()),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revision/$', FileRevision.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revision/$', FileRevision.as_view()),
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
from django.db import models, IntegrityError
|
from django.db import models, IntegrityError
|
||||||
@@ -10,6 +12,7 @@ from seaserv import seafile_api
|
|||||||
from seahub.auth.signals import user_logged_in
|
from seahub.auth.signals import user_logged_in
|
||||||
from seahub.group.models import GroupMessage
|
from seahub.group.models import GroupMessage
|
||||||
from seahub.utils import calc_file_path_hash, within_time_range
|
from seahub.utils import calc_file_path_hash, within_time_range
|
||||||
|
from seahub.utils.timeutils import datetime_to_isoformat_timestr
|
||||||
from fields import LowerCaseCharField
|
from fields import LowerCaseCharField
|
||||||
|
|
||||||
|
|
||||||
@@ -28,11 +31,89 @@ class FileDiscuss(models.Model):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.path_hash:
|
if not self.path_hash:
|
||||||
|
|
||||||
self.path_hash = calc_file_path_hash(self.path)
|
self.path_hash = calc_file_path_hash(self.path)
|
||||||
|
|
||||||
super(FileDiscuss, self).save(*args, **kwargs)
|
super(FileDiscuss, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentManager(models.Manager):
|
||||||
|
def add(self, repo_id, parent_path, item_name, author, comment):
|
||||||
|
c = self.model(repo_id=repo_id, parent_path=parent_path,
|
||||||
|
item_name=item_name, author=author, comment=comment)
|
||||||
|
c.save(using=self._db)
|
||||||
|
return c
|
||||||
|
|
||||||
|
def add_by_file_path(self, repo_id, file_path, author, comment):
|
||||||
|
file_path = self.model.normalize_path(file_path)
|
||||||
|
parent_path = os.path.dirname(file_path)
|
||||||
|
item_name = os.path.basename(file_path)
|
||||||
|
|
||||||
|
return self.add(repo_id, parent_path, item_name, author, comment)
|
||||||
|
|
||||||
|
def get_by_file_path(self, repo_id, file_path):
|
||||||
|
parent_path = os.path.dirname(file_path)
|
||||||
|
item_name = os.path.basename(file_path)
|
||||||
|
repo_id_parent_path_md5 = self.model.md5_repo_id_parent_path(
|
||||||
|
repo_id, parent_path)
|
||||||
|
|
||||||
|
objs = super(FileCommentManager, self).filter(
|
||||||
|
repo_id_parent_path_md5=repo_id_parent_path_md5,
|
||||||
|
item_name=item_name)
|
||||||
|
|
||||||
|
return objs
|
||||||
|
|
||||||
|
def get_by_parent_path(self, repo_id, parent_path):
|
||||||
|
repo_id_parent_path_md5 = self.model.md5_repo_id_parent_path(
|
||||||
|
repo_id, parent_path)
|
||||||
|
|
||||||
|
objs = super(FileCommentManager, self).filter(
|
||||||
|
repo_id_parent_path_md5=repo_id_parent_path_md5)
|
||||||
|
return objs
|
||||||
|
|
||||||
|
|
||||||
|
class FileComment(models.Model):
|
||||||
|
"""
|
||||||
|
Model used to record file comments.
|
||||||
|
"""
|
||||||
|
repo_id = models.CharField(max_length=36, db_index=True)
|
||||||
|
parent_path = models.TextField()
|
||||||
|
repo_id_parent_path_md5 = models.CharField(max_length=100, db_index=True)
|
||||||
|
item_name = models.TextField()
|
||||||
|
author = LowerCaseCharField(max_length=255, db_index=True)
|
||||||
|
comment = models.TextField()
|
||||||
|
created_at = models.DateTimeField(default=timezone.now)
|
||||||
|
updated_at = models.DateTimeField(default=timezone.now)
|
||||||
|
objects = FileCommentManager()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def md5_repo_id_parent_path(cls, repo_id, parent_path):
|
||||||
|
return hashlib.md5(repo_id + parent_path.rstrip('/')).hexdigest()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def normalize_path(self, path):
|
||||||
|
return path.rstrip('/') if path != '/' else '/'
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
self.parent_path = self.normalize_path(self.parent_path)
|
||||||
|
if not self.repo_id_parent_path_md5:
|
||||||
|
self.repo_id_parent_path_md5 = self.md5_repo_id_parent_path(
|
||||||
|
self.repo_id, self.parent_path)
|
||||||
|
|
||||||
|
super(FileComment, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
o = self
|
||||||
|
return {
|
||||||
|
'id': o.pk,
|
||||||
|
'repo_id': o.repo_id,
|
||||||
|
'parent_path': o.parent_path,
|
||||||
|
'item_name': o.item_name,
|
||||||
|
'author': o.author,
|
||||||
|
'comment': o.comment,
|
||||||
|
'created_at': datetime_to_isoformat_timestr(o.created_at),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
########## starred files
|
########## starred files
|
||||||
class StarredFile(object):
|
class StarredFile(object):
|
||||||
def format_path(self):
|
def format_path(self):
|
||||||
@@ -206,7 +287,7 @@ class InnerPubMsgReply(models.Model):
|
|||||||
from_email = models.EmailField()
|
from_email = models.EmailField()
|
||||||
message = models.CharField(max_length=150)
|
message = models.CharField(max_length=150)
|
||||||
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
||||||
|
##############################
|
||||||
|
|
||||||
class DeviceToken(models.Model):
|
class DeviceToken(models.Model):
|
||||||
"""
|
"""
|
||||||
|
42
tests/api/endpoints/test_file_comment.py
Normal file
42
tests/api/endpoints/test_file_comment.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
class FileCommentTest(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
o = FileComment.objects.add_by_file_path(repo_id=self.repo.id,
|
||||||
|
file_path=self.file,
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment')
|
||||||
|
self.endpoint = reverse('api2-file-comment', args=[self.repo.id, o.pk]) + '?p=' + self.file
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.remove_repo()
|
||||||
|
|
||||||
|
def test_can_get(self):
|
||||||
|
resp = self.client.get(self.endpoint)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert json_resp['parent_path'] == '/'
|
||||||
|
assert json_resp['item_name'] == 'test.txt'
|
||||||
|
|
||||||
|
def test_can_delete(self):
|
||||||
|
assert len(FileComment.objects.all()) == 1
|
||||||
|
resp = self.client.delete(self.endpoint)
|
||||||
|
self.assertEqual(204, resp.status_code)
|
||||||
|
assert len(FileComment.objects.all()) == 0
|
||||||
|
|
||||||
|
def test_invalid_user_can_not_delete(self):
|
||||||
|
self.logout()
|
||||||
|
self.login_as(self.admin)
|
||||||
|
|
||||||
|
assert len(FileComment.objects.all()) == 1
|
||||||
|
resp = self.client.delete(self.endpoint)
|
||||||
|
self.assertEqual(403, resp.status_code)
|
||||||
|
assert len(FileComment.objects.all()) == 1
|
47
tests/api/endpoints/test_file_comments.py
Normal file
47
tests/api/endpoints/test_file_comments.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
class FileCommentsTest(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
self.endpoint = reverse('api2-file-comments', args=[self.repo.id]) + '?p=' + self.file
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.remove_repo()
|
||||||
|
|
||||||
|
def test_can_list(self):
|
||||||
|
o = FileComment.objects.add_by_file_path(repo_id=self.repo.id,
|
||||||
|
file_path=self.file,
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment')
|
||||||
|
resp = self.client.get(self.endpoint)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['comments']) == 1
|
||||||
|
assert json_resp['comments'][0]['comment'] == o.comment
|
||||||
|
|
||||||
|
def test_can_post(self):
|
||||||
|
resp = self.client.post(self.endpoint, {
|
||||||
|
'comment': 'new comment'
|
||||||
|
})
|
||||||
|
self.assertEqual(201, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert json_resp['comment'] == 'new comment'
|
||||||
|
|
||||||
|
def test_invalid_user(self):
|
||||||
|
self.logout()
|
||||||
|
self.login_as(self.admin)
|
||||||
|
|
||||||
|
resp = self.client.get(self.endpoint)
|
||||||
|
self.assertEqual(403, resp.status_code)
|
||||||
|
|
||||||
|
resp = self.client.post(self.endpoint, {
|
||||||
|
'comment': 'new comment'
|
||||||
|
})
|
||||||
|
self.assertEqual(403, resp.status_code)
|
46
tests/api/endpoints/test_file_comments_counts.py
Normal file
46
tests/api/endpoints/test_file_comments_counts.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from seahub.base.models import FileComment
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
class FileCommentsCountsTest(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
self.endpoint = reverse('api2-file-comments-counts', args=[self.repo.id]) + '?p=/'
|
||||||
|
|
||||||
|
self.file2 = self.create_file(repo_id=self.repo.id, parent_dir='/',
|
||||||
|
filename='test2.txt',
|
||||||
|
username=self.user.username)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.remove_repo()
|
||||||
|
|
||||||
|
def test_can_get(self):
|
||||||
|
FileComment.objects.add_by_file_path(repo_id=self.repo.id,
|
||||||
|
file_path=self.file,
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment')
|
||||||
|
|
||||||
|
FileComment.objects.add_by_file_path(repo_id=self.repo.id,
|
||||||
|
file_path=self.file,
|
||||||
|
author=self.user.username,
|
||||||
|
comment='reply test comment')
|
||||||
|
|
||||||
|
FileComment.objects.add_by_file_path(repo_id=self.repo.id,
|
||||||
|
file_path=self.file2,
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment on other file')
|
||||||
|
|
||||||
|
resp = self.client.get(self.endpoint)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp) == 2
|
||||||
|
for d in json_resp:
|
||||||
|
if d.keys()[0] == 'test.txt':
|
||||||
|
assert d['test.txt'] == 2
|
||||||
|
|
||||||
|
if d.keys()[0] == 'test2.txt':
|
||||||
|
assert d['test2.txt'] == 1
|
0
tests/seahub/base/__init__.py
Normal file
0
tests/seahub/base/__init__.py
Normal file
43
tests/seahub/base/test_models.py
Normal file
43
tests/seahub/base/test_models.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from seahub.base.models import FileComment
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentManagerTest(BaseTestCase):
|
||||||
|
def test_can_add(self):
|
||||||
|
assert len(FileComment.objects.all()) == 0
|
||||||
|
|
||||||
|
o = FileComment.objects.add(repo_id='xxx', parent_path='/foo/bar',
|
||||||
|
item_name='test.txt',
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment')
|
||||||
|
assert o.parent_path == '/foo/bar'
|
||||||
|
assert len(FileComment.objects.all()) == 1
|
||||||
|
|
||||||
|
def test_get_by_file_path(self):
|
||||||
|
o1 = FileComment.objects.add(repo_id='xxx', parent_path='/foo/bar/',
|
||||||
|
item_name='test.txt',
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment 1')
|
||||||
|
o2 = FileComment.objects.add(repo_id='xxx', parent_path='/foo/bar/',
|
||||||
|
item_name='test.txt',
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment 2')
|
||||||
|
assert len(FileComment.objects.get_by_file_path('xxx', '/foo/bar/test.txt')) == 2
|
||||||
|
|
||||||
|
|
||||||
|
class FileCommentTest(BaseTestCase):
|
||||||
|
def test_normalize_path(self):
|
||||||
|
o = FileComment.objects.add(repo_id='xxx', parent_path='/foo/bar/',
|
||||||
|
item_name='test.txt',
|
||||||
|
author=self.user.username,
|
||||||
|
comment='test comment')
|
||||||
|
assert o.parent_path == '/foo/bar'
|
||||||
|
|
||||||
|
def test_can_save(self):
|
||||||
|
assert len(FileComment.objects.all()) == 0
|
||||||
|
|
||||||
|
FileComment(repo_id='xxx', parent_path='/foo/bar/',
|
||||||
|
item_name='test.txt', author=self.user.username,
|
||||||
|
comment='test comment').save()
|
||||||
|
|
||||||
|
assert len(FileComment.objects.all()) == 1
|
0
tests/seahub/options/__init__.py
Normal file
0
tests/seahub/options/__init__.py
Normal file
Reference in New Issue
Block a user