2020-08-01 03:43:15 +02:00
"use strict" ;
2020-07-16 22:40:18 +02:00
const { JSDOM } = require ( "jsdom" ) ;
2020-07-24 06:02:07 +02:00
const rewiremock = require ( "rewiremock/node" ) ;
2020-02-28 23:59:07 +01:00
2020-08-16 17:17:46 +02:00
const events = require ( "./lib/events.js" ) ;
2020-07-15 01:29:15 +02:00
set _global ( "bridge" , false ) ;
2018-08-01 21:17:03 +02:00
2019-11-02 00:06:25 +01:00
const noop = function ( ) { } ;
2018-08-01 21:17:03 +02:00
2020-07-15 01:29:15 +02:00
set _global ( "$" , global . make _zjquery ( ) ) ;
set _global ( "DOMParser" , new JSDOM ( ) . window . DOMParser ) ;
2017-02-24 16:18:56 +01:00
2020-07-15 01:29:15 +02:00
const LazySet = zrequire ( "lazy_set.js" ) . LazySet ;
2019-12-27 13:16:22 +01:00
2018-08-01 21:17:03 +02:00
const _navigator = {
2020-07-15 01:29:15 +02:00
platform : "" ,
2018-08-01 21:17:03 +02:00
} ;
2017-02-24 16:18:56 +01:00
2018-08-01 21:17:03 +02:00
const _document = {
2020-07-20 22:18:43 +02:00
getElementById ( ) {
2020-07-15 00:34:28 +02:00
return $ ( "#compose-textarea" ) ;
} ,
2020-07-20 22:18:43 +02:00
execCommand ( ) {
2020-07-15 00:34:28 +02:00
return false ;
} ,
2017-12-06 14:46:23 +01:00
location : { } ,
2018-08-01 21:17:03 +02:00
} ;
2017-06-27 14:55:11 +02:00
2018-08-01 21:17:03 +02:00
const _drafts = {
2017-06-29 06:54:10 +02:00
delete _draft _after _send : noop ,
2018-08-01 21:17:03 +02:00
} ;
2017-06-29 06:54:10 +02:00
2018-08-01 21:17:03 +02:00
const _sent _messages = {
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
start _tracking _message : noop ,
2018-08-01 21:17:03 +02:00
} ;
const _notifications = {
2018-01-04 21:31:23 +01:00
notify _above _composebox : noop ,
clear _compose _notifications : noop ,
2018-08-01 21:17:03 +02:00
} ;
const _reminder = {
2018-02-06 22:54:53 +01:00
is _deferred _delivery : noop ,
2018-08-01 21:17:03 +02:00
} ;
2020-07-15 01:29:15 +02:00
set _global ( "document" , _document ) ;
set _global ( "drafts" , _drafts ) ;
set _global ( "navigator" , _navigator ) ;
set _global ( "notifications" , _notifications ) ;
set _global ( "reminder" , _reminder ) ;
set _global ( "sent_messages" , _sent _messages ) ;
set _global ( "local_message" , { } ) ;
set _global ( "transmit" , { } ) ;
set _global ( "channel" , { } ) ;
set _global ( "stream_edit" , { } ) ;
set _global ( "markdown" , { } ) ;
set _global ( "loading" , { } ) ;
set _global ( "page_params" , { } ) ;
set _global ( "resize" , { } ) ;
set _global ( "subs" , { } ) ;
set _global ( "ui_util" , { } ) ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
2017-07-06 21:57:25 +02:00
// Setting these up so that we can test that links to uploads within messages are
// automatically converted to server relative links.
2020-07-15 01:29:15 +02:00
global . document . location . protocol = "https:" ;
global . document . location . host = "foo.com" ;
zrequire ( "zcommand" ) ;
zrequire ( "compose_ui" ) ;
const util = zrequire ( "util" ) ;
zrequire ( "rtl" ) ;
zrequire ( "common" ) ;
zrequire ( "stream_data" ) ;
zrequire ( "compose_state" ) ;
zrequire ( "people" ) ;
zrequire ( "input_pill" ) ;
zrequire ( "user_pill" ) ;
zrequire ( "compose_pm_pill" ) ;
zrequire ( "echo" ) ;
rewiremock . proxy ( ( ) => zrequire ( "compose" ) , {
2020-06-21 08:55:58 +02:00
"../../static/js/rendered_markdown" : {
update _elements : ( ) => { } ,
} ,
} ) ;
2020-07-15 01:29:15 +02:00
zrequire ( "upload" ) ;
zrequire ( "server_events_dispatch" ) ;
2017-02-24 16:18:56 +01:00
2018-06-27 20:55:56 +02:00
people . small _avatar _url _for _person = function ( ) {
2020-07-15 01:29:15 +02:00
return "http://example.com/example.png" ;
2018-06-27 20:55:56 +02:00
} ;
2020-04-08 00:23:15 +02:00
function stub _out _video _calls ( ) {
const elem = $ ( "#below-compose-content .video_link" ) ;
elem . toggle = ( show ) => {
if ( show ) {
elem . show ( ) ;
} else {
elem . hide ( ) ;
}
} ;
}
function reset _jquery ( ) {
// Avoid leaks.
2020-07-15 01:29:15 +02:00
set _global ( "$" , global . make _zjquery ( ) ) ;
2020-04-08 00:23:15 +02:00
}
2020-02-04 21:50:55 +01:00
const new _user = {
2020-07-15 01:29:15 +02:00
email : "new_user@example.com" ,
2020-02-04 21:50:55 +01:00
user _id : 101 ,
2020-07-15 01:29:15 +02:00
full _name : "New User" ,
2020-02-04 21:50:55 +01:00
date _joined : new Date ( ) ,
} ;
2019-11-02 00:06:25 +01:00
const me = {
2020-07-15 01:29:15 +02:00
email : "me@example.com" ,
2017-02-24 23:51:23 +01:00
user _id : 30 ,
2020-07-15 01:29:15 +02:00
full _name : "Me Myself" ,
2018-08-13 00:46:29 +02:00
date _joined : new Date ( ) ,
2017-02-24 23:51:23 +01:00
} ;
2019-11-02 00:06:25 +01:00
const alice = {
2020-07-15 01:29:15 +02:00
email : "alice@example.com" ,
2017-02-24 23:51:23 +01:00
user _id : 31 ,
2020-07-15 01:29:15 +02:00
full _name : "Alice" ,
2017-02-24 23:51:23 +01:00
} ;
2019-11-02 00:06:25 +01:00
const bob = {
2020-07-15 01:29:15 +02:00
email : "bob@example.com" ,
2017-02-24 23:51:23 +01:00
user _id : 32 ,
2020-07-15 01:29:15 +02:00
full _name : "Bob" ,
2017-02-24 23:51:23 +01:00
} ;
2020-05-26 22:34:15 +02:00
people . add _active _user ( new _user ) ;
people . add _active _user ( me ) ;
2017-02-24 23:51:23 +01:00
people . initialize _current _user ( me . user _id ) ;
2020-05-26 22:34:15 +02:00
people . add _active _user ( alice ) ;
people . add _active _user ( bob ) ;
2017-02-24 23:51:23 +01:00
2020-07-15 01:29:15 +02:00
run _test ( "validate_stream_message_address_info" , ( ) => {
2019-11-02 00:06:25 +01:00
const sub = {
2017-06-28 12:55:04 +02:00
stream _id : 101 ,
2020-07-15 01:29:15 +02:00
name : "social" ,
2017-06-28 12:55:04 +02:00
subscribed : true ,
} ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2020-07-15 01:29:15 +02:00
assert ( compose . validate _stream _message _address _info ( "social" ) ) ;
2017-06-28 13:10:46 +02:00
2017-06-28 19:24:53 +02:00
sub . subscribed = false ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2020-07-02 01:45:54 +02:00
global . stub _templates ( ( template _name ) => {
2020-07-15 01:29:15 +02:00
assert . equal ( template _name , "compose_not_subscribed" ) ;
return "compose_not_subscribed_stub" ;
2019-07-11 05:06:20 +02:00
} ) ;
2020-07-15 01:29:15 +02:00
assert ( ! compose . validate _stream _message _address _info ( "social" ) ) ;
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , "compose_not_subscribed_stub" ) ;
2017-06-28 19:24:53 +02:00
2018-08-01 21:17:03 +02:00
page _params . narrow _stream = false ;
2017-06-28 19:24:53 +02:00
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . data . stream , "social" ) ;
2017-06-28 19:24:53 +02:00
payload . data . subscribed = true ;
payload . success ( payload . data ) ;
} ;
2020-07-15 01:29:15 +02:00
assert ( compose . validate _stream _message _address _info ( "social" ) ) ;
2017-06-28 19:24:53 +02:00
2020-07-15 01:29:15 +02:00
sub . name = "Frontend" ;
2017-06-28 19:24:53 +02:00
sub . stream _id = 102 ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2017-06-28 19:24:53 +02:00
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . data . stream , "Frontend" ) ;
2017-06-28 19:24:53 +02:00
payload . data . subscribed = false ;
payload . success ( payload . data ) ;
} ;
2020-07-15 01:29:15 +02:00
assert ( ! compose . validate _stream _message _address _info ( "Frontend" ) ) ;
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , "compose_not_subscribed_stub" ) ;
2017-06-28 19:24:53 +02:00
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . data . stream , "Frontend" ) ;
2017-06-28 19:24:53 +02:00
payload . error ( { status : 404 } ) ;
} ;
2020-07-15 01:29:15 +02:00
assert ( ! compose . validate _stream _message _address _info ( "Frontend" ) ) ;
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
"translated: <p>The stream <b>Frontend</b> does not exist.</p><p>Manage your subscriptions <a href='#streams/all'>on your Streams page</a>.</p>" ,
) ;
2017-06-28 19:24:53 +02:00
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . data . stream , "social" ) ;
2017-06-28 19:24:53 +02:00
payload . error ( { status : 500 } ) ;
} ;
2020-07-15 01:29:15 +02:00
assert ( ! compose . validate _stream _message _address _info ( "social" ) ) ;
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "Error checking subscription" ) ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-02-24 23:51:23 +01:00
2020-07-15 01:29:15 +02:00
run _test ( "validate" , ( ) => {
2018-03-06 15:07:55 +01:00
function initialize _pm _pill ( ) {
2020-07-15 01:29:15 +02:00
set _global ( "$" , global . make _zjquery ( ) ) ;
2018-03-06 15:07:55 +01:00
2020-07-15 01:29:15 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , false ) ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-send-button" ) . trigger ( "focus" ) ;
2018-03-06 15:07:55 +01:00
$ ( "#sending-indicator" ) . hide ( ) ;
2020-07-15 01:29:15 +02:00
const pm _pill _container = $ . create ( "fake-pm-pill-container" ) ;
2020-08-01 03:56:10 +02:00
$ ( "#private_message_recipient" ) [ 0 ] = { } ;
2020-07-15 01:29:15 +02:00
$ ( "#private_message_recipient" ) . set _parent ( pm _pill _container ) ;
pm _pill _container . set _find _results ( ".input" , $ ( "#private_message_recipient" ) ) ;
$ ( "#private_message_recipient" ) . before = noop ;
2018-03-06 15:07:55 +01:00
compose _pm _pill . initialize ( ) ;
2018-08-01 21:17:03 +02:00
ui _util . place _caret _at _end = noop ;
2018-03-06 15:07:55 +01:00
$ ( "#zephyr-mirror-error" ) . is = noop ;
2018-03-31 13:22:29 +02:00
2020-07-02 01:45:54 +02:00
global . stub _templates ( ( fn ) => {
2020-07-15 01:29:15 +02:00
assert . equal ( fn , "input_pill" ) ;
return "<div>pill-html</div>" ;
2019-07-11 05:06:20 +02:00
} ) ;
2018-03-06 15:07:55 +01:00
}
function add _content _to _compose _box ( ) {
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "foobarfoobar" ) ;
2018-03-06 15:07:55 +01:00
}
initialize _pm _pill ( ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
assert ( ! $ ( "#sending-indicator" ) . visible ( ) ) ;
assert ( ! $ ( "#compose-send-button" ) . is _focused ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "You have nothing to send!" ) ) ;
2017-06-27 14:55:11 +02:00
2018-07-26 09:46:10 +02:00
reminder . is _deferred _delivery = ( ) => true ;
compose . validate ( ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#sending-indicator" ) . text ( ) , "translated: Scheduling..." ) ;
2018-07-26 09:46:10 +02:00
reminder . is _deferred _delivery = noop ;
2018-03-06 15:07:55 +01:00
add _content _to _compose _box ( ) ;
2019-11-02 00:06:25 +01:00
let zephyr _checked = false ;
2017-06-27 14:55:11 +02:00
$ ( "#zephyr-mirror-error" ) . is = function ( ) {
if ( ! zephyr _checked ) {
zephyr _checked = true ;
return true ;
}
return false ;
} ;
assert ( ! compose . validate ( ) ) ;
assert ( zephyr _checked ) ;
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
i18n . t ( "You need to be running Zephyr mirroring in order to send messages!" ) ,
) ;
2017-06-27 14:55:11 +02:00
2018-03-06 15:07:55 +01:00
initialize _pm _pill ( ) ;
add _content _to _compose _box ( ) ;
2018-07-23 08:19:48 +02:00
// test validating private messages
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "private" ) ;
2018-07-23 08:19:48 +02:00
2020-07-15 01:29:15 +02:00
compose _state . private _message _recipient ( "" ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
i18n . t ( "Please specify at least one valid recipient" ) ,
) ;
2017-06-27 14:55:11 +02:00
2018-03-06 15:07:55 +01:00
initialize _pm _pill ( ) ;
add _content _to _compose _box ( ) ;
2020-07-15 01:29:15 +02:00
compose _state . private _message _recipient ( "foo@zulip.com" ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
2018-03-06 15:07:55 +01:00
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
i18n . t ( "Please specify at least one valid recipient" , { } ) ,
) ;
2017-06-27 14:55:11 +02:00
2020-07-15 01:29:15 +02:00
compose _state . private _message _recipient ( "foo@zulip.com,alice@zulip.com" ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
2018-03-06 15:07:55 +01:00
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
i18n . t ( "Please specify at least one valid recipient" , { } ) ,
) ;
2017-06-27 14:55:11 +02:00
2020-05-26 22:34:15 +02:00
people . add _active _user ( bob ) ;
2020-07-15 01:29:15 +02:00
compose _state . private _message _recipient ( "bob@example.com" ) ;
2017-06-27 14:55:11 +02:00
assert ( compose . validate ( ) ) ;
2018-07-23 08:19:48 +02:00
page _params . realm _is _zephyr _mirror _realm = true ;
assert ( compose . validate ( ) ) ;
page _params . realm _is _zephyr _mirror _realm = false ;
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "stream" ) ;
compose _state . stream _name ( "" ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "Please specify a stream" ) ) ;
2017-06-27 14:55:11 +02:00
2020-07-15 01:29:15 +02:00
compose _state . stream _name ( "Denmark" ) ;
2018-08-01 21:17:03 +02:00
page _params . realm _mandatory _topics = true ;
2020-07-15 01:29:15 +02:00
compose _state . topic ( "" ) ;
2017-06-27 14:55:11 +02:00
assert ( ! compose . validate ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "Please specify a topic" ) ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-06-27 14:55:11 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "get_invalid_recipient_emails" , ( ) => {
2020-01-18 08:56:19 +01:00
const welcome _bot = {
2020-07-15 01:29:15 +02:00
email : "welcome-bot@example.com" ,
2017-06-28 21:36:57 +02:00
user _id : 124 ,
2020-07-15 01:29:15 +02:00
full _name : "Welcome Bot" ,
2017-06-28 21:36:57 +02:00
} ;
2020-02-25 12:16:26 +01:00
2018-08-01 21:17:03 +02:00
page _params . user _id = 30 ;
2020-02-25 12:16:26 +01:00
const params = { } ;
params . realm _users = [ ] ;
params . realm _non _active _users = [ ] ;
params . cross _realm _bots = [ welcome _bot ] ;
people . initialize ( page _params . user _id , params ) ;
2020-07-15 01:29:15 +02:00
compose _state . private _message _recipient ( "welcome-bot@example.com" ) ;
2017-06-28 21:36:57 +02:00
assert . deepEqual ( compose . get _invalid _recipient _emails ( ) , [ ] ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-06-28 21:36:57 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "validate_stream_message" , ( ) => {
2017-06-28 20:28:18 +02:00
// This test is in kind of continuation to test_validate but since it is
2017-11-09 16:26:38 +01:00
// primarily used to get coverage over functions called from validate()
// we are separating it up in different test. Though their relative position
2017-06-28 20:28:18 +02:00
// of execution should not be changed.
2018-08-01 21:17:03 +02:00
page _params . realm _mandatory _topics = false ;
2019-11-02 00:06:25 +01:00
const sub = {
2017-06-28 20:28:18 +02:00
stream _id : 101 ,
2020-07-15 01:29:15 +02:00
name : "social" ,
2017-06-28 20:28:18 +02:00
subscribed : true ,
} ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2020-07-15 01:29:15 +02:00
compose _state . stream _name ( "social" ) ;
2017-06-28 20:28:18 +02:00
assert ( compose . validate ( ) ) ;
assert ( ! $ ( "#compose-all-everyone" ) . visible ( ) ) ;
2017-11-26 19:58:36 +01:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2017-06-28 20:28:18 +02:00
2020-07-06 12:36:55 +02:00
stream _data . get _subscriber _count = function ( stream _id ) {
assert . equal ( stream _id , 101 ) ;
2017-06-28 20:28:18 +02:00
return 16 ;
} ;
2020-07-02 01:45:54 +02:00
global . stub _templates ( ( template _name , data ) => {
2020-07-15 01:29:15 +02:00
assert . equal ( template _name , "compose_all_everyone" ) ;
2017-06-28 20:28:18 +02:00
assert . equal ( data . count , 16 ) ;
2020-07-15 01:29:15 +02:00
return "compose_all_everyone_stub" ;
2019-07-11 05:06:20 +02:00
} ) ;
2019-11-02 00:06:25 +01:00
let compose _content ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-all-everyone" ) . append = function ( data ) {
2017-06-28 20:28:18 +02:00
compose _content = data ;
} ;
2020-07-15 01:29:15 +02:00
compose _state . message _content ( "Hey @**all**" ) ;
2017-06-28 20:28:18 +02:00
assert ( ! compose . validate ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
2017-11-26 19:58:36 +01:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( compose _content , "compose_all_everyone_stub" ) ;
2017-06-28 20:28:18 +02:00
assert ( $ ( "#compose-all-everyone" ) . visible ( ) ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-06-28 20:28:18 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "test_validate_stream_message_post_policy" , ( ) => {
2020-03-28 01:25:56 +01:00
// This test is in continuation with test_validate but it has been separated out
// for better readability. Their relative position of execution should not be changed.
2018-05-14 12:06:56 +02:00
// Although the position with respect to test_validate_stream_message does not matter
2020-07-06 12:36:55 +02:00
// as different stream is used for this test.
2018-08-01 21:17:03 +02:00
page _params . is _admin = false ;
2019-11-02 00:06:25 +01:00
const sub = {
2018-05-14 12:06:56 +02:00
stream _id : 102 ,
2020-07-15 01:29:15 +02:00
name : "stream102" ,
2018-05-14 12:06:56 +02:00
subscribed : true ,
2020-02-04 21:50:55 +01:00
stream _post _policy : stream _data . stream _post _policy _values . admins . code ,
2018-05-14 12:06:56 +02:00
} ;
2020-07-06 12:36:55 +02:00
2020-07-15 01:29:15 +02:00
compose _state . topic ( "subject102" ) ;
compose _state . stream _name ( "stream102" ) ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2018-05-14 12:06:56 +02:00
assert ( ! compose . validate ( ) ) ;
2020-07-15 00:34:28 +02:00
assert . equal (
$ ( "#compose-error-msg" ) . html ( ) ,
i18n . t ( "Only organization admins are allowed to post to this stream." ) ,
) ;
2018-05-14 12:06:56 +02:00
2020-07-06 12:36:55 +02:00
// reset compose_state.stream_name to 'social' again so that any tests occurung after this
2018-05-14 12:06:56 +02:00
// do not reproduce this error.
2020-07-15 01:29:15 +02:00
compose _state . stream _name ( "social" ) ;
2018-05-14 12:06:56 +02:00
} ) ;
2020-07-15 01:29:15 +02:00
run _test ( "markdown_rtl" , ( ) => {
const textarea = $ ( "#compose-textarea" ) ;
2018-07-11 14:07:26 +02:00
2019-11-02 00:06:25 +01:00
const event = {
2020-07-16 23:29:01 +02:00
keyCode : 65 , // A
2018-07-11 14:07:26 +02:00
} ;
rtl . get _direction = ( text ) => {
2020-07-15 01:29:15 +02:00
assert . equal ( text , " foo" ) ;
return "rtl" ;
2018-07-11 14:07:26 +02:00
} ;
2020-07-15 01:29:15 +02:00
assert . equal ( textarea . hasClass ( "rtl" ) , false ) ;
2018-07-11 14:07:26 +02:00
2020-07-15 01:29:15 +02:00
textarea . val ( "```quote foo" ) ;
2018-08-11 06:43:38 +02:00
compose . handle _keyup ( event , $ ( "#compose-textarea" ) ) ;
2018-07-11 14:07:26 +02:00
2020-07-15 01:29:15 +02:00
assert . equal ( textarea . hasClass ( "rtl" ) , true ) ;
2018-07-11 14:07:26 +02:00
} ) ;
// This is important for subsequent tests--put
// us back to the "normal" ltr case.
2020-07-15 01:29:15 +02:00
rtl . get _direction = ( ) => "ltr" ;
2018-07-11 14:07:26 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "markdown_ltr" , ( ) => {
const textarea = $ ( "#compose-textarea" ) ;
2018-07-11 14:07:26 +02:00
2019-11-02 00:06:25 +01:00
const event = {
2020-07-16 23:29:01 +02:00
keyCode : 65 , // A
2018-07-11 14:07:26 +02:00
} ;
2020-07-15 01:29:15 +02:00
assert . equal ( textarea . hasClass ( "rtl" ) , true ) ;
textarea . val ( "```quote foo" ) ;
2018-08-11 06:43:38 +02:00
compose . handle _keyup ( event , textarea ) ;
2018-07-11 14:07:26 +02:00
2020-07-15 01:29:15 +02:00
assert . equal ( textarea . hasClass ( "rtl" ) , false ) ;
2018-07-11 14:07:26 +02:00
} ) ;
2020-07-15 01:29:15 +02:00
run _test ( "markdown_shortcuts" , ( ) => {
2019-11-02 00:06:25 +01:00
let queryCommandEnabled = true ;
const event = {
2017-12-06 14:46:23 +01:00
keyCode : 66 ,
target : {
2020-07-15 01:29:15 +02:00
id : "compose-textarea" ,
2017-12-06 14:46:23 +01:00
} ,
stopPropagation : noop ,
preventDefault : noop ,
} ;
2019-11-02 00:06:25 +01:00
let input _text = "" ;
let range _start = 0 ;
let range _length = 0 ;
let compose _value = $ ( "#compose_textarea" ) . val ( ) ;
let selected _word = "" ;
2017-12-06 14:46:23 +01:00
global . document . queryCommandEnabled = function ( ) {
return queryCommandEnabled ;
} ;
global . document . execCommand = function ( cmd , bool , markdown ) {
2019-11-02 00:06:25 +01:00
const compose _textarea = $ ( "#compose-textarea" ) ;
const value = compose _textarea . val ( ) ;
2020-07-15 00:34:28 +02:00
$ ( "#compose-textarea" ) . val (
value . substring ( 0 , compose _textarea . range ( ) . start ) +
markdown +
value . substring ( compose _textarea . range ( ) . end , value . length ) ,
) ;
2017-12-06 14:46:23 +01:00
} ;
$ ( "#compose-textarea" ) . range = function ( ) {
return {
start : range _start ,
end : range _start + range _length ,
length : range _length ,
range : noop ,
2020-07-15 00:34:28 +02:00
text : $ ( "#compose-textarea" )
. val ( )
. substring ( range _start , range _length + range _start ) ,
2017-12-06 14:46:23 +01:00
} ;
} ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . caret = noop ;
2017-12-06 14:46:23 +01:00
2018-02-17 17:21:45 +01:00
function test _i _typed ( isCtrl , isCmd ) {
// Test 'i' is typed correctly.
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "i" ) ;
2018-02-17 17:21:45 +01:00
event . keyCode = undefined ;
event . which = 73 ;
event . metaKey = isCmd ;
event . ctrlKey = isCtrl ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "i" , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
}
function all _markdown _test ( isCtrl , isCmd ) {
input _text = "Any text." ;
$ ( "#compose-textarea" ) . val ( input _text ) ;
compose _value = $ ( "#compose-textarea" ) . val ( ) ;
// Select "text" word in compose box.
selected _word = "text" ;
range _start = compose _value . search ( selected _word ) ;
range _length = selected _word . length ;
// Test bold:
2020-08-11 02:09:14 +02:00
// Mac env = Cmd+b
// Windows/Linux = Ctrl+b
2018-02-17 17:21:45 +01:00
event . keyCode = 66 ;
event . ctrlKey = isCtrl ;
event . metaKey = isCmd ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "Any **text**." , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
// Test if no text is selected.
range _start = 0 ;
// Change cursor to first position.
range _length = 0 ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "****Any **text**." , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
// Test italic:
2020-08-11 02:09:14 +02:00
// Mac = Cmd+I
// Windows/Linux = Ctrl+I
2018-02-17 17:21:45 +01:00
$ ( "#compose-textarea" ) . val ( input _text ) ;
range _start = compose _value . search ( selected _word ) ;
range _length = selected _word . length ;
event . keyCode = 73 ;
event . shiftKey = false ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "Any *text*." , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
// Test if no text is selected.
range _length = 0 ;
// Change cursor to first position.
range _start = 0 ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "**Any *text*." , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
// Test link insertion:
2020-08-11 02:09:14 +02:00
// Mac = Cmd+Shift+L
// Windows/Linux = Ctrl+Shift+L
2018-02-17 17:21:45 +01:00
$ ( "#compose-textarea" ) . val ( input _text ) ;
range _start = compose _value . search ( selected _word ) ;
range _length = selected _word . length ;
event . keyCode = 76 ;
event . which = undefined ;
event . shiftKey = true ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( "Any [text](url)." , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
// Test if exec command is not enabled in browser.
queryCommandEnabled = false ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2018-02-17 17:21:45 +01:00
}
2020-08-11 02:09:14 +02:00
// This function cross tests the Cmd/Ctrl + Markdown shortcuts in
2018-02-17 17:21:45 +01:00
// Mac and Linux/Windows environments. So in short, this tests
// that e.g. Cmd+B should be ignored on Linux/Windows and Ctrl+B
// should be ignored on Mac.
function os _specific _markdown _test ( isCtrl , isCmd ) {
input _text = "Any text." ;
$ ( "#compose-textarea" ) . val ( input _text ) ;
compose _value = $ ( "#compose-textarea" ) . val ( ) ;
selected _word = "text" ;
range _start = compose _value . search ( selected _word ) ;
range _length = selected _word . length ;
event . metaKey = isCmd ;
event . ctrlKey = isCtrl ;
event . keyCode = 66 ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( input _text , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
event . keyCode = 73 ;
event . shiftKey = false ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( input _text , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
event . keyCode = 76 ;
event . shiftKey = true ;
2018-07-18 05:59:55 +02:00
compose . handle _keydown ( event , $ ( "#compose-textarea" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( input _text , $ ( "#compose-textarea" ) . val ( ) ) ;
2018-02-17 17:21:45 +01:00
}
// These keyboard shortcuts differ as to what key one should use
// on MacOS vs. other platforms: Cmd (Mac) vs. Ctrl (non-Mac).
// Default (Linux/Windows) userAgent tests:
test _i _typed ( false , false ) ;
2020-08-11 02:09:14 +02:00
// Check all the Ctrl + Markdown shortcuts work correctly
2018-02-17 17:21:45 +01:00
all _markdown _test ( true , false ) ;
2020-08-11 01:47:49 +02:00
// The Cmd + Markdown shortcuts should do nothing on Linux/Windows
2018-02-17 17:21:45 +01:00
os _specific _markdown _test ( false , true ) ;
2019-06-24 14:11:21 +02:00
// Setting following platform to test in mac env
_navigator . platform = "MacIntel" ;
2018-02-17 17:21:45 +01:00
// Mac userAgent tests:
test _i _typed ( false , false ) ;
2020-08-11 02:09:14 +02:00
// The Ctrl + Markdown shortcuts should do nothing on mac
2018-02-17 17:21:45 +01:00
os _specific _markdown _test ( true , false ) ;
2020-08-11 01:47:49 +02:00
// Check all the Cmd + Markdown shortcuts work correctly
2018-02-17 17:21:45 +01:00
all _markdown _test ( false , true ) ;
// Reset userAgent
2018-08-01 21:17:03 +02:00
_navigator . userAgent = "" ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-12-06 14:46:23 +01:00
2020-07-15 01:29:15 +02:00
run _test ( "send_message_success" , ( ) => {
$ ( "#compose-textarea" ) . val ( "foobarfoobar" ) ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-textarea" ) . trigger ( "blur" ) ;
2017-11-26 19:58:36 +01:00
$ ( "#compose-send-status" ) . show ( ) ;
2020-07-22 02:59:06 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , true ) ;
2017-06-29 06:54:10 +02:00
$ ( "#sending-indicator" ) . show ( ) ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
2019-11-02 00:06:25 +01:00
let reify _message _id _checked ;
2017-06-29 06:54:10 +02:00
echo . reify _message _id = function ( local _id , message _id ) {
2020-02-12 09:32:25 +01:00
assert . equal ( local _id , "1001" ) ;
2017-06-29 06:54:10 +02:00
assert . equal ( message _id , 12 ) ;
reify _message _id _checked = true ;
} ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
2020-02-12 09:32:25 +01:00
compose . send _message _success ( "1001" , 12 , false ) ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-textarea" ) . val ( ) , "" ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . is _focused ( ) ) ;
2017-11-26 19:58:36 +01:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
2017-06-29 06:54:10 +02:00
assert ( ! $ ( "#sending-indicator" ) . visible ( ) ) ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
assert ( reify _message _id _checked ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-06-29 14:31:26 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "send_message" , ( ) => {
2017-07-06 21:57:25 +02:00
// This is the common setup stuff for all of the four tests.
2019-11-02 00:06:25 +01:00
let stub _state ;
2017-07-06 21:57:25 +02:00
function initialize _state _stub _dict ( ) {
stub _state = { } ;
2018-02-20 13:08:50 +01:00
stub _state . send _msg _called = 0 ;
2017-07-06 21:57:25 +02:00
stub _state . get _events _running _called = 0 ;
stub _state . reify _message _id _checked = 0 ;
return stub _state ;
}
2020-07-15 01:29:15 +02:00
global . patch _builtin ( "setTimeout" , ( func ) => {
2017-07-06 21:57:25 +02:00
func ( ) ;
} ) ;
global . server _events = {
2020-07-20 22:18:43 +02:00
assert _get _events _running ( ) {
2017-07-06 21:57:25 +02:00
stub _state . get _events _running _called += 1 ;
} ,
} ;
// Tests start here.
( function test _message _send _success _codepath ( ) {
stub _state = initialize _state _stub _dict ( ) ;
2020-07-15 01:29:15 +02:00
compose _state . topic ( "" ) ;
compose _state . set _message _type ( "private" ) ;
2017-07-06 21:57:25 +02:00
page _params . user _id = 101 ;
2019-12-02 17:53:55 +01:00
compose _state . private _message _recipient = function ( ) {
2020-07-15 01:29:15 +02:00
return "alice@example.com" ;
2018-03-31 13:22:29 +02:00
} ;
2020-04-09 19:55:20 +02:00
const server _message _id = 127 ;
2020-04-09 17:59:58 +02:00
const fake _now = 555 ;
local _message . insert _message = ( message ) => {
assert . equal ( message . timestamp , fake _now ) ;
} ;
local _message . now = ( ) => fake _now ;
2020-04-09 19:55:20 +02:00
2020-04-09 17:59:58 +02:00
markdown . apply _markdown = ( ) => { } ;
markdown . add _topic _links = ( ) => { } ;
echo . try _deliver _locally = function ( message _request ) {
2020-04-09 19:55:20 +02:00
const local _id _float = 123.04 ;
2020-04-09 17:59:58 +02:00
return echo . insert _local _message ( message _request , local _id _float ) ;
2017-07-06 21:57:25 +02:00
} ;
2018-02-20 13:08:50 +01:00
transmit . send _message = function ( payload , success ) {
2019-11-02 00:06:25 +01:00
const single _msg = {
2020-07-15 01:29:15 +02:00
type : "private" ,
content : "[foobar](/user_uploads/123456)" ,
2018-05-07 03:30:13 +02:00
sender _id : 101 ,
queue _id : undefined ,
2020-07-15 01:29:15 +02:00
stream : "" ,
topic : "" ,
2019-05-23 22:18:58 +02:00
to : ` [ ${ alice . user _id } ] ` ,
2020-07-15 01:29:15 +02:00
reply _to : "alice@example.com" ,
private _message _recipient : "alice@example.com" ,
to _user _ids : "31" ,
local _id : "123.04" ,
2018-05-07 03:30:13 +02:00
locally _echoed : true ,
2017-07-06 21:57:25 +02:00
} ;
2019-05-23 22:18:58 +02:00
2018-02-20 13:08:50 +01:00
assert . deepEqual ( payload , single _msg ) ;
2020-04-09 19:55:20 +02:00
payload . id = server _message _id ;
2018-02-20 13:08:50 +01:00
success ( payload ) ;
stub _state . send _msg _called += 1 ;
2017-07-06 21:57:25 +02:00
} ;
echo . reify _message _id = function ( local _id , message _id ) {
2020-07-15 01:29:15 +02:00
assert . equal ( typeof local _id , "string" ) ;
assert . equal ( typeof message _id , "number" ) ;
2020-04-09 19:55:20 +02:00
assert . equal ( message _id , server _message _id ) ;
2017-07-06 21:57:25 +02:00
stub _state . reify _message _id _checked += 1 ;
} ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
2017-07-06 21:57:25 +02:00
// Setting message content with a host server link and we will assert
// later that this has been converted to a relative link.
2020-07-15 00:34:28 +02:00
$ ( "#compose-textarea" ) . val ( "[foobar]" + "(https://foo.com/user_uploads/123456)" ) ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-textarea" ) . trigger ( "blur" ) ;
2017-11-26 19:58:36 +01:00
$ ( "#compose-send-status" ) . show ( ) ;
2020-07-22 02:59:06 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , true ) ;
2017-07-06 21:57:25 +02:00
$ ( "#sending-indicator" ) . show ( ) ;
compose . send _message ( ) ;
2019-11-02 00:06:25 +01:00
const state = {
2017-07-06 21:57:25 +02:00
get _events _running _called : 1 ,
reify _message _id _checked : 1 ,
2018-02-20 13:08:50 +01:00
send _msg _called : 1 ,
2017-07-06 21:57:25 +02:00
} ;
assert . deepEqual ( stub _state , state ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-textarea" ) . val ( ) , "" ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . is _focused ( ) ) ;
2017-11-26 19:58:36 +01:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
2017-07-06 21:57:25 +02:00
assert ( ! $ ( "#sending-indicator" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-06 21:57:25 +02:00
// This is the additional setup which is common to both the tests below.
2018-02-20 13:08:50 +01:00
transmit . send _message = function ( payload , success , error ) {
stub _state . send _msg _called += 1 ;
2020-07-15 01:29:15 +02:00
error ( "Error sending message: Server says 408" ) ;
2017-07-06 21:57:25 +02:00
} ;
2018-02-20 13:08:50 +01:00
2019-11-02 00:06:25 +01:00
let echo _error _msg _checked ;
2018-02-20 13:08:50 +01:00
2017-07-06 21:57:25 +02:00
echo . message _send _error = function ( local _id , error _response ) {
2020-04-09 17:43:30 +02:00
assert . equal ( local _id , 123.04 ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( error _response , "Error sending message: Server says 408" ) ;
2017-07-06 21:57:25 +02:00
echo _error _msg _checked = true ;
} ;
// Tests start here.
( function test _param _error _function _passed _from _send _message ( ) {
stub _state = initialize _state _stub _dict ( ) ;
compose . send _message ( ) ;
2019-11-02 00:06:25 +01:00
const state = {
2017-07-06 21:57:25 +02:00
get _events _running _called : 1 ,
reify _message _id _checked : 0 ,
2018-02-20 13:08:50 +01:00
send _msg _called : 1 ,
2017-07-06 21:57:25 +02:00
} ;
assert . deepEqual ( stub _state , state ) ;
assert ( echo _error _msg _checked ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-06 21:57:25 +02:00
( function test _error _codepath _local _id _undefined ( ) {
stub _state = initialize _state _stub _dict ( ) ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "foobarfoobar" ) ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-textarea" ) . trigger ( "blur" ) ;
2017-11-26 19:58:36 +01:00
$ ( "#compose-send-status" ) . show ( ) ;
2020-07-22 02:59:06 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , true ) ;
2017-07-06 21:57:25 +02:00
$ ( "#sending-indicator" ) . show ( ) ;
2020-07-21 09:44:41 +02:00
$ ( "#compose-textarea" ) . off ( "select" ) ;
2017-07-06 21:57:25 +02:00
echo _error _msg _checked = false ;
echo . try _deliver _locally = function ( ) {
return ;
} ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
sent _messages . get _new _local _id = function ( ) {
2020-07-15 01:29:15 +02:00
return "loc-55" ;
sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
2017-07-30 12:56:46 +02:00
} ;
2017-07-06 21:57:25 +02:00
compose . send _message ( ) ;
2019-11-02 00:06:25 +01:00
const state = {
2017-07-06 21:57:25 +02:00
get _events _running _called : 1 ,
reify _message _id _checked : 0 ,
2018-02-20 13:08:50 +01:00
send _msg _called : 1 ,
2017-07-06 21:57:25 +02:00
} ;
assert . deepEqual ( stub _state , state ) ;
assert ( ! echo _error _msg _checked ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
2020-07-15 00:34:28 +02:00
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , "Error sending message: Server says 408" ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-textarea" ) . val ( ) , "foobarfoobar" ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . is _focused ( ) ) ;
2017-11-26 19:58:36 +01:00
assert ( $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
2017-07-06 21:57:25 +02:00
assert ( ! $ ( "#sending-indicator" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-06 21:57:25 +02:00
2020-07-15 01:29:15 +02:00
set _global ( "document" , "document-stub" ) ;
2018-04-12 18:06:39 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "enter_with_preview_open" , ( ) => {
2017-07-07 19:31:32 +02:00
// Test sending a message with content.
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "stream" ) ;
$ ( "#compose-textarea" ) . val ( "message me" ) ;
2017-11-26 20:37:44 +01:00
$ ( "#compose-textarea" ) . hide ( ) ;
2017-07-07 00:33:46 +02:00
$ ( "#undo_markdown_preview" ) . show ( ) ;
$ ( "#preview_message_area" ) . show ( ) ;
$ ( "#markdown_preview" ) . hide ( ) ;
page _params . enter _sends = true ;
2019-11-02 00:06:25 +01:00
let send _message _called = false ;
2017-07-07 00:33:46 +02:00
compose . send _message = function ( ) {
send _message _called = true ;
} ;
compose . enter _with _preview _open ( ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . visible ( ) ) ;
2017-07-07 00:33:46 +02:00
assert ( ! $ ( "#undo_markdown_preview" ) . visible ( ) ) ;
assert ( ! $ ( "#preview_message_area" ) . visible ( ) ) ;
assert ( $ ( "#markdown_preview" ) . visible ( ) ) ;
assert ( send _message _called ) ;
page _params . enter _sends = false ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-textarea" ) . trigger ( "blur" ) ;
2017-07-07 00:33:46 +02:00
compose . enter _with _preview _open ( ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . is _focused ( ) ) ;
2017-07-07 19:31:32 +02:00
// Test sending a message without content.
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "" ) ;
2017-07-07 19:31:32 +02:00
$ ( "#preview_message_area" ) . show ( ) ;
$ ( "#enter_sends" ) . prop ( "checked" , true ) ;
page _params . enter _sends = true ;
compose . enter _with _preview _open ( ) ;
assert ( $ ( "#enter_sends" ) . prop ( "checked" ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "You have nothing to send!" ) ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-07 00:33:46 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "finish" , ( ) => {
2017-07-07 00:48:51 +02:00
( function test _when _compose _validation _fails ( ) {
$ ( "#compose_invite_users" ) . show ( ) ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , false ) ;
2020-07-20 21:24:26 +02:00
$ ( "#compose-send-button" ) . trigger ( "focus" ) ;
2017-07-07 00:48:51 +02:00
$ ( "#sending-indicator" ) . hide ( ) ;
2020-07-21 09:44:41 +02:00
$ ( "#compose-textarea" ) . off ( "select" ) ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "" ) ;
2019-11-02 00:06:25 +01:00
const res = compose . finish ( ) ;
2017-07-07 00:48:51 +02:00
assert . equal ( res , false ) ;
assert ( ! $ ( "#compose_invite_users" ) . visible ( ) ) ;
assert ( ! $ ( "#sending-indicator" ) . visible ( ) ) ;
assert ( ! $ ( "#compose-send-button" ) . is _focused ( ) ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-send-button" ) . prop ( "disabled" ) , false ) ;
assert . equal ( $ ( "#compose-error-msg" ) . html ( ) , i18n . t ( "You have nothing to send!" ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-07 00:48:51 +02:00
( function test _when _compose _validation _succeed ( ) {
2017-11-26 20:37:44 +01:00
$ ( "#compose-textarea" ) . hide ( ) ;
2017-07-07 00:48:51 +02:00
$ ( "#undo_markdown_preview" ) . show ( ) ;
$ ( "#preview_message_area" ) . show ( ) ;
$ ( "#markdown_preview" ) . hide ( ) ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "foobarfoobar" ) ;
compose _state . set _message _type ( "private" ) ;
2019-12-02 17:53:55 +01:00
compose _state . private _message _recipient = function ( ) {
2020-07-15 01:29:15 +02:00
return "bob@example.com" ;
2018-03-31 13:22:29 +02:00
} ;
2019-11-02 00:06:25 +01:00
let compose _finished _event _checked = false ;
2020-07-21 05:53:07 +02:00
$ ( document ) . on ( "compose_finished.zulip" , ( ) => {
2018-04-12 18:06:39 +02:00
compose _finished _event _checked = true ;
2020-07-21 05:53:07 +02:00
} ) ;
2019-11-02 00:06:25 +01:00
let send _message _called = false ;
2017-07-07 00:48:51 +02:00
compose . send _message = function ( ) {
send _message _called = true ;
} ;
assert ( compose . finish ( ) ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . visible ( ) ) ;
2017-07-07 00:48:51 +02:00
assert ( ! $ ( "#undo_markdown_preview" ) . visible ( ) ) ;
assert ( ! $ ( "#preview_message_area" ) . visible ( ) ) ;
assert ( $ ( "#markdown_preview" ) . visible ( ) ) ;
assert ( send _message _called ) ;
assert ( compose _finished _event _checked ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-07 00:48:51 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "warn_if_private_stream_is_linked" , ( ) => {
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( {
name : compose _state . stream _name ( ) ,
2020-02-03 07:48:50 +01:00
subscribers : new LazySet ( [ 1 , 2 ] ) ,
2020-02-07 21:18:20 +01:00
stream _id : 99 ,
2020-01-14 15:57:16 +01:00
} ) ;
let denmark = {
2020-07-15 01:29:15 +02:00
name : "Denmark" ,
2020-02-03 07:48:50 +01:00
subscribers : new LazySet ( [ 1 , 2 , 3 ] ) ,
2020-01-14 15:57:16 +01:00
} ;
function test _noop _case ( invite _only ) {
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "stream" ) ;
2020-01-14 15:57:16 +01:00
denmark . invite _only = invite _only ;
compose . warn _if _private _stream _is _linked ( denmark ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_private_stream_alert" ) . visible ( ) , false ) ;
2020-01-14 15:57:16 +01:00
}
test _noop _case ( false ) ;
// invite_only=true and current compose stream subscribers are a subset
// of mentioned_stream subscribers.
test _noop _case ( true ) ;
$ ( "#compose_private" ) . hide ( ) ;
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "stream" ) ;
2020-01-14 15:57:16 +01:00
const checks = [
( function ( ) {
let called ;
2020-07-02 01:45:54 +02:00
global . stub _templates ( ( template _name , context ) => {
2020-01-14 15:57:16 +01:00
called = true ;
2020-07-15 01:29:15 +02:00
assert . equal ( template _name , "compose_private_stream_alert" ) ;
assert . equal ( context . stream _name , "Denmark" ) ;
return "fake-compose_private_stream_alert-template" ;
2020-01-14 15:57:16 +01:00
} ) ;
2020-07-15 00:34:28 +02:00
return function ( ) {
assert ( called ) ;
} ;
2020-07-16 22:35:58 +02:00
} ) ( ) ,
2020-01-14 15:57:16 +01:00
( function ( ) {
let called ;
$ ( "#compose_private_stream_alert" ) . append = function ( html ) {
called = true ;
2020-07-15 01:29:15 +02:00
assert . equal ( html , "fake-compose_private_stream_alert-template" ) ;
2020-01-14 15:57:16 +01:00
} ;
2020-07-15 00:34:28 +02:00
return function ( ) {
assert ( called ) ;
} ;
2020-07-16 22:35:58 +02:00
} ) ( ) ,
2020-01-14 15:57:16 +01:00
] ;
denmark = {
invite _only : true ,
2020-07-15 01:29:15 +02:00
name : "Denmark" ,
2020-02-03 07:48:50 +01:00
subscribers : new LazySet ( [ 1 ] ) ,
2020-01-14 15:57:16 +01:00
} ;
compose . warn _if _private _stream _is _linked ( denmark ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_private_stream_alert" ) . visible ( ) , true ) ;
2020-01-14 15:57:16 +01:00
2020-07-15 00:34:28 +02:00
for ( const f of checks ) {
f ( ) ;
}
2020-01-14 15:57:16 +01:00
} ) ;
2020-07-15 01:29:15 +02:00
run _test ( "initialize" , ( ) => {
2017-07-07 15:14:00 +02:00
// In this test we mostly do the setup stuff in addition to testing the
// normal workflow of the function. All the tests for the on functions are
// done in subsequent tests directly below this test.
2019-11-02 00:06:25 +01:00
let resize _watch _manual _resize _checked = false ;
2017-07-07 15:14:00 +02:00
resize . watch _manual _resize = function ( elem ) {
2020-07-15 01:29:15 +02:00
assert . equal ( "#compose-textarea" , elem ) ;
2017-07-07 15:14:00 +02:00
resize _watch _manual _resize _checked = true ;
} ;
2020-07-15 01:29:15 +02:00
set _global ( "bridge" , true ) ;
2019-11-02 00:06:25 +01:00
let xmlhttprequest _checked = false ;
2020-07-15 01:29:15 +02:00
set _global ( "XMLHttpRequest" , function ( ) {
2017-07-07 15:14:00 +02:00
this . upload = true ;
xmlhttprequest _checked = true ;
} ) ;
$ ( "#compose #attach_files" ) . addClass ( "notdisplayed" ) ;
2020-07-15 01:29:15 +02:00
global . document = "document-stub" ;
global . csrf _token = "fake-csrf-token" ;
2017-07-07 15:14:00 +02:00
2020-05-08 06:57:19 +02:00
page _params . max _file _upload _size _mib = 512 ;
2017-07-07 15:14:00 +02:00
2019-11-21 05:24:55 +01:00
let setup _upload _called = false ;
let uppy _cancel _all _called = false ;
upload . setup _upload = function ( config ) {
assert . equal ( config . mode , "compose" ) ;
setup _upload _called = true ;
return {
cancelAll : ( ) => {
uppy _cancel _all _called = true ;
} ,
} ;
2017-07-07 15:14:00 +02:00
} ;
2020-04-08 00:23:15 +02:00
page _params . realm _available _video _chat _providers = {
disabled : {
id : 0 ,
name : "disabled" ,
} ,
jitsi _meet : {
id : 1 ,
name : "Jitsi Meet" ,
} ,
zoom : {
id : 3 ,
name : "Zoom" ,
} ,
2020-04-27 22:41:31 +02:00
big _blue _button : {
id : 4 ,
name : "Big Blue Button" ,
} ,
2020-04-08 00:23:15 +02:00
} ;
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . disabled . id ;
stub _out _video _calls ( ) ;
2017-07-07 15:14:00 +02:00
compose . initialize ( ) ;
assert ( resize _watch _manual _resize _checked ) ;
assert ( xmlhttprequest _checked ) ;
assert ( ! $ ( "#compose #attach_files" ) . hasClass ( "notdisplayed" ) ) ;
2019-11-21 05:24:55 +01:00
assert ( setup _upload _called ) ;
2017-07-07 15:14:00 +02:00
2019-11-02 00:06:25 +01:00
let compose _actions _start _checked ;
2017-07-07 15:14:00 +02:00
function set _up _compose _start _mock ( expected _opts ) {
compose _actions _start _checked = false ;
global . compose _actions = {
2020-07-20 22:18:43 +02:00
start ( msg _type , opts ) {
2020-07-15 01:29:15 +02:00
assert . equal ( msg _type , "stream" ) ;
2017-07-07 15:14:00 +02:00
assert . deepEqual ( opts , expected _opts ) ;
compose _actions _start _checked = true ;
} ,
} ;
}
( function test _page _params _narrow _path ( ) {
page _params . narrow = true ;
reset _jquery ( ) ;
2020-04-08 00:23:15 +02:00
stub _out _video _calls ( ) ;
2017-07-07 15:14:00 +02:00
set _up _compose _start _mock ( { } ) ;
compose . initialize ( ) ;
assert ( compose _actions _start _checked ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-07 15:14:00 +02:00
( function test _page _params _narrow _topic ( ) {
2020-07-15 01:29:15 +02:00
page _params . narrow _topic = "testing" ;
2017-07-07 15:14:00 +02:00
reset _jquery ( ) ;
2020-04-08 00:23:15 +02:00
stub _out _video _calls ( ) ;
2020-07-15 01:29:15 +02:00
set _up _compose _start _mock ( { topic : "testing" } ) ;
2017-07-07 15:14:00 +02:00
compose . initialize ( ) ;
assert ( compose _actions _start _checked ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2019-11-21 05:24:55 +01:00
( function test _abort _xhr ( ) {
2020-07-22 02:59:06 +02:00
$ ( "#compose-send-button" ) . prop ( "disabled" , true ) ;
2019-11-21 05:24:55 +01:00
reset _jquery ( ) ;
2020-04-08 00:23:15 +02:00
stub _out _video _calls ( ) ;
2019-11-21 05:24:55 +01:00
compose . initialize ( ) ;
compose . abort _xhr ( ) ;
assert . equal ( $ ( "#compose-send-button" ) . attr ( ) , undefined ) ;
assert ( uppy _cancel _all _called ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-07 03:59:08 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "update_fade" , ( ) => {
2020-07-15 00:34:28 +02:00
const selector =
"#stream_message_recipient_stream,#stream_message_recipient_topic,#private_message_recipient" ;
2020-07-15 01:29:15 +02:00
const keyup _handler _func = $ ( selector ) . get _on _handler ( "keyup" ) ;
2017-07-07 15:41:13 +02:00
2019-11-02 00:06:25 +01:00
let set _focused _recipient _checked = false ;
let update _all _called = false ;
2017-07-07 15:41:13 +02:00
global . compose _fade = {
2020-07-20 22:18:43 +02:00
set _focused _recipient ( msg _type ) {
2020-07-15 01:29:15 +02:00
assert . equal ( msg _type , "private" ) ;
2017-07-07 15:41:13 +02:00
set _focused _recipient _checked = true ;
} ,
2020-07-20 22:18:43 +02:00
update _all ( ) {
2018-04-22 16:25:46 +02:00
update _all _called = true ;
2017-07-07 15:41:13 +02:00
} ,
} ;
compose _state . set _message _type ( false ) ;
keyup _handler _func ( ) ;
assert ( ! set _focused _recipient _checked ) ;
2018-04-22 16:25:46 +02:00
assert ( ! update _all _called ) ;
2017-07-07 15:41:13 +02:00
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "private" ) ;
2017-07-07 15:41:13 +02:00
keyup _handler _func ( ) ;
assert ( set _focused _recipient _checked ) ;
2018-04-22 16:25:46 +02:00
assert ( update _all _called ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-07 15:41:13 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "trigger_submit_compose_form" , ( ) => {
2019-11-02 00:06:25 +01:00
let prevent _default _checked = false ;
let compose _finish _checked = false ;
const e = {
2020-07-20 22:18:43 +02:00
preventDefault ( ) {
2017-07-07 15:42:51 +02:00
prevent _default _checked = true ;
} ,
} ;
compose . finish = function ( ) {
compose _finish _checked = true ;
} ;
2020-07-15 01:29:15 +02:00
const submit _handler = $ ( "#compose form" ) . get _on _handler ( "submit" ) ;
2017-07-07 15:42:51 +02:00
submit _handler ( e ) ;
assert ( prevent _default _checked ) ;
assert ( compose _finish _checked ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-07 15:42:51 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "needs_subscribe_warning" , ( ) => {
2020-07-13 22:49:18 +02:00
const invalid _user _id = 999 ;
2018-05-18 16:23:35 +02:00
2020-07-13 22:49:18 +02:00
const test _bot = {
2020-07-15 01:29:15 +02:00
full _name : "Test Bot" ,
email : "test-bot@example.com" ,
2020-07-13 22:49:18 +02:00
user _id : 135 ,
is _bot : true ,
2018-05-18 16:23:35 +02:00
} ;
2020-07-13 22:49:18 +02:00
people . add _active _user ( test _bot ) ;
2018-05-18 16:23:35 +02:00
2020-07-13 22:49:18 +02:00
const sub = {
stream _id : 110 ,
2020-07-15 01:29:15 +02:00
name : "stream" ,
2020-07-13 22:49:18 +02:00
can _access _subscribers : true ,
2018-05-18 16:23:35 +02:00
} ;
2020-07-13 22:49:18 +02:00
stream _data . add _sub ( sub ) ;
stream _data . set _subscribers ( sub , [ bob . user _id , me . user _id ] ) ;
2020-07-15 01:29:15 +02:00
blueslip . expect ( "error" , "Unknown user_id in get_by_user_id: 999" ) ;
2020-07-13 22:49:18 +02:00
// Test with an invalid user id.
assert . equal ( compose . needs _subscribe _warning ( invalid _user _id , sub . stream _id ) , false ) ;
// Test with bot user.
assert . equal ( compose . needs _subscribe _warning ( test _bot . user _id , sub . stream _id ) , false ) ;
// Test when user is subscribed to the stream.
assert . equal ( compose . needs _subscribe _warning ( bob . user _id , sub . stream _id ) , false ) ;
stream _data . remove _subscriber ( sub . stream _id , bob . user _id ) ;
// Test when the user is not subscribed.
assert . equal ( compose . needs _subscribe _warning ( bob . user _id , sub . stream _id ) , true ) ;
2018-05-18 16:23:35 +02:00
} ) ;
2020-07-15 01:29:15 +02:00
run _test ( "warn_if_mentioning_unsubscribed_user" , ( ) => {
2020-07-16 23:29:01 +02:00
let mentioned = {
2020-07-15 01:29:15 +02:00
email : "foo@bar.com" ,
2020-01-14 18:26:48 +01:00
} ;
2017-07-08 00:06:38 +02:00
2020-07-15 01:29:15 +02:00
$ ( "#compose_invite_users .compose_invite_user" ) . length = 0 ;
2017-07-09 14:13:42 +02:00
2020-01-14 18:39:10 +01:00
function test _noop _case ( is _private , is _zephyr _mirror , is _broadcast ) {
2020-07-15 01:29:15 +02:00
const msg _type = is _private ? "private" : "stream" ;
2020-01-14 18:26:48 +01:00
compose _state . set _message _type ( msg _type ) ;
page _params . realm _is _zephyr _mirror _realm = is _zephyr _mirror ;
2020-01-14 18:39:10 +01:00
mentioned . is _broadcast = is _broadcast ;
2020-01-14 18:26:48 +01:00
compose . warn _if _mentioning _unsubscribed _user ( mentioned ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_invite_users" ) . visible ( ) , false ) ;
2020-01-14 18:26:48 +01:00
}
2017-07-08 00:06:38 +02:00
2020-01-14 18:39:10 +01:00
test _noop _case ( true , false , false ) ;
test _noop _case ( false , true , false ) ;
test _noop _case ( false , false , true ) ;
2017-07-09 14:13:42 +02:00
2020-01-14 18:26:48 +01:00
$ ( "#compose_invite_users" ) . hide ( ) ;
2020-07-15 01:29:15 +02:00
compose _state . set _message _type ( "stream" ) ;
2020-01-14 18:26:48 +01:00
page _params . realm _is _zephyr _mirror _realm = false ;
2017-07-09 14:13:42 +02:00
2020-06-22 21:36:21 +02:00
// Test with empty stream name in compose box. It should return noop.
assert . equal ( compose _state . stream _name ( ) , "" ) ;
compose . warn _if _mentioning _unsubscribed _user ( mentioned ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_invite_users" ) . visible ( ) , false ) ;
2020-06-22 21:36:21 +02:00
2020-07-15 01:29:15 +02:00
compose _state . stream _name ( "random" ) ;
2020-06-22 21:36:21 +02:00
const sub = {
stream _id : 111 ,
2020-07-15 01:29:15 +02:00
name : "random" ,
2020-06-22 21:36:21 +02:00
} ;
// Test with invalid stream in compose box. It should return noop.
compose . warn _if _mentioning _unsubscribed _user ( mentioned ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_invite_users" ) . visible ( ) , false ) ;
2020-06-22 21:36:21 +02:00
// Test mentioning a user that should gets a warning.
2020-01-14 18:26:48 +01:00
const checks = [
( function ( ) {
let called ;
2020-07-08 22:28:35 +02:00
compose . needs _subscribe _warning = function ( user _id , stream _id ) {
2020-01-14 18:26:48 +01:00
called = true ;
2020-06-05 16:21:22 +02:00
assert . equal ( user _id , 34 ) ;
2020-07-08 22:28:35 +02:00
assert . equal ( stream _id , 111 ) ;
2020-01-14 18:26:48 +01:00
return true ;
} ;
2020-07-15 00:34:28 +02:00
return function ( ) {
assert ( called ) ;
} ;
2020-07-16 22:35:58 +02:00
} ) ( ) ,
2020-01-14 18:26:48 +01:00
( function ( ) {
let called ;
2020-07-02 01:45:54 +02:00
global . stub _templates ( ( template _name , context ) => {
2020-01-14 18:26:48 +01:00
called = true ;
2020-07-15 01:29:15 +02:00
assert . equal ( template _name , "compose_invite_users" ) ;
2020-06-04 19:41:45 +02:00
assert . equal ( context . user _id , 34 ) ;
2020-06-22 21:36:21 +02:00
assert . equal ( context . stream _id , 111 ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( context . name , "Foo Barson" ) ;
return "fake-compose-invite-user-template" ;
2020-01-14 18:26:48 +01:00
} ) ;
2020-07-15 00:34:28 +02:00
return function ( ) {
assert ( called ) ;
} ;
2020-07-16 22:35:58 +02:00
} ) ( ) ,
2020-01-14 18:26:48 +01:00
( function ( ) {
let called ;
$ ( "#compose_invite_users" ) . append = function ( html ) {
called = true ;
2020-07-15 01:29:15 +02:00
assert . equal ( html , "fake-compose-invite-user-template" ) ;
2020-01-14 18:26:48 +01:00
} ;
2020-07-15 00:34:28 +02:00
return function ( ) {
assert ( called ) ;
} ;
2020-07-16 22:35:58 +02:00
} ) ( ) ,
2020-01-14 18:26:48 +01:00
] ;
2017-07-09 14:13:42 +02:00
2020-01-14 18:26:48 +01:00
mentioned = {
2020-07-15 01:29:15 +02:00
email : "foo@bar.com" ,
2020-06-04 19:41:45 +02:00
user _id : 34 ,
2020-07-15 01:29:15 +02:00
full _name : "Foo Barson" ,
2020-01-14 18:26:48 +01:00
} ;
2017-07-09 14:13:42 +02:00
2020-06-22 21:36:21 +02:00
stream _data . add _sub ( sub ) ;
2020-01-14 18:26:48 +01:00
compose . warn _if _mentioning _unsubscribed _user ( mentioned ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_invite_users" ) . visible ( ) , true ) ;
2017-07-09 14:13:42 +02:00
2020-07-15 00:34:28 +02:00
for ( const f of checks ) {
f ( ) ;
}
2017-07-09 14:13:42 +02:00
2020-01-14 18:26:48 +01:00
// Simulate that the row was added to the DOM.
2020-07-15 01:29:15 +02:00
const warning _row = $ ( "<warning row>" ) ;
2017-07-09 14:13:42 +02:00
2020-01-14 18:26:48 +01:00
let looked _for _existing ;
warning _row . data = function ( field ) {
2020-07-15 01:29:15 +02:00
if ( field === "user-id" ) {
2020-06-22 21:36:21 +02:00
looked _for _existing = true ;
2020-07-15 01:29:15 +02:00
return "34" ;
2020-06-22 21:36:21 +02:00
}
2020-07-15 01:29:15 +02:00
if ( field === "stream-id" ) {
return "111" ;
2020-06-22 21:36:21 +02:00
}
2020-01-14 18:26:48 +01:00
} ;
2017-07-08 00:09:13 +02:00
2020-07-15 01:29:15 +02:00
const previous _users = $ ( "#compose_invite_users .compose_invite_user" ) ;
2020-01-14 18:26:48 +01:00
previous _users . length = 1 ;
previous _users [ 0 ] = warning _row ;
2020-07-15 01:29:15 +02:00
$ ( "#compose_invite_users" ) . hide ( ) ;
2020-01-14 18:26:48 +01:00
// Now try to mention the same person again. The template should
// not render.
global . stub _templates ( noop ) ;
compose . warn _if _mentioning _unsubscribed _user ( mentioned ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose_invite_users" ) . visible ( ) , true ) ;
2020-01-14 18:26:48 +01:00
assert ( looked _for _existing ) ;
} ) ;
2020-07-15 01:29:15 +02:00
run _test ( "on_events" , ( ) => {
2017-07-08 23:16:19 +02:00
function setup _parents _and _mock _remove ( container _sel , target _sel , parent ) {
2020-07-15 01:29:15 +02:00
const container = $ . create ( "fake " + container _sel ) ;
2019-11-02 00:06:25 +01:00
let container _removed = false ;
2017-07-08 00:09:13 +02:00
container . remove = function ( ) {
container _removed = true ;
} ;
2020-07-15 01:29:15 +02:00
const target = $ . create ( "fake click target (" + target _sel + ")" ) ;
2017-07-08 23:16:19 +02:00
target . set _parents _result ( parent , container ) ;
2017-07-08 00:09:13 +02:00
2019-11-02 00:06:25 +01:00
const event = {
2017-07-08 23:16:19 +02:00
preventDefault : noop ,
2020-07-20 22:18:43 +02:00
target ,
2017-07-08 23:16:19 +02:00
} ;
2019-02-02 15:44:51 +01:00
2019-11-02 00:06:25 +01:00
const helper = {
2020-07-20 22:18:43 +02:00
event ,
container ,
target ,
2019-02-02 15:44:51 +01:00
container _was _removed : ( ) => container _removed ,
} ;
return helper ;
2017-07-08 23:16:19 +02:00
}
( function test _compose _all _everyone _confirm _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose-all-everyone" ) . get _on _handler (
"click" ,
".compose-all-everyone-confirm" ,
) ;
2017-07-08 23:16:19 +02:00
2019-11-02 00:06:25 +01:00
const helper = setup _parents _and _mock _remove (
2020-07-15 01:29:15 +02:00
"compose-all-everyone" ,
"compose-all-everyone" ,
".compose-all-everyone" ,
2019-02-02 15:44:51 +01:00
) ;
2017-07-08 00:09:13 +02:00
$ ( "#compose-all-everyone" ) . show ( ) ;
2017-11-26 19:58:36 +01:00
$ ( "#compose-send-status" ) . show ( ) ;
2017-07-08 00:09:13 +02:00
2019-11-02 00:06:25 +01:00
let compose _finish _checked = false ;
2017-07-08 00:09:13 +02:00
compose . finish = function ( ) {
compose _finish _checked = true ;
} ;
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2017-07-08 00:09:13 +02:00
2019-02-02 15:44:51 +01:00
assert ( helper . container _was _removed ( ) ) ;
2017-07-08 00:09:13 +02:00
assert ( compose _finish _checked ) ;
assert ( ! $ ( "#compose-all-everyone" ) . visible ( ) ) ;
2017-11-26 19:58:36 +01:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-08 00:11:52 +02:00
( function test _compose _invite _users _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose_invite_users" ) . get _on _handler ( "click" , ".compose_invite_link" ) ;
2019-11-02 00:06:25 +01:00
const subscription = {
2017-07-08 00:11:52 +02:00
stream _id : 102 ,
2020-07-15 01:29:15 +02:00
name : "test" ,
2017-07-08 00:11:52 +02:00
subscribed : true ,
} ;
2020-06-03 21:38:43 +02:00
const mentioned = {
2020-07-15 01:29:15 +02:00
full _name : "Foo Barson" ,
email : "foo@bar.com" ,
2020-06-03 21:38:43 +02:00
user _id : 34 ,
} ;
people . add _active _user ( mentioned ) ;
2019-11-02 00:06:25 +01:00
let invite _user _to _stream _called = false ;
2020-06-03 21:38:43 +02:00
stream _edit . invite _user _to _stream = function ( user _ids , sub , success ) {
2017-07-08 00:11:52 +02:00
invite _user _to _stream _called = true ;
2020-06-03 21:38:43 +02:00
assert . deepEqual ( user _ids , [ mentioned . user _id ] ) ;
2017-07-08 00:11:52 +02:00
assert . equal ( sub , subscription ) ;
2020-07-16 23:29:01 +02:00
success ( ) ; // This will check success callback path.
2017-07-08 00:11:52 +02:00
} ;
2019-11-02 00:06:25 +01:00
const helper = setup _parents _and _mock _remove (
2020-07-15 01:29:15 +02:00
"compose_invite_users" ,
"compose_invite_link" ,
".compose_invite_user" ,
2019-02-02 15:44:51 +01:00
) ;
2017-07-08 00:11:52 +02:00
2019-02-02 15:44:51 +01:00
helper . container . data = function ( field ) {
2020-07-15 01:29:15 +02:00
if ( field === "user-id" ) {
return "34" ;
2020-06-22 21:36:21 +02:00
}
2020-07-15 01:29:15 +02:00
if ( field === "stream-id" ) {
return "102" ;
2020-06-22 21:36:21 +02:00
}
2017-07-08 00:11:52 +02:00
} ;
2020-07-15 01:29:15 +02:00
helper . target . prop ( "disabled" , false ) ;
2017-07-08 00:11:52 +02:00
// !sub will result in true here and we check the success code path.
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( subscription ) ;
2020-07-15 01:29:15 +02:00
$ ( "#stream_message_recipient_stream" ) . val ( "test" ) ;
2019-11-02 00:06:25 +01:00
let all _invite _children _called = false ;
2017-07-08 00:11:52 +02:00
$ ( "#compose_invite_users" ) . children = function ( ) {
all _invite _children _called = true ;
return [ ] ;
} ;
$ ( "#compose_invite_users" ) . show ( ) ;
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2017-07-08 00:11:52 +02:00
2019-02-02 15:44:51 +01:00
assert ( helper . container _was _removed ( ) ) ;
2017-07-08 00:11:52 +02:00
assert ( ! $ ( "#compose_invite_users" ) . visible ( ) ) ;
assert ( invite _user _to _stream _called ) ;
assert ( all _invite _children _called ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-08 00:13:14 +02:00
( function test _compose _invite _close _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose_invite_users" ) . get _on _handler ( "click" , ".compose_invite_close" ) ;
2017-07-08 00:13:14 +02:00
2019-11-02 00:06:25 +01:00
const helper = setup _parents _and _mock _remove (
2020-07-15 01:29:15 +02:00
"compose_invite_users_close" ,
"compose_invite_close" ,
".compose_invite_user" ,
2019-02-02 15:44:51 +01:00
) ;
2017-07-08 00:13:14 +02:00
2019-11-02 00:06:25 +01:00
let all _invite _children _called = false ;
2017-07-08 00:13:14 +02:00
$ ( "#compose_invite_users" ) . children = function ( ) {
all _invite _children _called = true ;
return [ ] ;
} ;
$ ( "#compose_invite_users" ) . show ( ) ;
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2017-07-08 00:13:14 +02:00
2019-02-02 15:44:51 +01:00
assert ( helper . container _was _removed ( ) ) ;
2017-07-08 00:13:14 +02:00
assert ( all _invite _children _called ) ;
assert ( ! $ ( "#compose_invite_users" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-08 00:22:11 +02:00
2018-04-07 05:01:53 +02:00
( function test _compose _not _subscribed _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose-send-status" ) . get _on _handler ( "click" , ".sub_unsub_button" ) ;
2019-11-02 00:06:25 +01:00
const subscription = {
2018-04-07 05:01:53 +02:00
stream _id : 102 ,
2020-07-15 01:29:15 +02:00
name : "test" ,
2018-04-07 05:01:53 +02:00
subscribed : false ,
} ;
2019-11-02 00:06:25 +01:00
let compose _not _subscribed _called = false ;
2018-04-07 05:01:53 +02:00
subs . sub _or _unsub = function ( ) {
compose _not _subscribed _called = true ;
} ;
2019-11-02 00:06:25 +01:00
const helper = setup _parents _and _mock _remove (
2020-07-15 01:29:15 +02:00
"compose-send-status" ,
"sub_unsub_button" ,
".compose_not_subscribed" ,
2019-02-02 15:44:51 +01:00
) ;
2018-04-07 05:01:53 +02:00
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2018-04-07 05:01:53 +02:00
assert ( compose _not _subscribed _called ) ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( subscription ) ;
2020-07-15 01:29:15 +02:00
$ ( "#stream_message_recipient_stream" ) . val ( "test" ) ;
2018-04-07 05:01:53 +02:00
$ ( "#compose-send-status" ) . show ( ) ;
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2018-04-07 05:01:53 +02:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-04-07 05:01:53 +02:00
( function test _compose _not _subscribed _close _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose-send-status" ) . get _on _handler (
"click" ,
"#compose_not_subscribed_close" ,
) ;
2018-04-07 05:01:53 +02:00
2019-11-02 00:06:25 +01:00
const helper = setup _parents _and _mock _remove (
2020-07-15 01:29:15 +02:00
"compose_user_not_subscribed_close" ,
"compose_not_subscribed_close" ,
".compose_not_subscribed" ,
2019-02-02 15:44:51 +01:00
) ;
2018-04-07 05:01:53 +02:00
$ ( "#compose-send-status" ) . show ( ) ;
2019-02-02 15:44:51 +01:00
handler ( helper . event ) ;
2018-04-07 05:01:53 +02:00
assert ( ! $ ( "#compose-send-status" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-04-07 05:01:53 +02:00
2017-07-08 00:22:11 +02:00
( function test _attach _files _compose _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose" ) . get _on _handler ( "click" , "#attach_files" ) ;
2020-07-15 01:29:15 +02:00
$ ( "#file_input" ) . clone = function ( param ) {
2017-07-08 00:22:11 +02:00
assert ( param ) ;
} ;
2019-11-02 00:06:25 +01:00
let compose _file _input _clicked = false ;
2020-07-21 05:53:07 +02:00
$ ( "#compose #file_input" ) . on ( "click" , ( ) => {
2017-07-08 00:22:11 +02:00
compose _file _input _clicked = true ;
2020-07-21 05:53:07 +02:00
} ) ;
2019-02-02 15:48:30 +01:00
2019-11-02 00:06:25 +01:00
const event = {
2019-02-02 15:48:30 +01:00
preventDefault : noop ,
} ;
2017-07-08 00:22:11 +02:00
handler ( event ) ;
assert ( compose _file _input _clicked ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-08 01:21:20 +02:00
2017-08-11 01:51:48 +02:00
( function test _video _link _compose _clicked ( ) {
2020-07-15 01:29:15 +02:00
page _params . jitsi _server _url = "https://meet.jit.si" ;
2018-04-03 01:46:55 +02:00
2019-11-02 00:06:25 +01:00
let syntax _to _insert ;
let called = false ;
2017-12-08 16:17:20 +01:00
2020-07-15 01:29:15 +02:00
const textarea = $ . create ( "target-stub" ) ;
2019-01-23 08:04:53 +01:00
2019-11-02 00:06:25 +01:00
const ev = {
2019-01-23 08:04:53 +01:00
preventDefault : noop ,
target : {
to _$ : ( ) => textarea ,
} ,
} ;
2017-12-08 16:17:20 +01:00
compose _ui . insert _syntax _and _focus = function ( syntax ) {
syntax _to _insert = syntax ;
2018-07-23 01:19:57 +02:00
called = true ;
2017-10-31 07:06:04 +01:00
} ;
2019-11-02 00:06:25 +01:00
const handler = $ ( "body" ) . get _on _handler ( "click" , ".video_link" ) ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "" ) ;
2017-08-11 01:51:48 +02:00
2019-01-23 08:04:53 +01:00
handler ( ev ) ;
2020-04-08 00:23:15 +02:00
assert ( ! called ) ;
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . jitsi _meet . id ;
handler ( ev ) ;
2017-08-11 01:51:48 +02:00
// video link ids consist of 15 random digits
2020-07-25 02:56:31 +02:00
let video _link _regex = /\[translated: Click to join video call\]\(https:\/\/meet.jit.si\/\d{15}\)/ ;
assert . match ( syntax _to _insert , video _link _regex ) ;
2018-07-23 01:19:57 +02:00
2020-04-08 00:23:15 +02:00
page _params . jitsi _server _url = null ;
called = false ;
handler ( ev ) ;
assert ( ! called ) ;
2019-05-09 09:54:38 +02:00
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . zoom . id ;
2018-12-28 20:45:54 +01:00
2019-11-16 09:26:28 +01:00
window . open = function ( url ) {
2020-07-15 01:29:15 +02:00
assert ( url . endsWith ( "/calls/zoom/register" ) ) ;
2020-08-16 17:17:46 +02:00
// The event here has value=true. We keep it in events.js to
// allow our tooling to verify its schema.
server _events _dispatch . dispatch _normal _event ( events . fixtures . has _zoom _token ) ;
2019-11-16 09:26:28 +01:00
} ;
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . url , "/json/calls/zoom/create" ) ;
2020-07-16 22:40:18 +02:00
payload . success ( { url : "example.zoom.com" } ) ;
2018-12-28 20:45:54 +01:00
} ;
2019-01-23 08:04:53 +01:00
handler ( ev ) ;
2020-07-25 02:56:31 +02:00
video _link _regex = /\[translated: Click to join video call\]\(example\.zoom\.com\)/ ;
assert . match ( syntax _to _insert , video _link _regex ) ;
2018-12-28 20:45:54 +01:00
2020-04-27 22:41:31 +02:00
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . big _blue _button . id ;
channel . get = function ( options ) {
2020-07-15 01:29:15 +02:00
assert ( options . url === "/json/calls/bigbluebutton/create" ) ;
2020-07-15 00:34:28 +02:00
options . success ( {
url :
"/calls/bigbluebutton/join?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22" ,
} ) ;
2020-04-27 22:41:31 +02:00
} ;
handler ( ev ) ;
2020-07-25 02:56:31 +02:00
video _link _regex = /\[translated: Click to join video call\]\(\/calls\/bigbluebutton\/join\?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22\)/ ;
assert . match ( syntax _to _insert , video _link _regex ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-08-11 01:51:48 +02:00
2017-07-08 01:21:20 +02:00
( function test _markdown _preview _compose _clicked ( ) {
// Tests setup
function setup _visibilities ( ) {
2017-11-26 20:37:44 +01:00
$ ( "#compose-textarea" ) . show ( ) ;
2017-07-08 01:21:20 +02:00
$ ( "#markdown_preview" ) . show ( ) ;
$ ( "#undo_markdown_preview" ) . hide ( ) ;
$ ( "#preview_message_area" ) . hide ( ) ;
}
function assert _visibilities ( ) {
2017-11-26 20:37:44 +01:00
assert ( ! $ ( "#compose-textarea" ) . visible ( ) ) ;
2017-07-08 01:21:20 +02:00
assert ( ! $ ( "#markdown_preview" ) . visible ( ) ) ;
assert ( $ ( "#undo_markdown_preview" ) . visible ( ) ) ;
assert ( $ ( "#preview_message_area" ) . visible ( ) ) ;
}
2017-07-29 02:51:33 +02:00
function setup _mock _markdown _contains _backend _only _syntax ( msg _content , return _val ) {
markdown . contains _backend _only _syntax = function ( msg ) {
2017-07-08 01:21:20 +02:00
assert . equal ( msg , msg _content ) ;
return return _val ;
} ;
}
2019-12-03 15:29:44 +01:00
function setup _mock _markdown _is _status _message ( msg _content , return _val ) {
markdown . is _status _message = function ( content ) {
2018-01-21 19:27:36 +01:00
assert . equal ( content , msg _content ) ;
return return _val ;
} ;
}
2017-07-08 01:21:20 +02:00
function test _post _success ( success _callback ) {
2019-11-02 00:06:25 +01:00
const resp = {
2020-07-15 01:29:15 +02:00
rendered : "Server: foobarfoobar" ,
2017-07-08 01:21:20 +02:00
} ;
success _callback ( resp ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#preview_content" ) . html ( ) , "Server: foobarfoobar" ) ;
2017-07-08 01:21:20 +02:00
}
function test _post _error ( error _callback ) {
error _callback ( ) ;
2020-07-15 00:34:28 +02:00
assert . equal ( $ ( "#preview_content" ) . html ( ) , "translated: Failed to generate preview" ) ;
2017-07-08 01:21:20 +02:00
}
function mock _channel _post ( msg ) {
channel . post = function ( payload ) {
2020-07-15 01:29:15 +02:00
assert . equal ( payload . url , "/json/messages/render" ) ;
2017-07-08 01:21:20 +02:00
assert ( payload . idempotent ) ;
assert ( payload . data ) ;
assert . deepEqual ( payload . data . content , msg ) ;
function test ( func , param ) {
2019-11-02 00:06:25 +01:00
let destroy _indicator _called = false ;
2017-07-08 01:21:20 +02:00
loading . destroy _indicator = function ( spinner ) {
assert . equal ( spinner , $ ( "#markdown_preview_spinner" ) ) ;
destroy _indicator _called = true ;
} ;
2017-07-29 02:51:33 +02:00
setup _mock _markdown _contains _backend _only _syntax ( msg , true ) ;
2017-07-08 01:21:20 +02:00
func ( param ) ;
assert ( destroy _indicator _called ) ;
}
test ( test _post _error , payload . error ) ;
test ( test _post _success , payload . success ) ;
} ;
}
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose" ) . get _on _handler ( "click" , "#markdown_preview" ) ;
2017-07-08 01:21:20 +02:00
// Tests start here
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "" ) ;
2017-07-08 01:21:20 +02:00
setup _visibilities ( ) ;
2019-11-02 00:06:25 +01:00
const event = {
2019-02-02 15:48:30 +01:00
preventDefault : noop ,
} ;
2017-07-08 01:21:20 +02:00
handler ( event ) ;
2020-07-15 00:34:28 +02:00
assert . equal ( $ ( "#preview_content" ) . html ( ) , "translated: Nothing to preview" ) ;
2017-07-08 01:21:20 +02:00
assert _visibilities ( ) ;
2019-11-02 00:06:25 +01:00
let make _indicator _called = false ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "```foobarfoobar```" ) ;
2017-07-08 01:21:20 +02:00
setup _visibilities ( ) ;
2020-07-15 01:29:15 +02:00
setup _mock _markdown _contains _backend _only _syntax ( "```foobarfoobar```" , true ) ;
setup _mock _markdown _is _status _message ( "```foobarfoobar```" , false ) ;
2017-07-08 01:21:20 +02:00
loading . make _indicator = function ( spinner ) {
2019-04-18 21:11:30 +02:00
assert . equal ( spinner . selector , "#markdown_preview_spinner" ) ;
2017-07-08 01:21:20 +02:00
make _indicator _called = true ;
} ;
2020-07-15 01:29:15 +02:00
mock _channel _post ( "```foobarfoobar```" ) ;
2017-07-08 01:21:20 +02:00
handler ( event ) ;
assert ( make _indicator _called ) ;
assert _visibilities ( ) ;
2019-11-02 00:06:25 +01:00
let apply _markdown _called = false ;
2020-07-15 01:29:15 +02:00
$ ( "#compose-textarea" ) . val ( "foobarfoobar" ) ;
2017-07-08 01:21:20 +02:00
setup _visibilities ( ) ;
2020-07-15 01:29:15 +02:00
setup _mock _markdown _contains _backend _only _syntax ( "foobarfoobar" , false ) ;
setup _mock _markdown _is _status _message ( "foobarfoobar" , false ) ;
mock _channel _post ( "foobarfoobar" ) ;
2017-07-08 01:21:20 +02:00
markdown . apply _markdown = function ( msg ) {
2020-07-15 01:29:15 +02:00
assert . equal ( msg . raw _content , "foobarfoobar" ) ;
2017-07-08 01:21:20 +02:00
apply _markdown _called = true ;
return msg ;
} ;
handler ( event ) ;
assert ( apply _markdown _called ) ;
assert _visibilities ( ) ;
2020-07-15 00:34:28 +02:00
assert . equal ( $ ( "#preview_content" ) . html ( ) , "Server: foobarfoobar" ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2017-07-08 01:27:11 +02:00
( function test _undo _markdown _preview _clicked ( ) {
2020-07-15 00:34:28 +02:00
const handler = $ ( "#compose" ) . get _on _handler ( "click" , "#undo_markdown_preview" ) ;
2017-07-08 01:27:11 +02:00
2017-11-26 20:37:44 +01:00
$ ( "#compose-textarea" ) . hide ( ) ;
2017-07-08 01:27:11 +02:00
$ ( "#undo_markdown_preview" ) . show ( ) ;
$ ( "#preview_message_area" ) . show ( ) ;
$ ( "#markdown_preview" ) . hide ( ) ;
2019-11-02 00:06:25 +01:00
const event = {
2019-02-02 15:48:30 +01:00
preventDefault : noop ,
} ;
2017-07-08 01:27:11 +02:00
handler ( event ) ;
2017-11-26 20:37:44 +01:00
assert ( $ ( "#compose-textarea" ) . visible ( ) ) ;
2017-07-08 01:27:11 +02:00
assert ( ! $ ( "#undo_markdown_preview" ) . visible ( ) ) ;
assert ( ! $ ( "#preview_message_area" ) . visible ( ) ) ;
assert ( $ ( "#markdown_preview" ) . visible ( ) ) ;
2020-07-16 22:35:58 +02:00
} ) ( ) ;
2018-05-15 12:40:07 +02:00
} ) ;
2017-07-08 00:06:38 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "create_message_object" , ( ) => {
2019-11-02 00:06:25 +01:00
const sub = {
2017-02-24 16:18:56 +01:00
stream _id : 101 ,
2020-07-15 01:29:15 +02:00
name : "social" ,
2017-02-24 16:18:56 +01:00
subscribed : true ,
} ;
2020-02-09 22:02:55 +01:00
stream _data . add _sub ( sub ) ;
2017-02-24 16:18:56 +01:00
2019-11-02 00:06:25 +01:00
const page = {
2020-07-15 01:29:15 +02:00
"#stream_message_recipient_stream" : "social" ,
"#stream_message_recipient_topic" : "lunch" ,
"#compose-textarea" : "burrito" ,
2017-02-24 16:18:56 +01:00
} ;
global . $ = function ( selector ) {
return {
2020-07-20 22:18:43 +02:00
val ( ) {
2017-02-24 16:18:56 +01:00
return page [ selector ] ;
} ,
} ;
} ;
2017-04-24 20:35:26 +02:00
global . compose _state . get _message _type = function ( ) {
2020-07-15 01:29:15 +02:00
return "stream" ;
2017-02-24 16:18:56 +01:00
} ;
2019-11-02 00:06:25 +01:00
let message = compose . create _message _object ( ) ;
2020-02-07 21:18:20 +01:00
assert . equal ( message . to , sub . stream _id ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( message . topic , "lunch" ) ;
assert . equal ( message . content , "burrito" ) ;
2020-02-07 21:18:20 +01:00
2020-07-15 01:29:15 +02:00
blueslip . expect ( "error" , "Trying to send message with bad stream name: BOGUS STREAM" ) ;
2020-02-07 21:18:20 +01:00
2020-07-15 01:29:15 +02:00
page [ "#stream_message_recipient_stream" ] = "BOGUS STREAM" ;
2020-02-07 21:18:20 +01:00
message = compose . create _message _object ( ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( message . to , "BOGUS STREAM" ) ;
assert . equal ( message . topic , "lunch" ) ;
assert . equal ( message . content , "burrito" ) ;
2017-02-24 16:18:56 +01:00
2017-04-24 20:35:26 +02:00
global . compose _state . get _message _type = function ( ) {
2020-07-15 01:29:15 +02:00
return "private" ;
2017-02-24 16:18:56 +01:00
} ;
2019-12-02 17:53:55 +01:00
compose _state . private _message _recipient = function ( ) {
2020-07-15 01:29:15 +02:00
return "alice@example.com, bob@example.com" ;
2018-03-31 13:22:29 +02:00
} ;
2017-03-29 08:54:26 +02:00
message = compose . create _message _object ( ) ;
2019-05-23 22:18:58 +02:00
assert . deepEqual ( message . to , [ alice . user _id , bob . user _id ] ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( message . to _user _ids , "31,32" ) ;
assert . equal ( message . content , "burrito" ) ;
2017-02-24 16:18:56 +01:00
2020-07-16 22:40:18 +02:00
const { email _list _to _user _ids _string } = people ;
2019-05-23 22:18:58 +02:00
people . email _list _to _user _ids _string = ( ) => undefined ;
message = compose . create _message _object ( ) ;
assert . deepEqual ( message . to , [ alice . email , bob . email ] ) ;
people . email _list _to _user _ids _string = email _list _to _user _ids _string ;
2018-05-15 12:40:07 +02:00
} ) ;
2018-07-23 02:41:55 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "nonexistent_stream_reply_error" , ( ) => {
set _global ( "$" , global . make _zjquery ( ) ) ;
2018-07-23 02:41:55 +02:00
2020-02-01 04:46:54 +01:00
const actions = [ ] ;
2018-07-23 02:41:55 +02:00
$ ( "#nonexistent_stream_reply_error" ) . show = ( ) => {
2020-02-01 04:46:54 +01:00
actions . push ( "show" ) ;
2018-07-23 02:41:55 +02:00
} ;
$ ( "#nonexistent_stream_reply_error" ) . hide = ( ) => {
2020-02-01 04:46:54 +01:00
actions . push ( "hide" ) ;
2018-07-23 02:41:55 +02:00
} ;
compose . nonexistent _stream _reply _error ( ) ;
2020-07-15 01:29:15 +02:00
assert . equal ( $ ( "#compose-reply-error-msg" ) . html ( ) , "There are no messages to reply to yet." ) ;
2020-02-01 04:46:54 +01:00
assert . deepEqual ( actions , [ "show" , "hide" ] ) ;
2018-07-23 02:41:55 +02:00
} ) ;
2018-08-13 23:17:45 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "narrow_button_titles" , ( ) => {
2020-07-02 01:41:40 +02:00
util . is _mobile = ( ) => false ;
2018-08-13 23:17:45 +02:00
2019-03-06 23:46:53 +01:00
compose . update _closed _compose _buttons _for _private ( ) ;
2018-08-13 23:17:45 +02:00
assert . equal ( $ ( "#left_bar_compose_stream_button_big" ) . text ( ) , i18n . t ( "New stream message" ) ) ;
2019-06-05 03:27:12 +02:00
assert . equal ( $ ( "#left_bar_compose_private_button_big" ) . text ( ) , i18n . t ( "New private message" ) ) ;
2018-08-13 23:17:45 +02:00
2019-03-06 23:46:53 +01:00
compose . update _closed _compose _buttons _for _stream ( ) ;
2018-08-13 23:17:45 +02:00
assert . equal ( $ ( "#left_bar_compose_stream_button_big" ) . text ( ) , i18n . t ( "New topic" ) ) ;
2019-03-06 23:46:53 +01:00
assert . equal ( $ ( "#left_bar_compose_private_button_big" ) . text ( ) , i18n . t ( "New private message" ) ) ;
2018-08-13 23:17:45 +02:00
} ) ;
2020-04-08 00:23:15 +02:00
2020-07-15 01:29:15 +02:00
run _test ( "test_video_chat_button_toggle" , ( ) => {
2020-04-08 00:23:15 +02:00
reset _jquery ( ) ;
stub _out _video _calls ( ) ;
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . disabled . id ;
compose . initialize ( ) ;
assert . equal ( $ ( "#below-compose-content .video_link" ) . visible ( ) , false ) ;
reset _jquery ( ) ;
stub _out _video _calls ( ) ;
page _params . realm _video _chat _provider =
page _params . realm _available _video _chat _providers . jitsi _meet . id ;
compose . initialize ( ) ;
assert . equal ( $ ( "#below-compose-content .video_link" ) . visible ( ) , false ) ;
reset _jquery ( ) ;
stub _out _video _calls ( ) ;
2020-07-15 01:29:15 +02:00
page _params . jitsi _server _url = "https://meet.jit.si" ;
2020-04-08 00:23:15 +02:00
compose . initialize ( ) ;
assert . equal ( $ ( "#below-compose-content .video_link" ) . visible ( ) , true ) ;
} ) ;