def test_link_github_issues(self):
        # "#\d+" in messages referencing a source GitHub repo should get linked
        # to GitHub issues.
        self.assertEqual(
            add_hyperlinks(b'Merge #5\n\n'
                           b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'Merge <a href="https://github.com/mozilla/foo/issues/5">#5</a>\n\n'
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
        )

        self.assertEqual(
            add_hyperlinks(b'Fix #34252\n\n'
                           b'Related to PR #1321\n\n'
                           b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'Fix <a href="https://github.com/mozilla/foo/issues/34252">#34252</a>\n\n'
            b'Related to PR <a href="https://github.com/mozilla/foo/issues/1321">#1321</a>\n\n'
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
        )

        # "#string" isn't linked.
        self.assertEqual(
            add_hyperlinks(b'Merge #foo\n\n'
                           b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'Merge #foo\n\n'
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
        )
 def test_link_xchannel(self):
     self.assertEqual(
         add_hyperlinks(b'X-Channel-Active-Revision: a1234567890123456789'),
         b'X-Channel-Active-Revision: a1234567890123456789')
     self.assertEqual(
         add_hyperlinks(b'X-Channel-Revision: a1234567890123456789'),
         b'X-Channel-Revision: a1234567890123456789')
     self.assertEqual(
         add_hyperlinks(b'X-Channel-Repo: mozilla-central\n'
                        b'X-Channel-Revision: a1234567890123456789'),
         b'X-Channel-Repo: mozilla-central\n'
         b'X-Channel-Revision: a1234567890123456789')
     self.assertEqual(
         add_hyperlinks(
             b'X-Channel-Repo: mozilla-central\n'
             b'X-Channel-Converted-Revision: a1234567890123456789'),
         b'X-Channel-Repo: mozilla-central\n'
         b'X-Channel-Converted-Revision: '
         b'<a href="https://hg.mozilla.org/mozilla-central/rev/a1234567890123456789">a1234567890123456789</a>'
     )
     self.assertEqual(
         add_hyperlinks(
             b'X-Channel-Repo: releases/mozilla-esr-59_0.1\n'
             b'X-Channel-Converted-Revision: a1234567890123456789'),
         b'X-Channel-Repo: releases/mozilla-esr-59_0.1\n'
         b'X-Channel-Converted-Revision: '
         b'<a href="https://hg.mozilla.org/releases/mozilla-esr-59_0.1/rev/a1234567890123456789">a1234567890123456789</a>'
     )
     self.assertEqual(
         add_hyperlinks(
             b'X-Channel-Repo: mozilla-central\n'
             b'X-Channel-Revision: b1234567890123456789\n'
             b'X-Channel-Repo: releases/mozilla-beta\n'
             b'X-Channel-Converted-Revision: a1234567890123456789'),
         b'X-Channel-Repo: mozilla-central\n'
         b'X-Channel-Revision: b1234567890123456789\n'
         b'X-Channel-Repo: releases/mozilla-beta\n'
         b'X-Channel-Converted-Revision: '
         b'<a href="https://hg.mozilla.org/releases/mozilla-beta/rev/a1234567890123456789">a1234567890123456789</a>'
     )
     self.assertEqual(
         add_hyperlinks(
             b'X-Channel-Repo: mozilla-central\n'
             b'X-Channel-Converted-Revision: b1234567890123456789\n'
             b'X-Channel-Repo: releases/mozilla-beta\n'
             b'X-Channel-Revision: a1234567890123456789'),
         b'X-Channel-Repo: mozilla-central\n'
         b'X-Channel-Converted-Revision: '
         b'<a href="https://hg.mozilla.org/mozilla-central/rev/b1234567890123456789">b1234567890123456789</a>\n'
         b'X-Channel-Repo: releases/mozilla-beta\n'
         b'X-Channel-Revision: a1234567890123456789')
     # try html through |escape|mozlink
     self.assertEqual(
         add_hyperlinks(
             escape(b'X-Channel-Repo: mozilla-&\n'
                    b'X-Channel-Revision: a1234567890123456789')),
         b'X-Channel-Repo: mozilla-&amp;\n'
         b'X-Channel-Revision: a1234567890123456789')
    def test_link_bugzilla(self):
        # Aggressive bug detection works normally.
        self.assertEqual(add_hyperlinks(
            b' 1234567\nfoo\n'),
            b' <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1234567">1234567</a>\nfoo\n')
        self.assertEqual(add_hyperlinks(
            b'bug 1\n'),
            b'<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1">bug 1</a>\n')
        self.assertEqual(add_hyperlinks(
            b'bug 123456\n'),
            b'<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=123456">bug 123456</a>\n')
        self.assertEqual(add_hyperlinks(
            b'12345 is a bug\n'),
            b'<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=12345">12345</a> is a bug\n')
        self.assertEqual(add_hyperlinks(
            b'foo #123456\n'),
            b'foo #<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=123456">123456</a>\n')

        # When GitHub is in play, bare numbers are not hyperlinked and #\d is
        # for GitHub issues.

        self.assertEqual(add_hyperlinks(
            b'Bug 123456 - Fix all of the things\n\n'
            b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=123456">Bug 123456</a> - Fix all of the things\n\n'
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n')

        self.assertEqual(add_hyperlinks(
            b'Merge #4256\n\n'
            b'This fixes #9000 and bug 324521\n\n'
            b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'Merge <a href="https://github.com/mozilla/foo/issues/4256">#4256</a>\n\n'
            b'This fixes <a href="https://github.com/mozilla/foo/issues/9000">#9000</a> and '
            b'<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=324521">bug 324521</a>\n\n'
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n')
 def test_link_phabricator(self):
     """Tests hyperlinking of Phabricator URLs on hg.mozilla.org.
     Only support hyperlinking for URLs added to commit messages via
     the Lando API."""
     # Phabricator URL matching Lando insertion should be hyperlinked
     self.assertEqual(
         add_hyperlinks(
             b'Differential Revision: https://phabricator.services.mozilla.com/D1234'
         ),
         b'Differential Revision: <a href="https://phabricator.services.mozilla.com/D1234">https://phabricator.services.mozilla.com/D1234</a>'
     )
    def test_link_source_repo(self):
        self.assertEqual(add_hyperlinks(b'Source-Repo: not a link\n'),
                         b'Source-Repo: not a link\n')

        self.assertEqual(
            add_hyperlinks(b'Source-Repo: https://example.com\n'),
            b'Source-Repo: <a href="https://example.com">https://example.com</a>\n'
        )

        # On subsequent line
        self.assertEqual(
            add_hyperlinks(b'summary\n\nSource-Repo: https://example.com\n'),
            b'summary\n\nSource-Repo: <a href="https://example.com">https://example.com</a>\n'
        )

        # With postfix content.
        self.assertEqual(
            add_hyperlinks(
                b'summary\n\nSource-Repo: https://example.com\nnext line\n'),
            b'summary\n\nSource-Repo: <a href="https://example.com">https://example.com</a>\nnext line\n'
        )

        self.assertEqual(
            add_hyperlinks(b'Source-Repo: https://github.com/mozilla/foo\n'),
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
        )

        # Check against malicious character in commit message.
        self.assertEqual(
            add_hyperlinks(
                b'Source-Repo: https://example.com?bad&escape=%20\n'),
            b'Source-Repo: <a href="https://example.com?bad&amp;escape=%20">https://example.com?bad&amp;escape=%20</a>\n'
        )
    def test_link_revision(self):
        # GitHub revision is linked.
        self.assertEqual(add_hyperlinks(
            b'Source-Repo: https://github.com/mozilla/foo\n'
            b'Source-Revision: abcdef\n'),
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
            b'Source-Revision: <a href="https://github.com/mozilla/foo/commit/abcdef">abcdef</a>\n')

        # Non-GitHub revision isn't linked.
        self.assertEqual(add_hyperlinks(
            b'summary\n\n'
            b'Source-Repo: https://example.com/foo\n'
            b'Source-Revision: abcdef\n'),
            b'summary\n\n'
            b'Source-Repo: <a href="https://example.com/foo">https://example.com/foo</a>\n'
            b'Source-Revision: abcdef\n')

        # Bad characters in revision string are escaped.
        self.assertEqual(add_hyperlinks(
            b'Source-Repo: https://github.com/mozilla/foo\n'
            b'Source-Revision: a?b&c=%20\n'),
            b'Source-Repo: <a href="https://github.com/mozilla/foo">https://github.com/mozilla/foo</a>\n'
            b'Source-Revision: <a href="https://github.com/mozilla/foo/commit/a?b&amp;c=%20">a?b&amp;c=%20</a>\n')
def mozlink(text):
    """Any text. Hyperlink to Bugzilla and other detected things."""
    return commitparser.add_hyperlinks(text)