Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: appengine/monorail/features/test/autolink_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Unittest for the autolink feature."""
7
8 import re
9 import unittest
10
11 from features import autolink
12 from framework import template_helpers
13 from proto import tracker_pb2
14 from testing import fake
15 from testing import testing_helpers
16
17
18 SIMPLE_EMAIL_RE = re.compile(r'([a-z]+)@([a-z]+)\.com')
19 OVER_AMBITIOUS_DOMAIN_RE = re.compile(r'([a-z]+)\.(com|net|org)')
20
21
22 class AutolinkTest(unittest.TestCase):
23
24 def RegisterEmailCallbacks(self, aa):
25
26 def LookupUsers(_mr, all_addresses):
27 """Return user objects for only users who are at trusted domains."""
28 return [addr for addr in all_addresses
29 if addr.endswith('@example.com')]
30
31 def Match2Addresses(_mr, match):
32 return [match.group(0)]
33
34 def MakeMailtoLink(_mr, match, comp_ref_artifacts):
35 email = match.group(0)
36 if email in comp_ref_artifacts:
37 return [template_helpers.TextRun(
38 tag='a', href='mailto:%s' % email, content=email)]
39 else:
40 return [template_helpers.TextRun('%s AT %s.com' % match.group(1, 2))]
41
42 aa.RegisterComponent('testcomp',
43 LookupUsers,
44 Match2Addresses,
45 {SIMPLE_EMAIL_RE: MakeMailtoLink})
46
47 def RegisterDomainCallbacks(self, aa):
48
49 def LookupDomains(_mr, _all_refs):
50 """Return business objects for only real domains. Always just True."""
51 return True # We don't have domain business objects, accept anything.
52
53 def Match2Domains(_mr, match):
54 return [match.group(0)]
55
56 def MakeHyperLink(_mr, match, _comp_ref_artifacts):
57 domain = match.group(0)
58 return [template_helpers.TextRun(tag='a', href=domain, content=domain)]
59
60 aa.RegisterComponent('testcomp2',
61 LookupDomains,
62 Match2Domains,
63 {OVER_AMBITIOUS_DOMAIN_RE: MakeHyperLink})
64
65 def setUp(self):
66 self.aa = autolink.Autolink()
67 self.RegisterEmailCallbacks(self.aa)
68 self.comment1 = ('Feel free to contact me at a@other.com, '
69 'or b@example.com, or c@example.org.')
70 self.comment2 = 'no matches in this comment'
71 self.comment3 = 'just matches with no ref: a@other.com, c@example.org'
72 self.comments = [self.comment1, self.comment2, self.comment3]
73
74 def testRegisterComponent(self):
75 self.assertIn('testcomp', self.aa.registry)
76
77 def testGetAllReferencedArtifacts(self):
78 all_ref_artifacts = self.aa.GetAllReferencedArtifacts(
79 None, self.comments)
80
81 self.assertIn('testcomp', all_ref_artifacts)
82 comp_refs = all_ref_artifacts['testcomp']
83 self.assertIn('b@example.com', comp_refs)
84 self.assertTrue(len(comp_refs) == 1)
85
86 def testMarkupAutolinks(self):
87 all_ref_artifacts = self.aa.GetAllReferencedArtifacts(None, self.comments)
88 result = self.aa.MarkupAutolinks(
89 None, [template_helpers.TextRun(self.comment1)], all_ref_artifacts)
90 self.assertEqual('Feel free to contact me at ', result[0].content)
91 self.assertEqual('a AT other.com', result[1].content)
92 self.assertEqual(', or ', result[2].content)
93 self.assertEqual('b@example.com', result[3].content)
94 self.assertEqual('mailto:b@example.com', result[3].href)
95 self.assertEqual(', or c@example.org.', result[4].content)
96
97 result = self.aa.MarkupAutolinks(
98 None, [template_helpers.TextRun(self.comment2)], all_ref_artifacts)
99 self.assertEqual('no matches in this comment', result[0].content)
100
101 result = self.aa.MarkupAutolinks(
102 None, [template_helpers.TextRun(self.comment3)], all_ref_artifacts)
103 self.assertEqual('just matches with no ref: ', result[0].content)
104 self.assertEqual('a AT other.com', result[1].content)
105 self.assertEqual(', c@example.org', result[2].content)
106
107 def testNonnestedAutolinks(self):
108 """Test that when a substitution yields plain text, others are applied."""
109 self.RegisterDomainCallbacks(self.aa)
110 all_ref_artifacts = self.aa.GetAllReferencedArtifacts(None, self.comments)
111 result = self.aa.MarkupAutolinks(
112 None, [template_helpers.TextRun(self.comment1)], all_ref_artifacts)
113 self.assertEqual('Feel free to contact me at ', result[0].content)
114 self.assertEqual('a AT ', result[1].content)
115 self.assertEqual('other.com', result[2].content)
116 self.assertEqual('other.com', result[2].href)
117 self.assertEqual(', or ', result[3].content)
118 self.assertEqual('b@example.com', result[4].content)
119 self.assertEqual('mailto:b@example.com', result[4].href)
120 self.assertEqual(', or c@', result[5].content)
121 self.assertEqual('example.org', result[6].content)
122 self.assertEqual('example.org', result[6].href)
123 self.assertEqual('.', result[7].content)
124
125 result = self.aa.MarkupAutolinks(
126 None, [template_helpers.TextRun(self.comment2)], all_ref_artifacts)
127 self.assertEqual('no matches in this comment', result[0].content)
128 result = self.aa.MarkupAutolinks(
129 None, [template_helpers.TextRun(self.comment3)], all_ref_artifacts)
130 self.assertEqual('just matches with no ref: ', result[0].content)
131 self.assertEqual('a AT ', result[1].content)
132 self.assertEqual('other.com', result[2].content)
133 self.assertEqual('other.com', result[2].href)
134 self.assertEqual(', c@', result[3].content)
135 self.assertEqual('example.org', result[4].content)
136 self.assertEqual('example.org', result[4].href)
137
138
139 class URLAutolinkTest(unittest.TestCase):
140
141 def DoLinkify(self, content):
142 """Calls the linkify method and returns the result.
143
144 Args:
145 content: string with a hyperlink.
146
147 Returns:
148 A list of TextRuns with some runs will have the embedded URL hyperlinked.
149 Or, None if no link was detected.
150 """
151 match = autolink._IS_A_LINK_RE.search(content)
152 if not match:
153 return None
154
155 replacement_runs = autolink.Linkify(None, match, None)
156 return replacement_runs
157
158 def testLinkify(self):
159 """Test that given url is autolinked when put in the given context."""
160 # Disallow the linking of URLs with user names and passwords.
161 test = 'http://user:pass@www.yahoo.com'
162 result = self.DoLinkify('What about %s' % test)
163 self.assertEqual(None, result[0].tag)
164 self.assertEqual(None, result[0].href)
165 self.assertEqual(test, result[0].content)
166
167 # Disallow the linking of non-HTTP(S) links
168 test = 'nntp://news.google.com'
169 result = self.DoLinkify('%s' % test)
170 self.assertEqual(None, result)
171
172 # Disallow the linking of file links
173 test = 'file://C:/Windows/System32/cmd.exe'
174 result = self.DoLinkify('%s' % test)
175 self.assertEqual(None, result)
176
177 # Test some known URLs
178 test = 'http://www.example.com'
179 result = self.DoLinkify('What about %s' % test)
180 self.assertEqual(test, result[0].href)
181 self.assertEqual(test, result[0].content)
182
183 def testLinkify_FTP(self):
184 """Test that FTP urls are linked."""
185 # Check for a standard ftp link
186 test = 'ftp://ftp.example.com'
187 result = self.DoLinkify('%s' % test)
188 self.assertEqual(test, result[0].href)
189 self.assertEqual(test, result[0].content)
190
191 def testLinkify_Context(self):
192 """Test that surrounding syntax is not considered part of the url."""
193 test = 'http://www.example.com'
194
195 # Check for a link followed by a comma at end of English phrase.
196 result = self.DoLinkify('The URL %s, points to a great website.' % test)
197 self.assertEqual(test, result[0].href)
198 self.assertEqual(test, result[0].content)
199 self.assertEqual(',', result[1].content)
200
201 # Check for a link followed by a period at end of English sentence.
202 result = self.DoLinkify('The best site ever, %s.' % test)
203 self.assertEqual(test, result[0].href)
204 self.assertEqual(test, result[0].content)
205 self.assertEqual('.', result[1].content)
206
207 # Check for a link in paranthesis (), [], or {}
208 result = self.DoLinkify('My fav site (%s).' % test)
209 self.assertEqual(test, result[0].href)
210 self.assertEqual(test, result[0].content)
211 self.assertEqual(').', result[1].content)
212
213 result = self.DoLinkify('My fav site [%s].' % test)
214 self.assertEqual(test, result[0].href)
215 self.assertEqual(test, result[0].content)
216 self.assertEqual('].', result[1].content)
217
218 result = self.DoLinkify('My fav site {%s}.' % test)
219 self.assertEqual(test, result[0].href)
220 self.assertEqual(test, result[0].content)
221 self.assertEqual('}.', result[1].content)
222
223 # Check for a link with trailing colon
224 result = self.DoLinkify('Hit %s: you will love it.' % test)
225 self.assertEqual(test, result[0].href)
226 self.assertEqual(test, result[0].content)
227 self.assertEqual(':', result[1].content)
228
229 # Check link with commas in query string, but don't include trailing comma.
230 test = 'http://www.example.com/?v=1,2,3'
231 result = self.DoLinkify('Try %s, ok?' % test)
232 self.assertEqual(test, result[0].href)
233 self.assertEqual(test, result[0].content)
234
235 # Check link surrounded by angle-brackets, or quotes.
236 result = self.DoLinkify('<%s>' % test)
237 self.assertEqual(test, result[0].href)
238 self.assertEqual(test, result[0].content)
239 self.assertEqual('>', result[1].content)
240
241 result = self.DoLinkify('"%s"' % test)
242 self.assertEqual(test, result[0].href)
243 self.assertEqual(test, result[0].content)
244 self.assertEqual('"', result[1].content)
245
246 # Check link with embedded quotes.
247 test = 'http://www.example.com/?q="a+b+c"'
248 result = self.DoLinkify('Try %s, ok?' % test)
249 self.assertEqual(test, result[0].href)
250 self.assertEqual(test, result[0].content)
251 self.assertEqual(',', result[1].content)
252
253 # Check link with embedded parens.
254 test = 'http://www.example.com/funky(foo)and(bar).asp'
255 result = self.DoLinkify('Try %s, ok?' % test)
256 self.assertEqual(test, result[0].href)
257 self.assertEqual(test, result[0].content)
258 self.assertEqual(',', result[1].content)
259
260 test = 'http://www.example.com/funky(foo)and(bar).asp'
261 result = self.DoLinkify('My fav site <%s>' % test)
262 self.assertEqual(test, result[0].href)
263 self.assertEqual(test, result[0].content)
264 self.assertEqual('>', result[1].content)
265
266 # Check link with embedded brackets and braces.
267 test = 'http://www.example.com/funky[foo]and{bar}.asp'
268 result = self.DoLinkify('My fav site <%s>' % test)
269 self.assertEqual(test, result[0].href)
270 self.assertEqual(test, result[0].content)
271 self.assertEqual('>', result[1].content)
272
273 # Check link with mismatched delimeters inside it or outside it.
274 test = 'http://www.example.com/funky"(foo]and>bar}.asp'
275 result = self.DoLinkify('My fav site <%s>' % test)
276 self.assertEqual(test, result[0].href)
277 self.assertEqual(test, result[0].content)
278 self.assertEqual('>', result[1].content)
279
280 test = 'http://www.example.com/funky"(foo]and>bar}.asp'
281 result = self.DoLinkify('My fav site {%s' % test)
282 self.assertEqual(test, result[0].href)
283 self.assertEqual(test, result[0].content)
284
285 test = 'http://www.example.com/funky"(foo]and>bar}.asp'
286 result = self.DoLinkify('My fav site %s}' % test)
287 self.assertEqual(test, result[0].href)
288 self.assertEqual(test, result[0].content)
289 self.assertEqual('}', result[1].content)
290
291 # Link as part of an HTML example.
292 test = 'http://www.example.com/'
293 result = self.DoLinkify('<a href="%s">' % test)
294 self.assertEqual(test, result[0].href)
295 self.assertEqual(test, result[0].content)
296 self.assertEqual('">', result[1].content)
297
298 # Link nested in an HTML tag.
299 result = self.DoLinkify('<span>%s</span>' % test)
300 self.assertEqual(test, result[0].href)
301 self.assertEqual(test, result[0].content)
302
303 # Link followed by HTML tag - same bug as above.
304 result = self.DoLinkify('%s<span>foo</span>' % test)
305 self.assertEqual(test, result[0].href)
306 self.assertEqual(test, result[0].content)
307
308 # Link followed by unescaped HTML tag.
309 result = self.DoLinkify('%s<span>foo</span>' % test)
310 self.assertEqual(test, result[0].href)
311 self.assertEqual(test, result[0].content)
312
313 def testLinkify_UnicodeContext(self):
314 """Test that unicode context does not mess up the link."""
315 test = 'http://www.example.com'
316
317 # This string has a non-breaking space \xa0.
318 result = self.DoLinkify(u'The correct RFC link is\xa0%s' % test)
319 self.assertEqual(test, result[0].content)
320 self.assertEqual(test, result[0].href)
321
322 def testLinkify_UnicodeLink(self):
323 """Test that unicode in a link is OK."""
324 test = u'http://www.example.com?q=division\xc3\xb7sign'
325
326 # This string has a non-breaking space \xa0.
327 result = self.DoLinkify(u'The unicode link is %s' % test)
328 self.assertEqual(test, result[0].content)
329 self.assertEqual(test, result[0].href)
330
331 def testLinkify_LinkTextEscapingDisabled(self):
332 """Test that url-like things that miss validation aren't linked."""
333 # Link matched by the regex but not accepted by the validator.
334 test = 'http://crash/reportdetail?reportid=35aa03e04772358b'
335 result = self.DoLinkify('<span>%s</span>' % test)
336 self.assertEqual(None, result[0].href)
337 self.assertEqual(test, result[0].content)
338
339
340 def _Issue(project_name, local_id, summary, status):
341 issue = tracker_pb2.Issue()
342 issue.project_name = project_name
343 issue.local_id = local_id
344 issue.summary = summary
345 issue.status = status
346 return issue
347
348
349 class TrackerAutolinkTest(unittest.TestCase):
350
351 COMMENT_TEXT = (
352 'This relates to issue 1, issue #2, and issue3 \n'
353 'as well as bug 4, bug #5, and bug6 \n'
354 'with issue other-project:12 and issue other-project#13. \n'
355 'Watch out for issues 21, 22, and 23 with oxford comma. \n'
356 'And also bugs 31, 32 and 33 with no oxford comma\n'
357 'We do not match when an issue\n'
358 '999. Is split across lines.'
359 )
360
361 def testExtractProjectAndIssueId(self):
362 mr = testing_helpers.MakeMonorailRequest(
363 path='/p/proj/issues/detail?id=1')
364 ref_batches = []
365 for match in autolink._ISSUE_REF_RE.finditer(self.COMMENT_TEXT):
366 new_refs = autolink.ExtractProjectAndIssueIds(mr, match)
367 ref_batches.append(new_refs)
368
369 self.assertEquals(
370 ref_batches,
371 [[(None, 1)],
372 [(None, 2)],
373 [(None, 3)],
374 [(None, 4)],
375 [(None, 5)],
376 [(None, 6)],
377 [('other-project', 12)],
378 [('other-project', 13)],
379 [(None, 21), (None, 22), (None, 23)],
380 [(None, 31), (None, 32), (None, 33)],
381 ])
382
383 def DoReplaceIssueRef(self, content):
384 """Calls the ReplaceIssueRef method and returns the result.
385
386 Args:
387 content: string that may have a textual reference to an issue.
388
389 Returns:
390 A list of TextRuns with some runs will have the reference hyperlinked.
391 Or, None if no reference detected.
392 """
393 match = autolink._ISSUE_REF_RE.search(content)
394 if not match:
395 return None
396
397 open_dict = {'proj:1': _Issue('proj', 1, 'summary-PROJ-1', 'New'),
398 # Assume there is no issue 3 in PROJ
399 'proj:4': _Issue('proj', 4, 'summary-PROJ-4', 'New'),
400 'proj:6': _Issue('proj', 6, 'summary-PROJ-6', 'New'),
401 'other-project:12': _Issue('other-project', 12,
402 'summary-OP-12', 'Accepted'),
403 }
404 closed_dict = {'proj:2': _Issue('proj', 2, 'summary-PROJ-2', 'Fixed'),
405 'proj:5': _Issue('proj', 5, 'summary-PROJ-5', 'Fixed'),
406 'other-project:13': _Issue('other-project', 13,
407 'summary-OP-12', 'Invalid'),
408 }
409 comp_ref_artifacts = (open_dict, closed_dict,)
410
411 mr = testing_helpers.MakeMonorailRequest(path='/p/proj/issues/detail?r=1')
412 replacement_runs = autolink.ReplaceIssueRef(mr, match, comp_ref_artifacts)
413 return replacement_runs
414
415 def testReplaceIssueRef(self):
416
417 result = self.DoReplaceIssueRef('This relates to issue 1')
418 self.assertEquals('/p/proj/issues/detail?id=1', result[0].href)
419 self.assertEquals('issue 1', result[0].content)
420 self.assertEquals(None, result[0].css_class)
421 self.assertEquals('summary-PROJ-1', result[0].title)
422 self.assertEquals('a', result[0].tag)
423
424 result = self.DoReplaceIssueRef(', issue #2')
425 self.assertEquals('/p/proj/issues/detail?id=2', result[0].href)
426 self.assertEquals('issue #2', result[0].content)
427 self.assertEquals('closed_ref', result[0].css_class)
428 self.assertEquals('summary-PROJ-2', result[0].title)
429 self.assertEquals('a', result[0].tag)
430
431 result = self.DoReplaceIssueRef(', and issue3 ')
432 self.assertEquals(None, result[0].href) # There is no issue 3
433 self.assertEquals('issue3', result[0].content)
434
435 result = self.DoReplaceIssueRef('as well as bug 4')
436 self.assertEquals('/p/proj/issues/detail?id=4', result[0].href)
437 self.assertEquals('bug 4', result[0].content)
438
439 result = self.DoReplaceIssueRef(', bug #5, ')
440 self.assertEquals('/p/proj/issues/detail?id=5', result[0].href)
441 self.assertEquals('bug #5', result[0].content)
442
443 result = self.DoReplaceIssueRef('and bug6')
444 self.assertEquals('/p/proj/issues/detail?id=6', result[0].href)
445 self.assertEquals('bug6', result[0].content)
446
447 result = self.DoReplaceIssueRef('with issue other-project:12')
448 self.assertEquals('/p/other-project/issues/detail?id=12', result[0].href)
449 self.assertEquals('issue other-project:12', result[0].content)
450
451 result = self.DoReplaceIssueRef('and issue other-project#13')
452 self.assertEquals('/p/other-project/issues/detail?id=13', result[0].href)
453 self.assertEquals('issue other-project#13', result[0].content)
454
455 def testParseProjectNameMatch(self):
456 golden = 'project-name'
457 variations = ['%s', ' %s', '%s ', '%s:', '%s#', '%s#:', '%s:#', '%s :#',
458 '\t%s', '%s\t', '\t%s\t', '\t\t%s\t\t', '\n%s', '%s\n',
459 '\n%s\n', '\n\n%s\n\n', '\t\n%s', '\n\t%s', '%s\t\n',
460 '%s\n\t', '\t\n%s#', '\n\t%s#', '%s\t\n#', '%s\n\t#',
461 '\t\n%s:', '\n\t%s:', '%s\t\n:', '%s\n\t:'
462 ]
463
464 # First pass checks all valid project name results
465 for pattern in variations:
466 self.assertEquals(
467 golden, autolink._ParseProjectNameMatch(pattern % golden))
468
469 # Second pass tests all inputs that should result in None
470 for pattern in variations:
471 self.assert_(
472 autolink._ParseProjectNameMatch(pattern % '') in [None, ''])
473
474
475 class VCAutolinkTest(unittest.TestCase):
476
477 GIT_HASH_1 = '1' * 40
478 GIT_HASH_2 = '2' * 40
479 GIT_HASH_3 = 'a1' * 20
480 GIT_COMMENT_TEXT = (
481 'This is a fix for r%s and R%s, by r2d2, who also authored revision %s, '
482 'revision #%s, revision %s, and revision %s' % (
483 GIT_HASH_1, GIT_HASH_2, GIT_HASH_3,
484 GIT_HASH_1.upper(), GIT_HASH_2.upper(), GIT_HASH_3.upper()))
485 SVN_COMMENT_TEXT = (
486 'This is a fix for r12 and R34, by r2d2, who also authored revision r4, '
487 'revision #1234567, revision 789, and revision 9025. If you have '
488 'questions, call me at 18005551212')
489
490 def testGetReferencedRevisions(self):
491 refs = ['1', '2', '3']
492 # For now, we do not look up revision objects, result is always None
493 self.assertIsNone(autolink.GetReferencedRevisions(None, refs))
494
495 def testExtractGitHashes(self):
496 refs = []
497 for match in autolink._GIT_HASH_RE.finditer(self.GIT_COMMENT_TEXT):
498 new_refs = autolink.ExtractRevNums(None, match)
499 refs.extend(new_refs)
500
501 self.assertEquals(
502 refs, [self.GIT_HASH_1, self.GIT_HASH_2, self.GIT_HASH_3,
503 self.GIT_HASH_1.upper(), self.GIT_HASH_2.upper(),
504 self.GIT_HASH_3.upper()])
505
506 def testExtractRevNums(self):
507 refs = []
508 for match in autolink._SVN_REF_RE.finditer(self.SVN_COMMENT_TEXT):
509 new_refs = autolink.ExtractRevNums(None, match)
510 refs.extend(new_refs)
511
512 self.assertEquals(
513 refs, ['12', '34', '4', '1234567', '789', '9025'])
514
515
516 def DoReplaceRevisionRef(self, content, project=None):
517 """Calls the ReplaceRevisionRef method and returns the result.
518
519 Args:
520 content: string with a hyperlink.
521 project: optional project.
522
523 Returns:
524 A list of TextRuns with some runs will have the embedded URL hyperlinked.
525 Or, None if no link was detected.
526 """
527 match = autolink._GIT_HASH_RE.search(content)
528 if not match:
529 return None
530
531 mr = testing_helpers.MakeMonorailRequest(
532 path='/p/proj/source/detail?r=1', project=project)
533 replacement_runs = autolink.ReplaceRevisionRef(mr, match, None)
534 return replacement_runs
535
536 def testReplaceRevisionRef(self):
537 result = self.DoReplaceRevisionRef(
538 'This is a fix for r%s' % self.GIT_HASH_1)
539 self.assertEquals('https://crrev.com/%s' % self.GIT_HASH_1, result[0].href)
540 self.assertEquals('r%s' % self.GIT_HASH_1, result[0].content)
541
542 result = self.DoReplaceRevisionRef(
543 'and R%s, by r2d2, who ' % self.GIT_HASH_2)
544 self.assertEquals('https://crrev.com/%s' % self.GIT_HASH_2, result[0].href)
545 self.assertEquals('R%s' % self.GIT_HASH_2, result[0].content)
546
547 result = self.DoReplaceRevisionRef('by r2d2, who ')
548 self.assertEquals(None, result)
549
550 result = self.DoReplaceRevisionRef(
551 'also authored revision %s, ' % self.GIT_HASH_3)
552 self.assertEquals('https://crrev.com/%s' % self.GIT_HASH_3, result[0].href)
553 self.assertEquals('revision %s' % self.GIT_HASH_3, result[0].content)
554
555 result = self.DoReplaceRevisionRef(
556 'revision #%s, ' % self.GIT_HASH_1.upper())
557 self.assertEquals(
558 'https://crrev.com/%s' % self.GIT_HASH_1.upper(), result[0].href)
559 self.assertEquals(
560 'revision #%s' % self.GIT_HASH_1.upper(), result[0].content)
561
562 result = self.DoReplaceRevisionRef(
563 'revision %s, ' % self.GIT_HASH_2.upper())
564 self.assertEquals(
565 'https://crrev.com/%s' % self.GIT_HASH_2.upper(), result[0].href)
566 self.assertEquals(
567 'revision %s' % self.GIT_HASH_2.upper(), result[0].content)
568
569 result = self.DoReplaceRevisionRef(
570 'and revision %s' % self.GIT_HASH_3.upper())
571 self.assertEquals(
572 'https://crrev.com/%s' % self.GIT_HASH_3.upper(), result[0].href)
573 self.assertEquals(
574 'revision %s' % self.GIT_HASH_3.upper(), result[0].content)
575
576 def testReplaceRevisionRef_CustomURL(self):
577 """A project can override the URL used for revision links."""
578 project = fake.Project()
579 project.revision_url_format = 'http://example.com/+/{revnum}'
580 result = self.DoReplaceRevisionRef(
581 'This is a fix for r%s' % self.GIT_HASH_1, project=project)
582 self.assertEquals(
583 'http://example.com/+/%s' % self.GIT_HASH_1, result[0].href)
584 self.assertEquals('r%s' % self.GIT_HASH_1, result[0].content)
585
586
587 if __name__ == '__main__':
588 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/features/test/activities_test.py ('k') | appengine/monorail/features/test/commands_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698