##// END OF EJS Templates
comments: update comments email templates....
marcink -
r3120:646ada6a default
parent child Browse files
Show More
@@ -1,313 +1,314 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import pytest
22 22
23 23 from rhodecode.tests import TestController
24 24
25 25 from rhodecode.model.db import (
26 26 ChangesetComment, Notification, UserNotification)
27 27 from rhodecode.model.meta import Session
28 28 from rhodecode.lib import helpers as h
29 29
30 30
31 31 def route_path(name, params=None, **kwargs):
32 32 import urllib
33 33
34 34 base_url = {
35 35 'repo_commit': '/{repo_name}/changeset/{commit_id}',
36 36 'repo_commit_comment_create': '/{repo_name}/changeset/{commit_id}/comment/create',
37 37 'repo_commit_comment_preview': '/{repo_name}/changeset/{commit_id}/comment/preview',
38 38 'repo_commit_comment_delete': '/{repo_name}/changeset/{commit_id}/comment/{comment_id}/delete',
39 39 }[name].format(**kwargs)
40 40
41 41 if params:
42 42 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
43 43 return base_url
44 44
45 45
46 46 @pytest.mark.backends("git", "hg", "svn")
47 47 class TestRepoCommitCommentsView(TestController):
48 48
49 49 @pytest.fixture(autouse=True)
50 50 def prepare(self, request, baseapp):
51 51 for x in ChangesetComment.query().all():
52 52 Session().delete(x)
53 53 Session().commit()
54 54
55 55 for x in Notification.query().all():
56 56 Session().delete(x)
57 57 Session().commit()
58 58
59 59 request.addfinalizer(self.cleanup)
60 60
61 61 def cleanup(self):
62 62 for x in ChangesetComment.query().all():
63 63 Session().delete(x)
64 64 Session().commit()
65 65
66 66 for x in Notification.query().all():
67 67 Session().delete(x)
68 68 Session().commit()
69 69
70 70 @pytest.mark.parametrize('comment_type', ChangesetComment.COMMENT_TYPES)
71 71 def test_create(self, comment_type, backend):
72 72 self.log_user()
73 73 commit = backend.repo.get_commit('300')
74 74 commit_id = commit.raw_id
75 75 text = u'CommentOnCommit'
76 76
77 77 params = {'text': text, 'csrf_token': self.csrf_token,
78 78 'comment_type': comment_type}
79 79 self.app.post(
80 80 route_path('repo_commit_comment_create',
81 81 repo_name=backend.repo_name, commit_id=commit_id),
82 82 params=params)
83 83
84 84 response = self.app.get(
85 85 route_path('repo_commit',
86 86 repo_name=backend.repo_name, commit_id=commit_id))
87 87
88 88 # test DB
89 89 assert ChangesetComment.query().count() == 1
90 90 assert_comment_links(response, ChangesetComment.query().count(), 0)
91 91
92 92 assert Notification.query().count() == 1
93 93 assert ChangesetComment.query().count() == 1
94 94
95 95 notification = Notification.query().all()[0]
96 96
97 97 comment_id = ChangesetComment.query().first().comment_id
98 98 assert notification.type_ == Notification.TYPE_CHANGESET_COMMENT
99 99
100 sbj = 'left {0} on commit `{1}` in the {2} repository'.format(
101 comment_type, h.show_id(commit), backend.repo_name)
102 assert sbj in notification.subject
100 author = notification.created_by_user.username_and_name
101 sbj = '{0} left a {1} on commit `{2}` in the {3} repository'.format(
102 author, comment_type, h.show_id(commit), backend.repo_name)
103 assert sbj == notification.subject
103 104
104 105 lnk = (u'/{0}/changeset/{1}#comment-{2}'.format(
105 106 backend.repo_name, commit_id, comment_id))
106 107 assert lnk in notification.body
107 108
108 109 @pytest.mark.parametrize('comment_type', ChangesetComment.COMMENT_TYPES)
109 110 def test_create_inline(self, comment_type, backend):
110 111 self.log_user()
111 112 commit = backend.repo.get_commit('300')
112 113 commit_id = commit.raw_id
113 114 text = u'CommentOnCommit'
114 115 f_path = 'vcs/web/simplevcs/views/repository.py'
115 116 line = 'n1'
116 117
117 118 params = {'text': text, 'f_path': f_path, 'line': line,
118 119 'comment_type': comment_type,
119 120 'csrf_token': self.csrf_token}
120 121
121 122 self.app.post(
122 123 route_path('repo_commit_comment_create',
123 124 repo_name=backend.repo_name, commit_id=commit_id),
124 125 params=params)
125 126
126 127 response = self.app.get(
127 128 route_path('repo_commit',
128 129 repo_name=backend.repo_name, commit_id=commit_id))
129 130
130 131 # test DB
131 132 assert ChangesetComment.query().count() == 1
132 133 assert_comment_links(response, 0, ChangesetComment.query().count())
133 134
134 135 if backend.alias == 'svn':
135 136 response.mustcontain(
136 137 '''data-f-path="vcs/commands/summary.py" '''
137 138 '''id="a_c--ad05457a43f8"'''
138 139 )
139 140 else:
140 141 response.mustcontain(
141 142 '''data-f-path="vcs/backends/hg.py" '''
142 143 '''id="a_c--9c390eb52cd6"'''
143 144 )
144 145
145 146 assert Notification.query().count() == 1
146 147 assert ChangesetComment.query().count() == 1
147 148
148 149 notification = Notification.query().all()[0]
149 150 comment = ChangesetComment.query().first()
150 151 assert notification.type_ == Notification.TYPE_CHANGESET_COMMENT
151 152
152 153 assert comment.revision == commit_id
153 sbj = 'left {comment_type} on commit `{commit}` ' \
154 '(file: `{f_path}`) in the {repo} repository'.format(
155 commit=h.show_id(commit),
156 f_path=f_path, line=line, repo=backend.repo_name,
157 comment_type=comment_type)
158 assert sbj in notification.subject
154
155 author = notification.created_by_user.username_and_name
156 sbj = '{0} left a {1} on file `{2}` in commit `{3}` in the {4} repository'.format(
157 author, comment_type, f_path, h.show_id(commit), backend.repo_name)
158
159 assert sbj == notification.subject
159 160
160 161 lnk = (u'/{0}/changeset/{1}#comment-{2}'.format(
161 162 backend.repo_name, commit_id, comment.comment_id))
162 163 assert lnk in notification.body
163 164 assert 'on line n1' in notification.body
164 165
165 166 def test_create_with_mention(self, backend):
166 167 self.log_user()
167 168
168 169 commit_id = backend.repo.get_commit('300').raw_id
169 170 text = u'@test_regular check CommentOnCommit'
170 171
171 172 params = {'text': text, 'csrf_token': self.csrf_token}
172 173 self.app.post(
173 174 route_path('repo_commit_comment_create',
174 175 repo_name=backend.repo_name, commit_id=commit_id),
175 176 params=params)
176 177
177 178 response = self.app.get(
178 179 route_path('repo_commit',
179 180 repo_name=backend.repo_name, commit_id=commit_id))
180 181 # test DB
181 182 assert ChangesetComment.query().count() == 1
182 183 assert_comment_links(response, ChangesetComment.query().count(), 0)
183 184
184 185 notification = Notification.query().one()
185 186
186 187 assert len(notification.recipients) == 2
187 188 users = [x.username for x in notification.recipients]
188 189
189 190 # test_regular gets notification by @mention
190 191 assert sorted(users) == [u'test_admin', u'test_regular']
191 192
192 193 def test_create_with_status_change(self, backend):
193 194 self.log_user()
194 195 commit = backend.repo.get_commit('300')
195 196 commit_id = commit.raw_id
196 197 text = u'CommentOnCommit'
197 198 f_path = 'vcs/web/simplevcs/views/repository.py'
198 199 line = 'n1'
199 200
200 201 params = {'text': text, 'changeset_status': 'approved',
201 202 'csrf_token': self.csrf_token}
202 203
203 204 self.app.post(
204 205 route_path(
205 206 'repo_commit_comment_create',
206 207 repo_name=backend.repo_name, commit_id=commit_id),
207 208 params=params)
208 209
209 210 response = self.app.get(
210 211 route_path('repo_commit',
211 212 repo_name=backend.repo_name, commit_id=commit_id))
212 213
213 214 # test DB
214 215 assert ChangesetComment.query().count() == 1
215 216 assert_comment_links(response, ChangesetComment.query().count(), 0)
216 217
217 218 assert Notification.query().count() == 1
218 219 assert ChangesetComment.query().count() == 1
219 220
220 221 notification = Notification.query().all()[0]
221 222
222 223 comment_id = ChangesetComment.query().first().comment_id
223 224 assert notification.type_ == Notification.TYPE_CHANGESET_COMMENT
224 225
225 sbj = 'left note on commit `{0}` (status: Approved) ' \
226 'in the {1} repository'.format(
227 h.show_id(commit), backend.repo_name)
228 assert sbj in notification.subject
226 author = notification.created_by_user.username_and_name
227 sbj = '[status: Approved] {0} left a note on commit `{1}` in the {2} repository'.format(
228 author, h.show_id(commit), backend.repo_name)
229 assert sbj == notification.subject
229 230
230 231 lnk = (u'/{0}/changeset/{1}#comment-{2}'.format(
231 232 backend.repo_name, commit_id, comment_id))
232 233 assert lnk in notification.body
233 234
234 235 def test_delete(self, backend):
235 236 self.log_user()
236 237 commit_id = backend.repo.get_commit('300').raw_id
237 238 text = u'CommentOnCommit'
238 239
239 240 params = {'text': text, 'csrf_token': self.csrf_token}
240 241 self.app.post(
241 242 route_path(
242 243 'repo_commit_comment_create',
243 244 repo_name=backend.repo_name, commit_id=commit_id),
244 245 params=params)
245 246
246 247 comments = ChangesetComment.query().all()
247 248 assert len(comments) == 1
248 249 comment_id = comments[0].comment_id
249 250
250 251 self.app.post(
251 252 route_path('repo_commit_comment_delete',
252 253 repo_name=backend.repo_name,
253 254 commit_id=commit_id,
254 255 comment_id=comment_id),
255 256 params={'csrf_token': self.csrf_token})
256 257
257 258 comments = ChangesetComment.query().all()
258 259 assert len(comments) == 0
259 260
260 261 response = self.app.get(
261 262 route_path('repo_commit',
262 263 repo_name=backend.repo_name, commit_id=commit_id))
263 264 assert_comment_links(response, 0, 0)
264 265
265 266 @pytest.mark.parametrize('renderer, input, output', [
266 267 ('rst', 'plain text', '<p>plain text</p>'),
267 268 ('rst', 'header\n======', '<h1 class="title">header</h1>'),
268 269 ('rst', '*italics*', '<em>italics</em>'),
269 270 ('rst', '**bold**', '<strong>bold</strong>'),
270 271 ('markdown', 'plain text', '<p>plain text</p>'),
271 272 ('markdown', '# header', '<h1>header</h1>'),
272 273 ('markdown', '*italics*', '<em>italics</em>'),
273 274 ('markdown', '**bold**', '<strong>bold</strong>'),
274 275 ], ids=['rst-plain', 'rst-header', 'rst-italics', 'rst-bold', 'md-plain',
275 276 'md-header', 'md-italics', 'md-bold', ])
276 277 def test_preview(self, renderer, input, output, backend, xhr_header):
277 278 self.log_user()
278 279 params = {
279 280 'renderer': renderer,
280 281 'text': input,
281 282 'csrf_token': self.csrf_token
282 283 }
283 284 commit_id = '0' * 16 # fake this for tests
284 285 response = self.app.post(
285 286 route_path('repo_commit_comment_preview',
286 repo_name=backend.repo_name, commit_id=commit_id,),
287 repo_name=backend.repo_name, commit_id=commit_id,),
287 288 params=params,
288 289 extra_environ=xhr_header)
289 290
290 291 response.mustcontain(output)
291 292
292 293
293 294 def assert_comment_links(response, comments, inline_comments):
294 295 if comments == 1:
295 296 comments_text = "%d Commit comment" % comments
296 297 else:
297 298 comments_text = "%d Commit comments" % comments
298 299
299 300 if inline_comments == 1:
300 301 inline_comments_text = "%d Inline Comment" % inline_comments
301 302 else:
302 303 inline_comments_text = "%d Inline Comments" % inline_comments
303 304
304 305 if comments:
305 306 response.mustcontain('<a href="#comments">%s</a>,' % comments_text)
306 307 else:
307 308 response.mustcontain(comments_text)
308 309
309 310 if inline_comments:
310 311 response.mustcontain(
311 312 'id="inline-comments-counter">%s</' % inline_comments_text)
312 313 else:
313 314 response.mustcontain(inline_comments_text)
@@ -1,105 +1,108 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="base.mako"/>
3 3 <%namespace name="base" file="base.mako"/>
4 4
5 5 ## EMAIL SUBJECT
6 6 <%def name="subject()" filter="n,trim,whitespace_filter">
7 7 <%
8 8 data = {
9 9 'user': h.person(user),
10 10 'repo_name': repo_name,
11 11 'commit_id': h.show_id(commit),
12 12 'status': status_change,
13 13 'comment_file': comment_file,
14 14 'comment_line': comment_line,
15 15 'comment_type': comment_type,
16 16 }
17 17 %>
18 18 ${_('[mention]') if mention else ''} \
19 19
20 20 % if comment_file:
21 ${_('%(user)s left %(comment_type)s on commit `%(commit_id)s` (file: `%(comment_file)s`)') % data} ${_('in the %(repo_name)s repository') % data |n}
21 ${_('{user} left a {comment_type} on file `{comment_file}` in commit `{commit_id}`').format(**data)} ${_('in the {repo_name} repository').format(**data) |n}
22 22 % else:
23 23 % if status_change:
24 ${_('%(user)s left %(comment_type)s on commit `%(commit_id)s` (status: %(status)s)') % data |n} ${_('in the %(repo_name)s repository') % data |n}
24 ${_('[status: {status}] {user} left a {comment_type} on commit `{commit_id}`').format(**data) |n} ${_('in the {repo_name} repository').format(**data) |n}
25 25 % else:
26 ${_('%(user)s left %(comment_type)s on commit `%(commit_id)s`') % data |n} ${_('in the %(repo_name)s repository') % data |n}
26 ${_('{user} left a {comment_type} on commit `{commit_id}`').format(**data) |n} ${_('in the {repo_name} repository').format(**data) |n}
27 27 % endif
28 28 % endif
29 29
30 30 </%def>
31 31
32 32 ## PLAINTEXT VERSION OF BODY
33 33 <%def name="body_plaintext()" filter="n,trim">
34 34 <%
35 35 data = {
36 36 'user': h.person(user),
37 37 'repo_name': repo_name,
38 38 'commit_id': h.show_id(commit),
39 39 'status': status_change,
40 40 'comment_file': comment_file,
41 41 'comment_line': comment_line,
42 42 'comment_type': comment_type,
43 43 }
44 44 %>
45 45 ${self.subject()}
46 46
47 47 * ${_('Comment link')}: ${commit_comment_url}
48 48
49 49 * ${_('Commit')}: ${h.show_id(commit)}
50 50
51 51 %if comment_file:
52 * ${_('File: %(comment_file)s on line %(comment_line)s') % data}
52 * ${_('File: {comment_file} on line {comment_line}').format(**data)}
53 53 %endif
54 54
55 55 ---
56 56
57 57 %if status_change:
58 58 ${_('Commit status was changed to')}: *${status_change}*
59 59 %endif
60 60
61 61 ${comment_body|n}
62 62
63 63 ${self.plaintext_footer()}
64 64 </%def>
65 65
66 66
67 67 <%
68 68 data = {
69 69 'user': h.person(user),
70 70 'repo': commit_target_repo,
71 71 'repo_name': repo_name,
72 72 'commit_id': h.show_id(commit),
73 73 'comment_file': comment_file,
74 74 'comment_line': comment_line,
75 75 'comment_type': comment_type,
76 76 }
77 77 %>
78 78 <table style="text-align:left;vertical-align:middle;">
79 79 <tr><td colspan="2" style="width:100%;padding-bottom:15px;border-bottom:1px solid #dbd9da;">
80 80
81 81 % if comment_file:
82 <h4><a href="${commit_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('%(user)s commented on commit `%(commit_id)s` (file:`%(comment_file)s`)') % data}</a> ${_('in the %(repo)s repository') % data |n}</h4>
82 <h4><a href="${commit_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('{user} left a {comment_type} on file `{comment_file}` in commit `{commit_id}`').format(**data)}</a> ${_('in the {repo} repository').format(**data) |n}</h4>
83 83 % else:
84 <h4><a href="${commit_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('%(user)s commented on commit `%(commit_id)s`') % data |n}</a> ${_('in the %(repo)s repository') % data |n}</h4>
84 <h4><a href="${commit_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('{user} left a {comment_type} on commit `{commit_id}`').format(**data) |n}</a> ${_('in the {repo} repository').format(**data) |n}</h4>
85 85 % endif
86 86 </td></tr>
87 87
88 88 <tr><td style="padding-right:20px;padding-top:15px;">${_('Commit')}</td><td style="padding-top:15px;"><a href="${commit_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${h.show_id(commit)}</a></td></tr>
89 89 <tr><td style="padding-right:20px;">${_('Description')}</td><td style="white-space:pre-wrap">${h.urlify_commit_message(commit.message, repo_name)}</td></tr>
90 90
91 91 % if status_change:
92 <tr><td style="padding-right:20px;">${_('Status')}</td>
93 <td>${_('The commit status was changed to')}: ${base.status_text(status_change, tag_type=status_change_type)}</td>
92 <tr>
93 <td style="padding-right:20px;">${_('Status')}</td>
94 <td>
95 ${_('The commit status was changed to')}: ${base.status_text(status_change, tag_type=status_change_type)}
96 </td>
94 97 </tr>
95 98 % endif
96 99 <tr>
97 100 <td style="padding-right:20px;">
98 101 % if comment_type == 'todo':
99 ${(_('TODO comment on line: %(comment_line)s') if comment_file else _('TODO comment')) % data}
102 ${(_('TODO comment on line: {comment_line}') if comment_file else _('TODO comment')).format(**data)}
100 103 % else:
101 ${(_('Note comment on line: %(comment_line)s') if comment_file else _('Note comment')) % data}
104 ${(_('Note comment on line: {comment_line}') if comment_file else _('Note comment')).format(**data)}
102 105 % endif
103 106 </td>
104 107 <td style="line-height:1.2em;white-space:pre-wrap">${h.render(comment_body, renderer=renderer_type, mentions=True)}</td></tr>
105 108 </table>
@@ -1,114 +1,114 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="base.mako"/>
3 3 <%namespace name="base" file="base.mako"/>
4 4
5 5 ## EMAIL SUBJECT
6 6 <%def name="subject()" filter="n,trim,whitespace_filter">
7 7 <%
8 8 data = {
9 9 'user': h.person(user),
10 10 'pr_title': pull_request.title,
11 11 'pr_id': pull_request.pull_request_id,
12 12 'status': status_change,
13 13 'comment_file': comment_file,
14 14 'comment_line': comment_line,
15 15 'comment_type': comment_type,
16 16 }
17 17 %>
18 18
19 ${_('[mention]') if mention else ''} \
19 ${(_('[mention]') if mention else '')} \
20 20
21 21 % if comment_file:
22 ${_('%(user)s left %(comment_type)s on pull request #%(pr_id)s "%(pr_title)s" (file: `%(comment_file)s`)') % data |n}
22 ${_('{user} left a {comment_type} on file `{comment_file}` in pull request #{pr_id} "{pr_title}"').format(**data) |n}
23 23 % else:
24 24 % if status_change:
25 ${_('%(user)s left %(comment_type)s on pull request #%(pr_id)s "%(pr_title)s" (status: %(status)s)') % data |n}
25 ${_('[status: {status}] {user} left a {comment_type} on pull request #{pr_id} "{pr_title}"').format(**data) |n}
26 26 % else:
27 ${_('%(user)s left %(comment_type)s on pull request #%(pr_id)s "%(pr_title)s"') % data |n}
27 ${_('{user} left a {comment_type} on pull request #{pr_id} "{pr_title}"').format(**data) |n}
28 28 % endif
29 29 % endif
30 30 </%def>
31 31
32 32 ## PLAINTEXT VERSION OF BODY
33 33 <%def name="body_plaintext()" filter="n,trim">
34 34 <%
35 35 data = {
36 36 'user': h.person(user),
37 37 'pr_title': pull_request.title,
38 38 'pr_id': pull_request.pull_request_id,
39 39 'status': status_change,
40 40 'comment_file': comment_file,
41 41 'comment_line': comment_line,
42 42 'comment_type': comment_type,
43 43 }
44 44 %>
45 45 ${self.subject()}
46 46
47 47 * ${_('Comment link')}: ${pr_comment_url}
48 48
49 49 * ${_('Source repository')}: ${pr_source_repo_url}
50 50
51 51 %if comment_file:
52 * ${_('File: %(comment_file)s on line %(comment_line)s') % {'comment_file': comment_file, 'comment_line': comment_line}}
52 * ${_('File: {comment_file} on line {comment_line}').format(comment_file=comment_file, comment_line=comment_line)}
53 53 %endif
54 54
55 55 ---
56 56
57 57 %if status_change and not closing_pr:
58 ${_('%(user)s submitted pull request #%(pr_id)s status: *%(status)s*') % data}
58 ${_('{user} submitted pull request #{pr_id} status: *{status}*').format(**data)}
59 59 %elif status_change and closing_pr:
60 ${_('%(user)s submitted pull request #%(pr_id)s status: *%(status)s and closed*') % data}
60 ${_('{user} submitted pull request #{pr_id} status: *{status} and closed*').format(**data)}
61 61 %endif
62 62
63 ${comment_body|n}
63 ${comment_body |n}
64 64
65 65 ${self.plaintext_footer()}
66 66 </%def>
67 67
68 68
69 69 <%
70 70 data = {
71 71 'user': h.person(user),
72 72 'pr_title': pull_request.title,
73 73 'pr_id': pull_request.pull_request_id,
74 74 'status': status_change,
75 75 'comment_file': comment_file,
76 76 'comment_line': comment_line,
77 77 'comment_type': comment_type,
78 78 }
79 79 %>
80 80 <table style="text-align:left;vertical-align:middle;">
81 81 <tr><td colspan="2" style="width:100%;padding-bottom:15px;border-bottom:1px solid #dbd9da;">
82 82
83 83 % if comment_file:
84 <h4><a href="${pr_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('%(user)s commented on pull request #%(pr_id)s "%(pr_title)s" (file:`%(comment_file)s`)') % data |n}</a></h4>
84 <h4><a href="${pr_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('{user} left a {comment_type} on file `{comment_file}` in pull request #{pr_id} "{pr_title}"').format(**data) |n}</a></h4>
85 85 % else:
86 <h4><a href="${pr_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('%(user)s commented on pull request #%(pr_id)s "%(pr_title)s"') % data |n}</a></h4>
86 <h4><a href="${pr_comment_url}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('{user} left a {comment_type} on pull request #{pr_id} "{pr_title}"').format(**data) |n}</a></h4>
87 87 % endif
88 88
89 89 </td></tr>
90 90 <tr><td style="padding-right:20px;padding-top:15px;">${_('Source')}</td><td style="padding-top:15px;"><a style="color:#427cc9;text-decoration:none;cursor:pointer" href="${pr_source_repo_url}">${pr_source_repo.repo_name}</a></td></tr>
91 91
92 92 % if status_change:
93 93 <tr>
94 94 <td style="padding-right:20px;">${_('Status')}</td>
95 95 <td>
96 96 % if closing_pr:
97 97 ${_('Closed pull request with status')}: ${base.status_text(status_change, tag_type=status_change_type)}
98 98 % else:
99 99 ${_('Submitted review status')}: ${base.status_text(status_change, tag_type=status_change_type)}
100 100 % endif
101 101 </td>
102 102 </tr>
103 103 % endif
104 104 <tr>
105 105 <td style="padding-right:20px;">
106 106 % if comment_type == 'todo':
107 ${(_('TODO comment on line: %(comment_line)s') if comment_file else _('TODO comment')) % data}
107 ${(_('TODO comment on line: {comment_line}') if comment_file else _('TODO comment')).format(**data)}
108 108 % else:
109 ${(_('Note comment on line: %(comment_line)s') if comment_file else _('Note comment')) % data}
109 ${(_('Note comment on line: {comment_line}') if comment_file else _('Note comment')).format(**data)}
110 110 % endif
111 111 </td>
112 112 <td style="line-height:1.2em;white-space:pre-wrap">${h.render(comment_body, renderer=renderer_type, mentions=True)}</td>
113 113 </tr>
114 114 </table>
General Comments 0
You need to be logged in to leave comments. Login now