const noop = function () {}; set_global('$', global.make_zjquery()); set_global('page_params', { use_websockets: true, }); set_global('channel', {}); set_global('navigator', {}); set_global('reload', {}); set_global('reload_state', {}); set_global('socket', {}); set_global('Socket', function () { return global.socket; }); set_global('sent_messages', { start_tracking_message: noop, report_server_ack: noop, }); set_global('blueslip', global.make_zblueslip()); zrequire('people'); zrequire('util'); zrequire('transmit'); function test_with_mock_socket(test_params) { transmit.initialize(); let socket_send_called; const send_args = {}; global.socket.send = function (request, success, error) { global.socket.send = undefined; socket_send_called = true; // Save off args for check_send_args callback. send_args.request = request; send_args.success = success; send_args.error = error; }; // Run the actual code here. test_params.run_code(); assert(socket_send_called); test_params.check_send_args(send_args); } run_test('transmit_message_sockets', () => { page_params.use_websockets = true; global.navigator.userAgent = 'unittest_transmit_message'; // Our request is mostly unimportant, except that the // socket_user_agent field will be added. const request = {foo: 'bar'}; let success_func_checked = false; const success = function () { success_func_checked = true; }; // Our error function gets wrapped, so we set up a real // function to test the wrapping mechanism. let error_func_checked = false; const error = function (error_msg) { assert.equal(error_msg, 'Error sending message: simulated_error'); error_func_checked = true; }; test_with_mock_socket({ run_code: function () { transmit.send_message(request, success, error); }, check_send_args: function (send_args) { // The real code patches new data on the request, rather // than making a copy, so we test both that it didn't // clone the object and that it did add a field. assert.equal(send_args.request, request); assert.deepEqual(send_args.request, { foo: 'bar', socket_user_agent: 'unittest_transmit_message', }); send_args.success({}); assert(success_func_checked); // Our error function does get wrapped, so we test by // using socket.send's error callback, which should // invoke our test error function via a wrapper // function in the real code. send_args.error('response', {msg: 'simulated_error'}); assert(error_func_checked); }, }); }); page_params.use_websockets = false; run_test('transmit_message_ajax', () => { let success_func_called; const success = function () { success_func_called = true; }; const request = {foo: 'bar'}; channel.post = function (opts) { assert.equal(opts.url, '/json/messages'); assert.equal(opts.data.foo, 'bar'); opts.success(); }; transmit.send_message(request, success); assert(success_func_called); channel.xhr_error_message = function (msg) { assert.equal(msg, 'Error sending message'); return msg; }; channel.post = function (opts) { assert.equal(opts.url, '/json/messages'); assert.equal(opts.data.foo, 'bar'); const xhr = 'whatever'; opts.error(xhr, 'timeout'); }; let error_func_called; const error = function (response) { assert.equal(response, 'Error sending message'); error_func_called = true; }; transmit.send_message(request, success, error); assert(error_func_called); }); run_test('transmit_message_ajax_reload_pending', () => { const success = function () { throw 'unexpected success'; }; reload_state.is_pending = function () { return true; }; let reload_initiated; reload.initiate = function (opts) { reload_initiated = true; assert.deepEqual(opts, { immediate: true, save_pointer: true, save_narrow: true, save_compose: true, send_after_reload: true, }); }; const request = {foo: 'bar'}; let error_func_called; const error = function (response) { assert.equal(response, 'Error sending message'); error_func_called = true; }; error_func_called = false; channel.post = function (opts) { assert.equal(opts.url, '/json/messages'); assert.equal(opts.data.foo, 'bar'); const xhr = 'whatever'; opts.error(xhr, 'bad request'); }; transmit.send_message(request, success, error); assert(!error_func_called); assert(reload_initiated); }); run_test('reply_message_stream', () => { const stream_message = { type: 'stream', stream: 'social', topic: 'lunch', sender_full_name: 'Alice', sender_id: 123, }; const content = 'hello'; let send_message_args; transmit.send_message = (args) => { send_message_args = args; }; page_params.user_id = 44; page_params.queue_id = 66; sent_messages.get_new_local_id = () => 99; transmit.reply_message({ message: stream_message, content: content, }); assert.deepEqual(send_message_args, { sender_id: 44, queue_id: 66, local_id: 99, type: 'stream', to: 'social', content: '@**Alice** hello', topic: 'lunch', }); }); run_test('reply_message_private', () => { const fred = { user_id: 3, email: 'fred@example.com', full_name: 'Fred Frost', }; people.add(fred); people.is_my_user_id = () => false; const pm_message = { type: 'private', display_recipient: [ {id: fred.user_id}, ], }; const content = 'hello'; let send_message_args; transmit.send_message = (args) => { send_message_args = args; }; page_params.user_id = 155; page_params.queue_id = 177; sent_messages.get_new_local_id = () => 199; transmit.reply_message({ message: pm_message, content: content, }); assert.deepEqual(send_message_args, { sender_id: 155, queue_id: 177, local_id: 199, type: 'private', to: '["fred@example.com"]', content: 'hello', }); }); run_test('reply_message_errors', () => { const bogus_message = { type: 'bogus', }; blueslip.set_test_data('error', 'unknown message type: bogus'); transmit.reply_message({ message: bogus_message, }); blueslip.clear_test_data(); });