# -*- coding: utf-8 -*- from __future__ import print_function from __future__ import absolute_import from django.conf import settings from django.test import TestCase from zerver.lib import bugdown from zerver.lib.actions import ( do_add_realm_emoji, do_remove_realm_emoji, get_realm, ) from zerver.models import ( get_user_profile_by_email, Message, RealmFilter, ) import os import ujson import six class FencedBlockPreprocessorTest(TestCase): def test_simple_quoting(self): processor = bugdown.fenced_code.FencedBlockPreprocessor(None) markdown = [ '~~~ quote', 'hi', 'bye', '', '' ] expected = [ '', '> hi', '> bye', '', '', '' ] lines = processor.run(markdown) self.assertEqual(lines, expected) def test_serial_quoting(self): processor = bugdown.fenced_code.FencedBlockPreprocessor(None) markdown = [ '~~~ quote', 'hi', '~~~', '', '~~~ quote', 'bye', '', '' ] expected = [ '', '> hi', '', '', '', '> bye', '', '', '' ] lines = processor.run(markdown) self.assertEqual(lines, expected) def test_serial_code(self): processor = bugdown.fenced_code.FencedBlockPreprocessor(None) # Simulate code formatting. processor.format_code = lambda lang, code: lang + ':' + code processor.placeholder = lambda s: '**' + s.strip('\n') + '**' markdown = [ '``` .py', 'hello()', '```', '', '``` .py', 'goodbye()', '```', '', '' ] expected = [ '', '**py:hello()**', '', '', '', '**py:goodbye()**', '', '', '' ] lines = processor.run(markdown) self.assertEqual(lines, expected) def test_nested_code(self): processor = bugdown.fenced_code.FencedBlockPreprocessor(None) # Simulate code formatting. processor.format_code = lambda lang, code: lang + ':' + code processor.placeholder = lambda s: '**' + s.strip('\n') + '**' markdown = [ '~~~ quote', 'hi', '``` .py', 'hello()', '```', '', '' ] expected = [ '', '> hi', '', '> **py:hello()**', '', '', '' ] lines = processor.run(markdown) self.assertEqual(lines, expected) def bugdown_convert(text): return bugdown.convert(text, "zulip.com") class BugdownTest(TestCase): def common_bugdown_test(self, text, expected): converted = bugdown_convert(text) self.assertEqual(converted, expected) def load_bugdown_tests(self): test_fixtures = {} data_file = open(os.path.join(os.path.dirname(__file__), 'fixtures/bugdown-data.json'), 'r') data = ujson.loads('\n'.join(data_file.readlines())) for test in data['regular_tests']: test_fixtures[test['name']] = test return test_fixtures, data['linkify_tests'] def test_bugdown_fixtures(self): format_tests, linkify_tests = self.load_bugdown_tests() self.maxDiff = None for name, test in six.iteritems(format_tests): converted = bugdown_convert(test['input']) print("Running Bugdown test %s" % (name,)) self.assertEqual(converted, test['expected_output']) def replaced(payload, url, phrase=''): target = " target=\"_blank\"" if url[:4] == 'http': href = url elif '@' in url: href = 'mailto:' + url target = "" else: href = 'http://' + url return payload % ("%s" % (href, target, href, url),) print("Running Bugdown Linkify tests") self.maxDiff = None for inline_url, reference, url in linkify_tests: try: match = replaced(reference, url, phrase=inline_url) except TypeError: match = reference converted = bugdown_convert(inline_url) self.assertEqual(match, converted) def test_inline_youtube(self): msg = 'Check out the debate: http://www.youtube.com/watch?v=hx1mjT73xYE' converted = bugdown_convert(msg) self.assertEqual(converted, '
Check out the debate: http://www.youtube.com/watch?v=hx1mjT73xYE
\n ') def test_inline_dropbox(self): return # The dropbox url format changed msg = 'Look at how hilarious our old office was: https://www.dropbox.com/s/ymdijjcg67hv2ta/IMG_0923.JPG' converted = bugdown_convert(msg) self.assertEqual(converted, 'Look at how hilarious our old office was: https://www.dropbox.com/s/ymdijjcg67hv2ta/IMG_0923.JPG
\n ') msg = 'Look at my hilarious drawing folder: https://www.dropbox.com/sh/cm39k9e04z7fhim/AAAII5NK-9daee3FcF41anEua?dl=' converted = bugdown_convert(msg) self.assertEqual(converted, 'Look at my hilarious drawing folder: https://www.dropbox.com/sh/cm39k9e04z7fhim/AAAII5NK-9daee3FcF41anEua?dl=
\n ') # Test photo album previews msg = 'https://www.dropbox.com/sc/tditp9nitko60n5/03rEiZldy5' converted = bugdown_convert(msg) self.assertEqual(converted, 'https://www.dropbox.com/sc/tditp9nitko60n5/03rEiZldy5
\n ') # Make sure we're not overzealous in our conversion: msg = 'Look at the new dropbox logo: https://www.dropbox.com/static/images/home_logo.png' converted = bugdown_convert(msg) self.assertEqual(converted, 'Look at the new dropbox logo: https://www.dropbox.com/static/images/home_logo.png
\n ') # Don't fail on bad dropbox links msg = "https://meta-dbdev.dev.corp.dropbox.com/photos/cl/ROmr9K1XYtmpneM" converted = bugdown_convert(msg) self.assertEqual(converted, 'https://meta-dbdev.dev.corp.dropbox.com/photos/cl/ROmr9K1XYtmpneM
\n ') def test_twitter_id_extraction(self): self.assertEqual(bugdown.get_tweet_id('http://twitter.com/#!/VizzQuotes/status/409030735191097344'), '409030735191097344') self.assertEqual(bugdown.get_tweet_id('http://twitter.com/VizzQuotes/status/409030735191097344'), '409030735191097344') self.assertEqual(bugdown.get_tweet_id('http://twitter.com/VizzQuotes/statuses/409030735191097344'), '409030735191097344') self.assertEqual(bugdown.get_tweet_id('https://twitter.com/wdaher/status/1017581858'), '1017581858') self.assertEqual(bugdown.get_tweet_id('https://twitter.com/wdaher/status/1017581858/'), '1017581858') self.assertEqual(bugdown.get_tweet_id('https://twitter.com/windyoona/status/410766290349879296/photo/1'), '410766290349879296') self.assertEqual(bugdown.get_tweet_id('https://twitter.com/windyoona/status/410766290349879296/'), '410766290349879296') def test_inline_interesting_links(self): def make_link(url): return '%s' % (url, url, url) normal_tweet_html = """@twitter meets @seepicturely at #tcdisrupt cc.@boscomonkey @episod http://instagram.com/p/MuW67/""" mention_in_link_tweet_html = """http://foo.com""" media_tweet_html = """http://twitter.com/NEVNBoston/status/421654515616849920/photo/1""" def make_inline_twitter_preview(url, tweet_html, image_html=''): ## As of right now, all previews are mocked to be the exact same tweet return """""" % (url, tweet_html, image_html) msg = 'http://www.twitter.com' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
' % make_link('http://www.twitter.com')) msg = 'http://www.twitter.com/wdaher/' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
' % make_link('http://www.twitter.com/wdaher/')) msg = 'http://www.twitter.com/wdaher/status/3' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
' % make_link('http://www.twitter.com/wdaher/status/3')) # id too long msg = 'http://www.twitter.com/wdaher/status/2879779692873154569' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
' % make_link('http://www.twitter.com/wdaher/status/2879779692873154569')) # id too large (i.e. tweet doesn't exist) msg = 'http://www.twitter.com/wdaher/status/999999999999999999' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
' % make_link('http://www.twitter.com/wdaher/status/999999999999999999')) msg = 'http://www.twitter.com/wdaher/status/287977969287315456' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
\n%s' % (make_link('http://www.twitter.com/wdaher/status/287977969287315456'), make_inline_twitter_preview('http://www.twitter.com/wdaher/status/287977969287315456', normal_tweet_html))) msg = 'https://www.twitter.com/wdaher/status/287977969287315456' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
\n%s' % (make_link('https://www.twitter.com/wdaher/status/287977969287315456'), make_inline_twitter_preview('https://www.twitter.com/wdaher/status/287977969287315456', normal_tweet_html))) msg = 'http://twitter.com/wdaher/status/287977969287315456' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
\n%s' % (make_link('http://twitter.com/wdaher/status/287977969287315456'), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315456', normal_tweet_html))) # A max of 3 will be converted msg = 'http://twitter.com/wdaher/status/287977969287315456 http://twitter.com/wdaher/status/287977969287315457 http://twitter.com/wdaher/status/287977969287315457 http://twitter.com/wdaher/status/287977969287315457' converted = bugdown_convert(msg) self.assertEqual(converted, '%s %s %s %s
\n%s%s%s' % (make_link('http://twitter.com/wdaher/status/287977969287315456'), make_link('http://twitter.com/wdaher/status/287977969287315457'), make_link('http://twitter.com/wdaher/status/287977969287315457'), make_link('http://twitter.com/wdaher/status/287977969287315457'), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315456', normal_tweet_html), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315457', normal_tweet_html), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315457', normal_tweet_html))) # Tweet has a mention in a URL, only the URL is linked msg = 'http://twitter.com/wdaher/status/287977969287315458' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
\n%s' % (make_link('http://twitter.com/wdaher/status/287977969287315458'), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315458', mention_in_link_tweet_html))) # Tweet with an image msg = 'http://twitter.com/wdaher/status/287977969287315459' converted = bugdown_convert(msg) self.assertEqual(converted, '%s
\n%s' % (make_link('http://twitter.com/wdaher/status/287977969287315459'), make_inline_twitter_preview('http://twitter.com/wdaher/status/287977969287315459', media_tweet_html, """"""))) def test_fetch_tweet_data_settings_validation(self): with self.settings(TEST_SUITE=False, TWITTER_CONSUMER_KEY=None): self.assertIs(None, bugdown.fetch_tweet_data('287977969287315459')) def test_realm_emoji(self): def emoji_img(name, url): return '' % (name, url, name) zulip_realm = get_realm('zulip.com') url = "https://zulip.com/test_realm_emoji.png" do_add_realm_emoji(zulip_realm, "test", url) # Needs to mock an actual message because that's how bugdown obtains the realm msg = Message(sender=get_user_profile_by_email("hamlet@zulip.com")) converted = bugdown.convert(":test:", "zulip.com", msg) self.assertEqual(converted, '%s
' %(emoji_img(':test:', url))) do_remove_realm_emoji(zulip_realm, 'test') converted = bugdown.convert(":test:", "zulip.com", msg) self.assertEqual(converted, ':test:
') def test_realm_patterns(self): RealmFilter(realm=get_realm('zulip.com'), pattern=r"#(?PWe should fix #224 and #115, but not issue#124 or #1124z or trac #15 today.
') def test_stream_subscribe_button_simple(self): msg = '!_stream_subscribe_button(simple)' converted = bugdown_convert(msg) self.assertEqual( converted, '' '' '' '' '' '
' ) def test_stream_subscribe_button_in_name(self): msg = '!_stream_subscribe_button(simple (not\\))' converted = bugdown_convert(msg) self.assertEqual( converted, '' '' '' '' '' '
' ) def test_stream_subscribe_button_after_name(self): msg = '!_stream_subscribe_button(simple) (not)' converted = bugdown_convert(msg) self.assertEqual( converted, '' '' '' '' '' ' (not)
' ) def test_stream_subscribe_button_slash(self): msg = '!_stream_subscribe_button(simple\\\\)' converted = bugdown_convert(msg) self.assertEqual( converted, '' '' '' '' '' '
' ) def test_in_app_modal_link(self): msg = '!modal_link(#settings, Settings page)' converted = bugdown_convert(msg) self.assertEqual( converted, '' 'Settings page' '
' ) def test_mit_rendering(self): msg = "**test**" converted = bugdown.convert(msg, "mit.edu/zephyr_mirror") self.assertEqual( converted, "**test**
", ) msg = "* test" converted = bugdown.convert(msg, "mit.edu/zephyr_mirror") self.assertEqual( converted, "* test
", ) msg = "https://lists.debian.org/debian-ctte/2014/02/msg00173.html" converted = bugdown.convert(msg, "mit.edu/zephyr_mirror") self.assertEqual( converted, '', )