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, |
|
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, |
|
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