/*global Dict */ var path = require('path'); var fs = require('fs'); set_global('window', { location: { origin: 'http://zulip.zulipdev.com', }, }); set_global('page_params', { realm_users: [], realm_emoji: { burrito: {display_url: '/static/generated/emoji/images/emoji/burrito.png', source_url: '/static/generated/emoji/images/emoji/burrito.png'}, }, realm_filters: [ [ "#(?P[0-9]{2,8})", "https://trac.zulip.net/ticket/%(id)s", ], [ "ZBUG_(?P[0-9]{2,8})", "https://trac2.zulip.net/ticket/%(id)s", ], [ "ZGROUP_(?P[0-9]{2,8}):(?P[0-9]{1,8})", "https://zone_%(zone)s.zulip.net/ticket/%(id)s", ], ], }); set_global('blueslip', {}); add_dependencies({ marked: 'third/marked/lib/marked.js', emoji_codes: 'generated/emoji/emoji_codes.js', emoji: 'js/emoji.js', people: 'js/people.js', stream_data: 'js/stream_data.js', hash_util: 'js/hash_util', fenced_code: 'js/fenced_code.js', katex: 'node_modules/katex/dist/katex.min.js', util: 'js/util.js', }); var doc = ""; set_global('document', doc); set_global('$', global.make_zjquery()); set_global('feature_flags', {local_echo: true}); var people = global.people; var cordelia = { full_name: 'Cordelia Lear', user_id: 101, email: 'cordelia@zulip.com', }; people.add(cordelia); people.add({ full_name: 'Leo', user_id: 102, email: 'leo@zulip.com', }); people.initialize_current_user(cordelia.user_id); var stream_data = global.stream_data; var denmark = { subscribed: false, color: 'blue', name: 'Denmark', stream_id: 1, in_home_view: false, }; var social = { subscribed: true, color: 'red', name: 'social', stream_id: 2, in_home_view: true, invite_only: true, }; stream_data.add_sub('Denmark', denmark); stream_data.add_sub('social', social); // Check the default behavior of fenced code blocks // works properly before markdown is initialized. (function test_fenced_block_defaults() { var input = '\n```\nfenced code\n```\n\nand then after\n'; var expected = '\n\n
fenced code\n
\n\n\n\nand then after\n\n'; var output = fenced_code.process_fenced_code(input); assert.equal(output, expected); }()); var markdown = require('js/markdown.js'); markdown.initialize(); var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver/fixtures/bugdown-data.json'), 'utf8', 'r')); (function test_bugdown_detection() { var no_markup = [ "This is a plaintext message", "This is a plaintext: message", "This is a :plaintext message", "This is a :plaintext message: message", "Contains a not an image.jpeg/ok file", "Contains a not an http://www.google.com/ok/image.png/stop file", "No png to be found here, a png", "No user mention **leo**", "No user mention @what there", "We like to code\n~~~\ndef code():\n we = \"like to do\"\n~~~", "This is a\nmultiline :emoji: here\n message", "This is an :emoji: message", "User Mention @**leo**", "User Mention @**leo f**", "User Mention @**leo with some name**", "Stream #**Verona**", "This contains !gravatar(leo@zulip.com)", "And an avatar !avatar(leo@zulip.com) is here", ]; var markup = [ "Contains a https://zulip.com/image.png file", "Contains a https://zulip.com/image.jpg file", "https://zulip.com/image.jpg", "also https://zulip.com/image.jpg", "https://zulip.com/image.jpg too", "Contains a zulip.com/foo.jpeg file", "Contains a https://zulip.com/image.png file", "twitter url https://twitter.com/jacobian/status/407886996565016579", "https://twitter.com/jacobian/status/407886996565016579", "then https://twitter.com/jacobian/status/407886996565016579", "twitter url http://twitter.com/jacobian/status/407886996565016579", "youtube url https://www.youtube.com/watch?v=HHZ8iqswiCw&feature=youtu.be&a", ]; no_markup.forEach(function (content) { assert.equal(markdown.contains_bugdown(content), false); }); markup.forEach(function (content) { assert.equal(markdown.contains_bugdown(content), true); }); }()); (function test_marked_shared() { var tests = bugdown_data.regular_tests; tests.forEach(function (test) { var message = {raw_content: test.input}; markdown.apply_markdown(message); var output = message.content; if (test.bugdown_matches_marked) { assert.equal(test.expected_output, output); } else { assert.notEqual(test.expected_output, output); } }); }()); (function test_message_flags() { var message = {raw_content: '@**Leo**'}; markdown.apply_markdown(message); assert(!_.contains(message.flags, 'mentioned')); message = {raw_content: '@**Cordelia Lear**'}; markdown.apply_markdown(message); assert(_.contains(message.flags, 'mentioned')); message = {raw_content: '@**all**'}; markdown.apply_markdown(message); assert(_.contains(message.flags, 'mentioned')); }()); (function test_marked() { var test_cases = [ {input: 'hello', expected: '

hello

'}, {input: 'hello there', expected: '

hello there

'}, {input: 'hello **bold** for you', expected: '

hello bold for you

'}, {input: '__hello__', expected: '

__hello__

'}, {input: '\n```\nfenced code\n```\n\nand then after\n', expected: '
fenced code\n
\n\n\n

and then after

'}, {input: '\n```\n fenced code trailing whitespace \n```\n\nand then after\n', expected: '
    fenced code trailing whitespace\n
\n\n\n

and then after

'}, {input: '* a\n* list \n* here', expected: '
    \n
  • a
  • \n
  • list
  • \n
  • here
  • \n
'}, {input: '\n```c#\nfenced code special\n```\n\nand then after\n', expected: '
fenced code special\n
\n\n\n

and then after

'}, {input: '\n```vb.net\nfenced code dot\n```\n\nand then after\n', expected: '
fenced code dot\n
\n\n\n

and then after

'}, {input: 'Some text first\n* a\n* list \n* here\n\nand then after', expected: '

Some text first

\n
    \n
  • a
  • \n
  • list
  • \n
  • here
  • \n
\n

and then after

'}, {input: '1. an\n2. ordered \n3. list', expected: '

1. an

\n

2. ordered

\n

3. list

'}, {input: '\n~~~quote\nquote this for me\n~~~\nthanks\n', expected: '
\n

quote this for me

\n
\n

thanks

'}, {input: 'This is a @**Cordelia Lear** mention', expected: '

This is a @Cordelia Lear mention

'}, {input: 'These @ @**** are not mentions', expected: '

These @ @** are not mentions

'}, {input: 'These # #**** are not mentions', expected: '

These # #** are not mentions

'}, {input: 'These @* @*** are not mentions', expected: '

These @* @*** are not mentions

'}, {input: 'These #* #*** are also not mentions', expected: '

These #* #*** are also not mentions

'}, {input: 'This is a #**Denmark** stream link', expected: '

This is a #Denmark stream link

'}, {input: 'This is #**Denmark** and #**social** stream links', expected: '

This is #Denmark and #social stream links

'}, {input: 'And this is a #**wrong** stream link', expected: '

And this is a #**wrong** stream link

'}, {input: 'mmm...:burrito:s', expected: '

mmm...:burrito:s

'}, {input: 'This is an :poop: message', expected: '

This is an :poop: message

'}, {input: "\ud83d\udca9", expected: '

:poop:

'}, {input: '\u{1f937}', expected: '

\u{1f937}

' }, {input: 'This is a realm filter #1234 with text after it', expected: '

This is a realm filter #1234 with text after it

'}, {input: 'This is a realm filter with ZGROUP_123:45 groups', expected: '

This is a realm filter with ZGROUP_123:45 groups

'}, {input: 'This is an !avatar(cordelia@zulip.com) of Cordelia Lear', expected: '

This is an cordelia@zulip.com of Cordelia Lear

'}, {input: 'This is a !gravatar(cordelia@zulip.com) of Cordelia Lear', expected: '

This is a cordelia@zulip.com of Cordelia Lear

'}, {input: 'Test *italic*', expected: '

Test italic

'}, ]; // We remove one of the unicode emoji we put as input in one of the test // cases (U+1F937), to verify that we display the emoji as it was input if it // isn't present in emoji.emojis_by_unicode. delete emoji.emojis_by_unicode['1f937']; test_cases.forEach(function (test_case) { var input = test_case.input; var expected = test_case.expected; var message = {raw_content: input}; markdown.apply_markdown(message); var output = message.content; assert.equal(expected, output); }); }()); (function test_subject_links() { var message = {type: 'stream', subject: "No links here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, []); message = {type: 'stream', subject: "One #123 link here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 1); assert.equal(message.subject_links[0], "https://trac.zulip.net/ticket/123"); message = {type: 'stream', subject: "Two #123 #456 link here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 2); assert.equal(message.subject_links[0], "https://trac.zulip.net/ticket/123"); assert.equal(message.subject_links[1], "https://trac.zulip.net/ticket/456"); message = {type: 'stream', subject: "New ZBUG_123 link here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 1); assert.equal(message.subject_links[0], "https://trac2.zulip.net/ticket/123"); message = {type: 'stream', subject: "New ZBUG_123 with #456 link here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 2); assert(message.subject_links.indexOf("https://trac2.zulip.net/ticket/123") !== -1); assert(message.subject_links.indexOf("https://trac.zulip.net/ticket/456") !== -1); message = {type: 'stream', subject: "One ZGROUP_123:45 link here"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 1); assert.equal(message.subject_links[0], "https://zone_45.zulip.net/ticket/123"); message = {type: "not-stream"}; markdown.add_subject_links(message); assert.equal(message.subject_links.length, 0); }()); (function test_message_flags() { var input = "/me is testing this"; var message = {subject: "No links here", raw_content: input}; message.flags = ['read']; markdown.apply_markdown(message); markdown.add_message_flags(message); assert.equal(message.flags.length, 2); assert(message.flags.indexOf('read') !== -1); assert(message.flags.indexOf('is_me_message') !== -1); input = "testing this @**all** @**Cordelia Lear**"; message = {subject: "No links here", raw_content: input}; markdown.apply_markdown(message); markdown.add_message_flags(message); assert.equal(message.flags.length, 1); assert(message.flags.indexOf('mentioned') !== -1); input = "test @all"; message = {subject: "No links here", raw_content: input}; markdown.apply_markdown(message); markdown.add_message_flags(message); assert.equal(message.flags.length, 1); assert(message.flags.indexOf('mentioned') !== -1); input = "test @any"; message = {subject: "No links here", raw_content: input}; markdown.apply_markdown(message); markdown.add_message_flags(message); assert.equal(message.flags.length, 0); assert(message.flags.indexOf('mentioned') === -1); }()); (function test_python_to_js_filter() { // The only way to reach python_to_js_filter is indirectly, hence the call // to set_realm_filters. markdown.set_realm_filters([[ '/a(?im)a/g'], [ '/a(?L)a/g' ]]); var actual_value = (marked.InlineLexer.rules.zulip.realm_filters); var expected_value = [ /\/aa\/g/gim, /\/aa\/g/g ]; assert.deepEqual(actual_value, expected_value); }()); (function test_katex_throws_unexpected_exceptions() { katex.renderToString = function () { throw new Error('some-exception'); }; var blueslip_error_called = false; blueslip.error = function (ex) { assert.equal(ex.message, 'some-exception'); blueslip_error_called = true; }; var message = { raw_content: '$$a$$' }; markdown.apply_markdown(message); assert(blueslip_error_called); }());