##// END OF EJS Templates
model: comments: allow selective retrieval of inline comments...
Thomas De Schampheleire -
r7409:445d6875 default
parent child Browse files
Show More
@@ -244,30 +244,51 b' class ChangesetCommentsModel(object):'
244 return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
244 return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
245 inline=False)
245 inline=False)
246
246
247 def get_inline_comments(self, repo_id, revision=None, pull_request=None):
247 def get_inline_comments(self, repo_id, revision=None, pull_request=None,
248 f_path=None, line_no=None):
248 """
249 """
249 Gets inline comments for either revision or pull_request.
250 Gets inline comments for either revision or pull_request.
250
251
251 Returns a list of tuples with file path and list of comments per line number.
252 Returns a list of tuples with file path and list of comments per line number.
252 """
253 """
253 comments = self._get_comments(repo_id, revision=revision, pull_request=pull_request,
254 comments = self._get_comments(repo_id, revision=revision, pull_request=pull_request,
254 inline=True)
255 inline=True, f_path=f_path, line_no=line_no)
255
256
256 paths = defaultdict(lambda: defaultdict(list))
257 paths = defaultdict(lambda: defaultdict(list))
257 for co in comments:
258 for co in comments:
258 paths[co.f_path][co.line_no].append(co)
259 paths[co.f_path][co.line_no].append(co)
259 return paths.items()
260 return paths.items()
260
261
261 def _get_comments(self, repo_id, revision=None, pull_request=None, inline=False):
262 def _get_comments(self, repo_id, revision=None, pull_request=None,
263 inline=False, f_path=None, line_no=None):
262 """
264 """
263 Gets comments for either revision or pull_request_id, either inline or general.
265 Gets comments for either revision or pull_request_id, either inline or general.
266 If a file path and optionally line number are given, return only the matching inline comments.
264 """
267 """
268 if f_path is None and line_no is not None:
269 raise Exception("line_no only makes sense if f_path is given.")
270
271 if inline is None and f_path is not None:
272 raise Exception("f_path only makes sense for inline comments.")
273
265 q = Session().query(ChangesetComment)
274 q = Session().query(ChangesetComment)
266
275
267 if inline:
276 if inline:
268 q = q.filter(ChangesetComment.line_no != None) \
277 if f_path is not None:
269 .filter(ChangesetComment.f_path != None)
278 # inline comments for a given file...
279 q = q.filter(ChangesetComment.f_path == f_path)
280 if line_no is None:
281 # ... on any line
282 q = q.filter(ChangesetComment.line_no != None)
283 else:
284 # ... on specific line
285 q = q.filter(ChangesetComment.line_no == line_no)
286 else:
287 # all inline comments
288 q = q.filter(ChangesetComment.line_no != None) \
289 .filter(ChangesetComment.f_path != None)
270 else:
290 else:
291 # all general comments
271 q = q.filter(ChangesetComment.line_no == None) \
292 q = q.filter(ChangesetComment.line_no == None) \
272 .filter(ChangesetComment.f_path == None)
293 .filter(ChangesetComment.f_path == None)
273
294
@@ -2,16 +2,20 b' from kallithea.tests.base import *'
2 from kallithea.model.comment import ChangesetCommentsModel
2 from kallithea.model.comment import ChangesetCommentsModel
3 from kallithea.model.db import Repository
3 from kallithea.model.db import Repository
4
4
5 import pytest
5 from tg.util.webtest import test_context
6 from tg.util.webtest import test_context
6
7
7 class TestComments(TestController):
8 class TestComments(TestController):
8
9
9 def _check_comment_count(self, repo_id, revision, expected_len_comments, expected_len_inline_comments):
10 def _check_comment_count(self, repo_id, revision,
11 expected_len_comments, expected_len_inline_comments,
12 f_path=None, line_no=None
13 ):
10 comments = ChangesetCommentsModel().get_comments(repo_id,
14 comments = ChangesetCommentsModel().get_comments(repo_id,
11 revision=revision)
15 revision=revision)
12 assert len(comments) == expected_len_comments
16 assert len(comments) == expected_len_comments
13 inline_comments = ChangesetCommentsModel().get_inline_comments(repo_id,
17 inline_comments = ChangesetCommentsModel().get_inline_comments(repo_id,
14 revision=revision)
18 revision=revision, f_path=f_path, line_no=line_no)
15 assert len(inline_comments) == expected_len_inline_comments
19 assert len(inline_comments) == expected_len_inline_comments
16
20
17 return comments, inline_comments
21 return comments, inline_comments
@@ -153,3 +157,74 b' class TestComments(TestController):'
153
157
154 self._check_comment_count(repo_id, revision,
158 self._check_comment_count(repo_id, revision,
155 expected_len_comments=0, expected_len_inline_comments=0)
159 expected_len_comments=0, expected_len_inline_comments=0)
160
161 def test_selective_retrieval_of_inline_comments(self):
162 with test_context(self.app):
163 repo_id = Repository.get_by_repo_name(HG_REPO).repo_id
164 revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
165
166 self._check_comment_count(repo_id, revision,
167 expected_len_comments=0, expected_len_inline_comments=0)
168
169 text = u'an inline comment'
170 f_path = u'vcs/tests/base.py'
171 line_no = u'n50'
172 new_comment = ChangesetCommentsModel().create(
173 text=text,
174 repo=HG_REPO,
175 author=TEST_USER_REGULAR_LOGIN,
176 revision=revision,
177 f_path=f_path,
178 line_no=line_no,
179 send_email=False)
180
181 text2 = u'another inline comment, same file'
182 line_no2 = u'o41'
183 new_comment2 = ChangesetCommentsModel().create(
184 text=text2,
185 repo=HG_REPO,
186 author=TEST_USER_REGULAR_LOGIN,
187 revision=revision,
188 f_path=f_path,
189 line_no=line_no2,
190 send_email=False)
191
192 text3 = u'another inline comment, same file'
193 f_path3 = u'vcs/tests/test_hg.py'
194 line_no3 = u'n159'
195 new_comment3 = ChangesetCommentsModel().create(
196 text=text3,
197 repo=HG_REPO,
198 author=TEST_USER_REGULAR_LOGIN,
199 revision=revision,
200 f_path=f_path3,
201 line_no=line_no3,
202 send_email=False)
203
204 # now selectively retrieve comments of one file
205 comments, inline_comments = self._check_comment_count(repo_id, revision,
206 f_path=f_path,
207 expected_len_comments=0, expected_len_inline_comments=1)
208 # inline_comments is a list of tuples (file_path, dict)
209 # where the dict keys are line numbers and values are lists of comments
210 assert inline_comments[0][0] == f_path
211 assert len(inline_comments[0][1]) == 2
212 assert inline_comments[0][1][line_no][0].text == text
213 assert inline_comments[0][1][line_no2][0].text == text2
214
215 # now selectively retrieve comments of one file, one line
216 comments, inline_comments = self._check_comment_count(repo_id, revision,
217 f_path=f_path, line_no=line_no2,
218 expected_len_comments=0, expected_len_inline_comments=1)
219 # inline_comments is a list of tuples (file_path, dict)
220 # where the dict keys are line numbers and values are lists of comments
221 assert inline_comments[0][0] == f_path
222 assert len(inline_comments[0][1]) == 1
223 assert inline_comments[0][1][line_no2][0].text == text2
224
225 # verify that retrieval based on line_no but no f_path fails
226 with pytest.raises(Exception) as excinfo:
227 self._check_comment_count(repo_id, revision,
228 f_path=None, line_no=line_no2,
229 expected_len_comments=0, expected_len_inline_comments=0)
230 assert 'line_no only makes sense if f_path is given' in str(excinfo.value)
General Comments 0
You need to be logged in to leave comments. Login now