[PATCH 2 of 2] model: comments: allow selective retrieval of inline comments
Thomas De Schampheleire
patrickdepinguin at gmail.com
Thu Dec 27 11:25:39 UTC 2018
# HG changeset patch
# User Thomas De Schampheleire <thomas.de_schampheleire at nokia.com>
# Date 1545856772 -3600
# Wed Dec 26 21:39:32 2018 +0100
# Node ID 58164beda5bf9d4b87ac54f1f265c2c81d0cf125
# Parent 1235dd8c18cb1f3fe525a7997effe23acba6de94
model: comments: allow selective retrieval of inline comments
Allow retrieving inline comments of only a specified file and possibly line
number, by filtering at database level.
This will be useful when adding more code context in comment notification
emails.
diff --git a/kallithea/model/comment.py b/kallithea/model/comment.py
--- a/kallithea/model/comment.py
+++ b/kallithea/model/comment.py
@@ -244,30 +244,51 @@ class ChangesetCommentsModel(object):
return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
inline=False)
- def get_inline_comments(self, repo_id, revision=None, pull_request=None):
+ def get_inline_comments(self, repo_id, revision=None, pull_request=None,
+ f_path=None, line_no=None):
"""
Gets inline comments for either revision or pull_request.
Returns a list of tuples with file path and list of comments per line number.
"""
comments = self._get_comments(repo_id, revision=revision, pull_request=pull_request,
- inline=True)
+ inline=True, f_path=f_path, line_no=line_no)
paths = defaultdict(lambda: defaultdict(list))
for co in comments:
paths[co.f_path][co.line_no].append(co)
return paths.items()
- def _get_comments(self, repo_id, revision=None, pull_request=None, inline=False):
+ def _get_comments(self, repo_id, revision=None, pull_request=None,
+ inline=False, f_path=None, line_no=None):
"""
Gets comments for either revision or pull_request_id, either inline or general.
+ If a file path and optionally line number are given, return only the matching inline comments.
"""
+ if f_path is None and line_no is not None:
+ raise Exception("line_no only makes sense if f_path is given.")
+
+ if inline is None and f_path is not None:
+ raise Exception("f_path only makes sense for inline comments.")
+
q = Session().query(ChangesetComment)
if inline:
- q = q.filter(ChangesetComment.line_no != None) \
- .filter(ChangesetComment.f_path != None)
+ if f_path is not None:
+ # inline comments for a given file...
+ q = q.filter(ChangesetComment.f_path == f_path)
+ if line_no is None:
+ # ... on any line
+ q = q.filter(ChangesetComment.line_no != None)
+ else:
+ # ... on specific line
+ q = q.filter(ChangesetComment.line_no == line_no)
+ else:
+ # all inline comments
+ q = q.filter(ChangesetComment.line_no != None) \
+ .filter(ChangesetComment.f_path != None)
else:
+ # all general comments
q = q.filter(ChangesetComment.line_no == None) \
.filter(ChangesetComment.f_path == None)
diff --git a/kallithea/tests/models/test_comments.py b/kallithea/tests/models/test_comments.py
--- a/kallithea/tests/models/test_comments.py
+++ b/kallithea/tests/models/test_comments.py
@@ -2,16 +2,20 @@ from kallithea.tests.base import *
from kallithea.model.comment import ChangesetCommentsModel
from kallithea.model.db import Repository
+import pytest
from tg.util.webtest import test_context
class TestComments(TestController):
- def _check_comment_count(self, repo_id, revision, expected_len_comments, expected_len_inline_comments):
+ def _check_comment_count(self, repo_id, revision,
+ expected_len_comments, expected_len_inline_comments,
+ f_path=None, line_no=None
+ ):
comments = ChangesetCommentsModel().get_comments(repo_id,
revision=revision)
assert len(comments) == expected_len_comments
inline_comments = ChangesetCommentsModel().get_inline_comments(repo_id,
- revision=revision)
+ revision=revision, f_path=f_path, line_no=line_no)
assert len(inline_comments) == expected_len_inline_comments
return comments, inline_comments
@@ -153,3 +157,74 @@ class TestComments(TestController):
self._check_comment_count(repo_id, revision,
expected_len_comments=0, expected_len_inline_comments=0)
+
+ def test_selective_retrieval_of_inline_comments(self):
+ with test_context(self.app):
+ repo_id = Repository.get_by_repo_name(HG_REPO).repo_id
+ revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
+
+ self._check_comment_count(repo_id, revision,
+ expected_len_comments=0, expected_len_inline_comments=0)
+
+ text = u'an inline comment'
+ f_path = u'vcs/tests/base.py'
+ line_no = u'n50'
+ new_comment = ChangesetCommentsModel().create(
+ text=text,
+ repo=HG_REPO,
+ author=TEST_USER_REGULAR_LOGIN,
+ revision=revision,
+ f_path=f_path,
+ line_no=line_no,
+ send_email=False)
+
+ text2 = u'another inline comment, same file'
+ line_no2 = u'o41'
+ new_comment2 = ChangesetCommentsModel().create(
+ text=text2,
+ repo=HG_REPO,
+ author=TEST_USER_REGULAR_LOGIN,
+ revision=revision,
+ f_path=f_path,
+ line_no=line_no2,
+ send_email=False)
+
+ text3 = u'another inline comment, same file'
+ f_path3 = u'vcs/tests/test_hg.py'
+ line_no3 = u'n159'
+ new_comment3 = ChangesetCommentsModel().create(
+ text=text3,
+ repo=HG_REPO,
+ author=TEST_USER_REGULAR_LOGIN,
+ revision=revision,
+ f_path=f_path3,
+ line_no=line_no3,
+ send_email=False)
+
+ # now selectively retrieve comments of one file
+ comments, inline_comments = self._check_comment_count(repo_id, revision,
+ f_path=f_path,
+ expected_len_comments=0, expected_len_inline_comments=1)
+ # inline_comments is a list of tuples (file_path, dict)
+ # where the dict keys are line numbers and values are lists of comments
+ assert inline_comments[0][0] == f_path
+ assert len(inline_comments[0][1]) == 2
+ assert inline_comments[0][1][line_no][0].text == text
+ assert inline_comments[0][1][line_no2][0].text == text2
+
+ # now selectively retrieve comments of one file, one line
+ comments, inline_comments = self._check_comment_count(repo_id, revision,
+ f_path=f_path, line_no=line_no2,
+ expected_len_comments=0, expected_len_inline_comments=1)
+ # inline_comments is a list of tuples (file_path, dict)
+ # where the dict keys are line numbers and values are lists of comments
+ assert inline_comments[0][0] == f_path
+ assert len(inline_comments[0][1]) == 1
+ assert inline_comments[0][1][line_no2][0].text == text2
+
+ # verify that retrieval based on line_no but no f_path fails
+ with pytest.raises(Exception) as excinfo:
+ self._check_comment_count(repo_id, revision,
+ f_path=None, line_no=line_no2,
+ expected_len_comments=0, expected_len_inline_comments=0)
+ assert 'line_no only makes sense if f_path is given' in str(excinfo.value)
More information about the kallithea-general
mailing list