2013-05-11 14:20:07 +02:00
( function ( root , factory ) {
2018-10-13 17:47:52 +02:00
define ( [ "jasmine" , "mock" , "test-utils" ] , factory ) ;
} ( this , function ( jasmine , mock , test _utils ) {
2018-07-30 18:16:32 +02:00
const _ = converse . env . _ ,
$pres = converse . env . $pres ,
$iq = converse . env . $iq ,
$msg = converse . env . $msg ,
2019-09-19 16:54:55 +02:00
Model = converse . env . Model ,
2018-07-30 18:16:32 +02:00
Strophe = converse . env . Strophe ,
Promise = converse . env . Promise ,
sizzle = converse . env . sizzle ,
u = converse . env . utils ;
2015-02-01 16:15:34 +01:00
2019-01-28 10:06:23 +01:00
describe ( "Groupchats" , function ( ) {
2018-10-13 14:13:26 +02:00
2016-06-03 10:22:31 +02:00
describe ( "The \"rooms\" API" , function ( ) {
2017-07-11 10:41:11 +02:00
it ( "has a method 'close' which closes rooms by JID or all rooms when called with no arguments" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-12-08 20:42:09 +01:00
_converse . connection . IQ _stanzas = [ ] ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'leisure@montague.lit' , 'romeo' ) ;
2019-12-08 20:42:09 +01:00
_converse . connection . IQ _stanzas = [ ] ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'news@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
expect ( u . isVisible ( _converse . chatboxviews . get ( 'lounge@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
expect ( u . isVisible ( _converse . chatboxviews . get ( 'leisure@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
expect ( u . isVisible ( _converse . chatboxviews . get ( 'news@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
2019-10-24 14:29:15 +02:00
await _converse . api . roomviews . close ( 'lounge@montague.lit' ) ;
2019-06-03 07:58:51 +02:00
expect ( _converse . chatboxviews . get ( 'lounge@montague.lit' ) ) . toBeUndefined ( ) ;
expect ( u . isVisible ( _converse . chatboxviews . get ( 'leisure@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
expect ( u . isVisible ( _converse . chatboxviews . get ( 'news@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
2019-10-24 14:29:15 +02:00
await _converse . api . roomviews . close ( [ 'leisure@montague.lit' , 'news@montague.lit' ] ) ;
2019-06-03 07:58:51 +02:00
expect ( _converse . chatboxviews . get ( 'lounge@montague.lit' ) ) . toBeUndefined ( ) ;
expect ( _converse . chatboxviews . get ( 'leisure@montague.lit' ) ) . toBeUndefined ( ) ;
expect ( _converse . chatboxviews . get ( 'news@montague.lit' ) ) . toBeUndefined ( ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
await test _utils . openAndEnterChatRoom ( _converse , 'leisure@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
expect ( u . isVisible ( _converse . chatboxviews . get ( 'lounge@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
expect ( u . isVisible ( _converse . chatboxviews . get ( 'leisure@montague.lit' ) . el ) ) . toBeTruthy ( ) ;
2019-10-24 14:29:15 +02:00
await _converse . api . roomviews . close ( ) ;
2019-06-03 07:58:51 +02:00
expect ( _converse . chatboxviews . get ( 'lounge@montague.lit' ) ) . toBeUndefined ( ) ;
expect ( _converse . chatboxviews . get ( 'leisure@montague.lit' ) ) . toBeUndefined ( ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-06-03 10:22:31 +02:00
2018-07-25 12:05:09 +02:00
it ( "has a method 'get' which returns a wrapped groupchat (if it exists)" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-12 09:55:43 +02:00
2019-10-24 14:29:15 +02:00
await test _utils . waitForRoster ( _converse , 'current' ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . rosterview . el . querySelectorAll ( '.roster-group .group-toggle' ) . length , 300 ) ;
2019-07-10 09:47:13 +02:00
let muc _jid = 'chillout@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
2019-10-04 18:26:33 +02:00
let room = await _converse . api . rooms . get ( muc _jid ) ;
2018-11-09 11:55:34 +01:00
expect ( room instanceof Object ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
let chatroomview = _converse . chatboxviews . get ( muc _jid ) ;
2018-11-09 11:55:34 +01:00
expect ( chatroomview . is _chatroom ) . toBeTruthy ( ) ;
expect ( u . isVisible ( chatroomview . el ) ) . toBeTruthy ( ) ;
2019-10-24 14:29:15 +02:00
await chatroomview . close ( ) ;
2018-11-09 11:55:34 +01:00
// Test with mixed case
2019-07-10 09:47:13 +02:00
muc _jid = 'Leisure@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
2019-10-04 18:26:33 +02:00
room = await _converse . api . rooms . get ( muc _jid ) ;
2018-11-09 11:55:34 +01:00
expect ( room instanceof Object ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
chatroomview = _converse . chatboxviews . get ( muc _jid . toLowerCase ( ) ) ;
2018-11-09 11:55:34 +01:00
expect ( u . isVisible ( chatroomview . el ) ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
muc _jid = 'leisure@montague.lit' ;
2019-10-04 18:26:33 +02:00
room = await _converse . api . rooms . get ( muc _jid ) ;
2018-11-09 11:55:34 +01:00
expect ( room instanceof Object ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
chatroomview = _converse . chatboxviews . get ( muc _jid . toLowerCase ( ) ) ;
2018-11-09 11:55:34 +01:00
expect ( u . isVisible ( chatroomview . el ) ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
muc _jid = 'leiSure@montague.lit' ;
2019-10-04 18:26:33 +02:00
room = await _converse . api . rooms . get ( muc _jid ) ;
2018-11-09 11:55:34 +01:00
expect ( room instanceof Object ) . toBeTruthy ( ) ;
2019-07-10 09:47:13 +02:00
chatroomview = _converse . chatboxviews . get ( muc _jid . toLowerCase ( ) ) ;
2018-11-09 11:55:34 +01:00
expect ( u . isVisible ( chatroomview . el ) ) . toBeTruthy ( ) ;
chatroomview . close ( ) ;
// Non-existing room
2019-07-10 09:47:13 +02:00
muc _jid = 'chillout2@montague.lit' ;
2019-10-04 18:26:33 +02:00
room = await _converse . api . rooms . get ( muc _jid ) ;
2019-11-01 16:04:55 +01:00
expect ( room ) . toBe ( null ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-06-03 10:22:31 +02:00
2017-07-12 09:55:43 +02:00
it ( "has a method 'open' which opens (optionally configures) and returns a wrapped chat box" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-12 09:55:43 +02:00
2020-01-16 13:01:57 +01:00
// Mock 'getDiscoInfo', otherwise the room won't be
2017-02-27 22:09:17 +01:00
// displayed as it waits first for the features to be returned
// (when it's a new room being created).
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2017-02-27 22:09:17 +01:00
2019-06-03 07:58:51 +02:00
let jid = 'lounge@montague.lit' ;
2019-07-11 12:30:14 +02:00
let chatroomview , IQ _id ;
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
await test _utils . waitForRoster ( _converse , 'current' ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . rosterview . el . querySelectorAll ( '.roster-group .group-toggle' ) . length ) ;
2019-12-08 20:42:09 +01:00
2018-11-09 11:55:34 +01:00
let room = await _converse . api . rooms . open ( jid ) ;
// Test on groupchat that's not yet open
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( jid ) ;
expect ( chatroomview . is _chatroom ) . toBeTruthy ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( chatroomview . el ) ) ;
2018-11-09 11:55:34 +01:00
// Test again, now that the room exists.
room = await _converse . api . rooms . open ( jid ) ;
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( jid ) ;
expect ( chatroomview . is _chatroom ) . toBeTruthy ( ) ;
expect ( u . isVisible ( chatroomview . el ) ) . toBeTruthy ( ) ;
2019-10-24 14:29:15 +02:00
await chatroomview . close ( ) ;
2018-11-09 11:55:34 +01:00
// Test with mixed case in JID
2019-06-03 07:58:51 +02:00
jid = 'Leisure@montague.lit' ;
2018-11-09 11:55:34 +01:00
room = await _converse . api . rooms . open ( jid ) ;
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( jid . toLowerCase ( ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( chatroomview . el ) ) ;
2018-11-09 11:55:34 +01:00
2019-06-03 07:58:51 +02:00
jid = 'leisure@montague.lit' ;
2018-11-09 11:55:34 +01:00
room = await _converse . api . rooms . open ( jid ) ;
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( jid . toLowerCase ( ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( chatroomview . el ) ) ;
2018-11-09 11:55:34 +01:00
2019-06-03 07:58:51 +02:00
jid = 'leiSure@montague.lit' ;
2018-11-09 11:55:34 +01:00
room = await _converse . api . rooms . open ( jid ) ;
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( jid . toLowerCase ( ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( chatroomview . el ) ) ;
2018-11-09 11:55:34 +01:00
chatroomview . close ( ) ;
_converse . muc _instant _rooms = false ;
2019-05-21 11:06:21 +02:00
const sendIQ = _converse . connection . sendIQ ;
2018-11-09 11:55:34 +01:00
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
// Test with configuration
room = await _converse . api . rooms . open ( 'room@conference.example.org' , {
'nick' : 'some1' ,
'auto_configure' : true ,
'roomconfig' : {
2019-05-04 06:15:39 +02:00
'getmemberlist' : [ 'moderator' , 'participant' ] ,
2018-11-09 11:55:34 +01:00
'changesubject' : false ,
'membersonly' : true ,
'persistentroom' : true ,
'publicroom' : true ,
'roomdesc' : 'Welcome to this groupchat' ,
'whois' : 'anyone'
2018-07-30 18:16:32 +02:00
}
2016-12-02 19:12:40 +01:00
} ) ;
2019-09-19 16:54:55 +02:00
expect ( room instanceof Model ) . toBeTruthy ( ) ;
2018-11-09 11:55:34 +01:00
chatroomview = _converse . chatboxviews . get ( 'room@conference.example.org' ) ;
// We pretend this is a new room, so no disco info is returned.
2019-04-11 23:10:57 +02:00
const features _stanza = $iq ( {
2018-11-09 11:55:34 +01:00
from : 'room@conference.example.org' ,
'id' : IQ _id ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-09 11:55:34 +01:00
'type' : 'error'
} ) . c ( 'error' , { 'type' : 'cancel' } )
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-06-03 07:58:51 +02:00
/ * < p r e s e n c e x m l n s = " j a b b e r : c l i e n t " t o = " r o m e o @ m o n t a g u e . l i t / p d a " f r o m = " r o o m @ c o n f e r e n c e . e x a m p l e . o r g / y o " >
2018-11-09 11:55:34 +01:00
* < x xmlns = "http://jabber.org/protocol/muc#user" >
2019-06-03 07:58:51 +02:00
* < item affiliation = "owner" jid = "romeo@montague.lit/pda" role = "moderator" / >
2018-11-09 11:55:34 +01:00
* < status code = "110" / >
* < status code = "201" / >
* < / x >
* < / p r e s e n c e >
* /
2019-04-11 23:10:57 +02:00
const presence = $pres ( {
2018-11-09 11:55:34 +01:00
from : 'room@conference.example.org/some1' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda'
2018-11-09 11:55:34 +01:00
} )
. c ( 'x' , { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
affiliation : 'owner' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/pda' ,
2018-11-09 11:55:34 +01:00
role : 'moderator'
} ) . up ( )
. c ( 'status' , { code : '110' } ) . up ( )
. c ( 'status' , { code : '201' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
expect ( _converse . connection . sendIQ ) . toHaveBeenCalled ( ) ;
2019-05-21 11:06:21 +02:00
const IQ _stanzas = _converse . connection . IQ _stanzas ;
const iq = IQ _stanzas . filter ( s => s . querySelector ( ` query[xmlns=" ${ Strophe . NS . MUC _OWNER } "] ` ) ) . pop ( ) ;
expect ( Strophe . serialize ( iq ) ) . toBe (
` <iq id=" ${ iq . getAttribute ( 'id' ) } " to="room@conference.example.org" type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#owner"/></iq> ` ) ;
2019-02-12 14:21:45 +01:00
const node = u . toStanza ( `
< iq xmlns = "jabber:client"
type = "result"
2019-06-03 07:58:51 +02:00
to = "romeo@montague.lit/pda"
2019-05-21 11:06:21 +02:00
from = "room@conference.example.org" id = "${iq.getAttribute('id')}" >
2019-02-12 14:21:45 +01:00
< query xmlns = "http://jabber.org/protocol/muc#owner" >
< x xmlns = "jabber:x:data" type = "form" >
< title > Configuration for room @ conference . example . org < / t i t l e >
< instructions > Complete and submit this form to configure the room . < / i n s t r u c t i o n s >
< field var = "FORM_TYPE" type = "hidden" >
< value > http : //jabber.org/protocol/muc#roomconfig</value>
< / f i e l d >
< field type = "text-single" var = "muc#roomconfig_roomname" label = "Name" >
< value > Room < / v a l u e >
< / f i e l d >
< field type = "text-single" var = "muc#roomconfig_roomdesc" label = "Description" > < value / > < / f i e l d >
< field type = "boolean" var = "muc#roomconfig_persistentroom" label = "Make Room Persistent?" / >
< field type = "boolean" var = "muc#roomconfig_publicroom" label = "Make Room Publicly Searchable?" > < value > 1 < / v a l u e > < / f i e l d >
< field type = "boolean" var = "muc#roomconfig_changesubject" label = "Allow Occupants to Change Subject?" / >
< field type = "list-single" var = "muc#roomconfig_whois" label = "Who May Discover Real JIDs?" > < option label = "Moderators Only" >
< value > moderators < / v a l u e > < / o p t i o n > < o p t i o n l a b e l = " A n y o n e " > < v a l u e > a n y o n e < / v a l u e > < / o p t i o n >
< / f i e l d >
2019-05-04 06:15:39 +02:00
< field label = "Roles and Affiliations that May Retrieve Member List"
type = "list-multi"
var = "muc#roomconfig_getmemberlist" >
< value > moderator < / v a l u e >
< value > participant < / v a l u e >
< value > visitor < / v a l u e >
< / f i e l d >
2019-02-12 14:21:45 +01:00
< field type = "text-private" var = "muc#roomconfig_roomsecret" label = "Password" > < value / > < / f i e l d >
< field type = "boolean" var = "muc#roomconfig_moderatedroom" label = "Make Room Moderated?" / >
< field type = "boolean" var = "muc#roomconfig_membersonly" label = "Make Room Members-Only?" / >
< field type = "text-single" var = "muc#roomconfig_historylength" label = "Maximum Number of History Messages Returned by Room" >
< value > 20 < / v a l u e > < / f i e l d >
< / x >
< / q u e r y >
< / i q > ` ) ;
2018-11-09 11:55:34 +01:00
spyOn ( chatroomview . model , 'sendConfiguration' ) . and . callThrough ( ) ;
2019-02-12 14:21:45 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( node ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => chatroomview . model . sendConfiguration . calls . count ( ) === 1 ) ;
2019-05-21 11:06:21 +02:00
const sent _stanza = IQ _stanzas . filter ( s => s . getAttribute ( 'type' ) === 'set' ) . pop ( ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( 'field[var="muc#roomconfig_roomname"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'Room' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_roomdesc"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'Welcome to this groupchat' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_persistentroom"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( '1' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_getmemberlist"] value' , sent _stanza ) . map ( e => e . textContent . trim ( ) ) . join ( ' ' ) ) . toBe ( 'moderator participant' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_publicroom"] value ' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( '1' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_changesubject"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( '0' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_whois"] value ' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'anyone' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_membersonly"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( '1' ) ;
expect ( sizzle ( 'field[var="muc#roomconfig_historylength"] value' , sent _stanza ) . pop ( ) . textContent . trim ( ) ) . toBe ( '20' ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-06-03 10:22:31 +02:00
} ) ;
2018-07-25 12:05:09 +02:00
describe ( "An instant groupchat" , function ( ) {
2018-01-10 13:25:40 +01:00
2017-07-11 10:41:11 +02:00
it ( "will be created when muc_instant_rooms is set to true" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-12-08 20:42:09 +01:00
let IQ _stanzas = _converse . connection . IQ _stanzas ;
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'lounge' , 'montague.lit' , 'romeo' ) ;
2018-11-20 18:10:55 +01:00
2019-09-05 12:49:10 +02:00
const disco _selector = ` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] ` ;
const stanza = await u . waitUntil ( ( ) => IQ _stanzas . filter ( iq => iq . querySelector ( disco _selector ) ) . pop ( ) ) ;
// We pretend this is a new room, so no disco info is returned.
2018-11-09 11:55:34 +01:00
const features _stanza = $iq ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit' ,
2018-09-13 10:51:56 +02:00
'id' : stanza . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-09 11:55:34 +01:00
'type' : 'error'
2017-07-12 09:55:43 +02:00
} ) . c ( 'error' , { 'type' : 'cancel' } )
2018-09-13 10:51:56 +02:00
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2017-02-14 17:55:32 +01:00
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-05-20 10:06:37 +02:00
spyOn ( view . model , 'join' ) . and . callThrough ( ) ;
2019-09-05 12:49:10 +02:00
await test _utils . waitForReservedNick ( _converse , muc _jid , '' ) ;
const input = await u . waitUntil ( ( ) => view . el . querySelector ( 'input[name="nick"]' ) , 1000 ) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . NICKNAME _REQUIRED ) ;
2018-11-09 11:55:34 +01:00
input . value = 'nicky' ;
view . el . querySelector ( 'input[type=submit]' ) . click ( ) ;
2019-05-20 10:06:37 +02:00
expect ( view . model . join ) . toHaveBeenCalled ( ) ;
2019-12-08 20:42:09 +01:00
_converse . connection . IQ _stanzas = [ ] ;
await test _utils . getRoomFeatures ( _converse , muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ;
2018-11-09 11:55:34 +01:00
// The user has just entered the room (because join was called)
// and receives their own presence from the server.
// See example 24:
2019-03-04 17:49:44 +01:00
// https://xmpp.org/extensions/xep-0045.html#enter-pres
2018-11-09 11:55:34 +01:00
//
/ * < p r e s e n c e x m l n s = " j a b b e r : c l i e n t " t o = " j o r d i e . l a n g e n @ c h a t . e x a m p l e . o r g / c o n v e r s e . j s - 1 1 6 5 9 2 9 9 " f r o m = " m y r o o m @ c o n f e r e n c e . c h a t . e x a m p l e . o r g / j c " >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
* < item jid = "jordie.langen@chat.example.org/converse.js-11659299" affiliation = "owner" role = "moderator" / >
* < status code = "110" / >
* < status code = "201" / >
* < / x >
* < / p r e s e n c e >
* /
2019-05-20 10:06:37 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
2019-06-11 12:16:27 +02:00
from : 'lounge@montague.lit/nicky' ,
2018-11-09 11:55:34 +01:00
id : '5025e055-036c-4bc5-a227-706e7e352053'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : 'owner' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/orchard' ,
2018-11-09 11:55:34 +01:00
role : 'moderator'
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . up ( )
. c ( 'status' ) . attrs ( { code : '201' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . ENTERED ) ;
2019-07-10 09:47:13 +02:00
await test _utils . returnMemberLists ( _converse , muc _jid ) ;
2020-03-31 22:43:55 +02:00
const num _info _msgs = await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-content .chat-info' ) . length ) ;
expect ( num _info _msgs ) . toBe ( 1 ) ;
2019-06-11 12:16:27 +02:00
2019-08-12 20:16:34 +02:00
const info _texts = Array . from ( view . el . querySelectorAll ( '.chat-content .chat-info' ) ) . map ( e => e . textContent . trim ( ) ) ;
2019-06-19 11:04:09 +02:00
expect ( info _texts [ 0 ] ) . toBe ( 'A new groupchat has been created' ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "nicky has entered the groupchat" ) ;
2019-05-21 11:06:21 +02:00
2018-11-09 11:55:34 +01:00
// An instant room is created by saving the default configuratoin.
//
/ * < i q t o = " m y r o o m @ c o n f e r e n c e . c h a t . e x a m p l e . o r g " t y p e = " s e t " x m l n s = " j a b b e r : c l i e n t " i d = " 5 0 2 5 e 0 5 5 - 0 3 6 c - 4 b c 5 - a 2 2 7 - 7 0 6 e 7 e 3 5 2 0 5 3 : s e n d I Q " >
* < query xmlns = "http://jabber.org/protocol/muc#owner" > < x xmlns = "jabber:x:data" type = "submit" / > < / q u e r y >
* < / i q >
* /
2019-12-08 20:42:09 +01:00
const selector = ` query[xmlns=" ${ Strophe . NS . MUC _OWNER } "] ` ;
IQ _stanzas = _converse . connection . IQ _stanzas ;
const iq = await u . waitUntil ( ( ) => IQ _stanzas . filter ( s => s . querySelector ( selector ) ) . pop ( ) ) ;
2019-05-21 11:06:21 +02:00
expect ( Strophe . serialize ( iq ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ iq . getAttribute ( 'id' ) } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-09 11:55:34 +01:00
` <query xmlns="http://jabber.org/protocol/muc#owner"><x type="submit" xmlns="jabber:x:data"/> ` +
` </query></iq> ` ) ;
2019-07-10 09:47:13 +02:00
2018-11-09 11:55:34 +01:00
done ( ) ;
2017-02-14 17:55:32 +01:00
} ) ) ;
} ) ;
2018-07-25 12:05:09 +02:00
describe ( "A Groupchat" , function ( ) {
2014-01-19 06:02:18 +01:00
2019-07-26 13:32:21 +02:00
describe ( "upon being entered" , function ( ) {
2019-08-08 15:12:18 +02:00
2019-07-26 13:32:21 +02:00
it ( "will fetch the member list if muc_fetch_members is true" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { 'muc_fetch_members' : true } ,
2019-07-26 13:32:21 +02:00
async function ( done , _converse ) {
2020-02-20 17:11:07 +01:00
let sent _IQs = _converse . connection . IQ _stanzas ;
2019-08-08 15:12:18 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
let view = _converse . chatboxviews . get ( muc _jid ) ;
2020-02-20 17:11:07 +01:00
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation]' ) ) . length ) . toBe ( 3 ) ;
2019-07-26 13:32:21 +02:00
2019-08-08 15:12:18 +02:00
// Check in reverse order that we requested all three lists
const owner _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( owner _iq ) ) . toBe (
` <iq id=" ${ owner _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="owner"/></query> ` +
` </iq> ` ) ;
const admin _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( admin _iq ) ) . toBe (
` <iq id=" ${ admin _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="admin"/></query> ` +
` </iq> ` ) ;
const member _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( member _iq ) ) . toBe (
` <iq id=" ${ member _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="member"/></query> ` +
` </iq> ` ) ;
2020-02-20 17:11:07 +01:00
view . close ( ) ;
2019-08-08 15:12:18 +02:00
2020-02-20 17:11:07 +01:00
_converse . connection . IQ _stanzas = [ ] ;
sent _IQs = _converse . connection . IQ _stanzas ;
2019-07-26 13:32:21 +02:00
_converse . muc _fetch _members = false ;
await test _utils . openAndEnterChatRoom ( _converse , 'orchard@montague.lit' , 'romeo' ) ;
view = _converse . chatboxviews . get ( 'orchard@montague.lit' ) ;
2020-02-20 17:11:07 +01:00
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation]' ) ) . length ) . toBe ( 0 ) ;
await view . close ( ) ;
_converse . connection . IQ _stanzas = [ ] ;
sent _IQs = _converse . connection . IQ _stanzas ;
_converse . muc _fetch _members = [ 'admin' ] ;
await test _utils . openAndEnterChatRoom ( _converse , 'courtyard@montague.lit' , 'romeo' ) ;
view = _converse . chatboxviews . get ( 'courtyard@montague.lit' ) ;
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation]' ) ) . length ) . toBe ( 1 ) ;
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation="admin"]' ) ) . length ) . toBe ( 1 ) ;
view . close ( ) ;
_converse . connection . IQ _stanzas = [ ] ;
sent _IQs = _converse . connection . IQ _stanzas ;
_converse . muc _fetch _members = [ 'owner' ] ;
await test _utils . openAndEnterChatRoom ( _converse , 'garden@montague.lit' , 'romeo' ) ;
view = _converse . chatboxviews . get ( 'garden@montague.lit' ) ;
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation]' ) ) . length ) . toBe ( 1 ) ;
expect ( sent _IQs . filter ( iq => iq . querySelector ( 'query item[affiliation="owner"]' ) ) . length ) . toBe ( 1 ) ;
view . close ( ) ;
2019-07-26 13:32:21 +02:00
done ( ) ;
} ) ) ;
2019-08-08 15:12:18 +02:00
describe ( "when fetching the member lists" , function ( ) {
it ( "gracefully handles being forbidden from fetching the lists for certain affiliations" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { 'muc_fetch_members' : true } ,
2019-08-08 15:12:18 +02:00
async function ( done , _converse ) {
const sent _IQs = _converse . connection . IQ _stanzas ;
const muc _jid = 'lounge@montague.lit' ;
const features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
'muc_hidden' ,
'muc_membersonly' ,
'muc_passwordprotected' ,
Strophe . NS . MAM ,
Strophe . NS . SID
] ;
const nick = 'romeo' ;
await _converse . api . rooms . open ( muc _jid ) ;
2019-12-08 20:42:09 +01:00
await test _utils . getRoomFeatures ( _converse , muc _jid , features ) ;
2019-08-08 15:12:18 +02:00
await test _utils . waitForReservedNick ( _converse , muc _jid , nick ) ;
test _utils . receiveOwnMUCPresence ( _converse , muc _jid , nick ) ;
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . ENTERED ) ) ;
2019-08-08 15:12:18 +02:00
// Check in reverse order that we requested all three lists
const owner _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( owner _iq ) ) . toBe (
` <iq id=" ${ owner _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="owner"/></query> ` +
` </iq> ` ) ;
const admin _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( admin _iq ) ) . toBe (
` <iq id=" ${ admin _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="admin"/></query> ` +
` </iq> ` ) ;
const member _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( member _iq ) ) . toBe (
` <iq id=" ${ member _iq . getAttribute ( 'id' ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="member"/></query> ` +
` </iq> ` ) ;
// It might be that the user is not allowed to fetch certain lists.
let err _stanza = u . toStanza (
` <iq xmlns="jabber:client" type="error" to=" ${ _converse . jid } " from=" ${ muc _jid } " id=" ${ admin _iq . getAttribute ( 'id' ) } ">
< error type = "auth" > < forbidden xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" / > < / e r r o r >
< / i q > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( err _stanza ) ) ;
err _stanza = u . toStanza (
` <iq xmlns="jabber:client" type="error" to=" ${ _converse . jid } " from=" ${ muc _jid } " id=" ${ owner _iq . getAttribute ( 'id' ) } ">
< error type = "auth" > < forbidden xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" / > < / e r r o r >
< / i q > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( err _stanza ) ) ;
// Now the service sends the member lists to the user
const member _list _stanza = $iq ( {
'from' : muc _jid ,
'id' : member _iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/orchard' ,
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : Strophe . NS . MUC _ADMIN } )
. c ( 'item' , {
'affiliation' : 'member' ,
'jid' : 'hag66@shakespeare.lit' ,
'nick' : 'thirdwitch' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( member _list _stanza ) ) ;
await u . waitUntil ( ( ) => view . model . occupants . length > 1 ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
// The existing owner occupant should not have their
// affiliation removed due to the owner list
// not being returned (forbidden err).
expect ( view . model . occupants . findWhere ( { 'jid' : _converse . bare _jid } ) . get ( 'affiliation' ) ) . toBe ( 'owner' ) ;
expect ( view . model . occupants . findWhere ( { 'jid' : 'hag66@shakespeare.lit' } ) . get ( 'affiliation' ) ) . toBe ( 'member' ) ;
done ( ) ;
} ) ) ;
} ) ;
2019-07-26 13:32:21 +02:00
} ) ;
2020-04-07 11:30:43 +02:00
describe ( "topic" , function ( ) {
2020-04-06 14:27:44 +02:00
it ( "is shown the header" ,
mock . initConverse (
[ 'rosterGroupsFetched' ] , { } ,
async function ( done , _converse ) {
await test _utils . openAndEnterChatRoom ( _converse , 'jdev@conference.jabber.org' , 'jc' ) ;
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org' ;
let stanza = u . toStanza ( `
2020-04-07 11:30:43 +02:00
< message xmlns = "jabber:client" to = "${_converse.jid}" type = "groupchat" from = "jdev@conference.jabber.org/ralphm" >
2020-04-06 14:27:44 +02:00
< subject > $ { text } < / s u b j e c t >
< delay xmlns = "urn:xmpp:delay" stamp = "2014-02-04T09:35:39Z" from = "jdev@conference.jabber.org" / >
< x xmlns = "jabber:x:delay" stamp = "20140204T09:35:39" from = "jdev@conference.jabber.org" / >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
const view = _converse . chatboxviews . get ( 'jdev@conference.jabber.org' ) ;
await new Promise ( resolve => view . model . once ( 'change:subject' , resolve ) ) ;
const head _desc = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-head__desc' ) ) ;
expect ( head _desc ? . textContent . trim ( ) ) . toBe ( text ) ;
stanza = u . toStanza (
2020-04-07 11:30:43 +02:00
` <message xmlns="jabber:client" to=" ${ _converse . jid } " type="groupchat" from="jdev@conference.jabber.org/ralphm">
2020-04-06 14:27:44 +02:00
< subject > This is a message subject < / s u b j e c t >
< body > This is a message < / b o d y >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
expect ( sizzle ( '.chat-msg__subject' , view . el ) . length ) . toBe ( 1 ) ;
expect ( sizzle ( '.chat-msg__subject' , view . el ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'This is a message subject' ) ;
expect ( sizzle ( '.chat-msg__text' ) . length ) . toBe ( 1 ) ;
expect ( sizzle ( '.chat-msg__text' ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'This is a message' ) ;
expect ( view . el . querySelector ( '.chat-head__desc' ) . textContent . trim ( ) ) . toBe ( text ) ;
done ( ) ;
} ) ) ;
it ( "can be toggled by the user" ,
mock . initConverse (
[ 'rosterGroupsFetched' ] , { } ,
async function ( done , _converse ) {
await test _utils . openAndEnterChatRoom ( _converse , 'jdev@conference.jabber.org' , 'jc' ) ;
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org' ;
let stanza = u . toStanza ( `
2020-04-07 11:30:43 +02:00
< message xmlns = "jabber:client" to = "${_converse.jid}" type = "groupchat" from = "jdev@conference.jabber.org/ralphm" >
2020-04-06 14:27:44 +02:00
< subject > $ { text } < / s u b j e c t >
< delay xmlns = "urn:xmpp:delay" stamp = "2014-02-04T09:35:39Z" from = "jdev@conference.jabber.org" / >
< x xmlns = "jabber:x:delay" stamp = "20140204T09:35:39" from = "jdev@conference.jabber.org" / >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
const view = _converse . chatboxviews . get ( 'jdev@conference.jabber.org' ) ;
await new Promise ( resolve => view . model . once ( 'change:subject' , resolve ) ) ;
const head _desc = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-head__desc' ) ) ;
expect ( head _desc ? . textContent . trim ( ) ) . toBe ( text ) ;
stanza = u . toStanza (
2020-04-07 11:30:43 +02:00
` <message xmlns="jabber:client" to=" ${ _converse . jid } " type="groupchat" from="jdev@conference.jabber.org/ralphm">
2020-04-06 14:27:44 +02:00
< subject > This is a message subject < / s u b j e c t >
< body > This is a message < / b o d y >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
expect ( sizzle ( '.chat-msg__subject' , view . el ) . length ) . toBe ( 1 ) ;
expect ( sizzle ( '.chat-msg__subject' , view . el ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'This is a message subject' ) ;
expect ( sizzle ( '.chat-msg__text' ) . length ) . toBe ( 1 ) ;
expect ( sizzle ( '.chat-msg__text' ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'This is a message' ) ;
const topic _el = view . el . querySelector ( '.chat-head__desc' ) ;
expect ( topic _el . textContent . trim ( ) ) . toBe ( text ) ;
expect ( u . isVisible ( topic _el ) ) . toBe ( true ) ;
const toggle = view . el . querySelector ( '.hide-topic' ) ;
expect ( toggle . textContent ) . toBe ( 'Hide topic' ) ;
toggle . click ( ) ;
await u . waitUntil ( ( ) => ! u . isVisible ( topic _el ) ) ;
expect ( view . el . querySelector ( '.hide-topic' ) . textContent ) . toBe ( 'Show topic' ) ;
done ( ) ;
} ) ) ;
2020-04-07 11:30:43 +02:00
it ( "causes an info message to be shown when received in real-time" ,
mock . initConverse (
[ 'rosterGroupsFetched' ] , { } ,
async function ( done , _converse ) {
spyOn ( _converse . ChatRoom . prototype , 'handleSubjectChange' ) . and . callThrough ( ) ;
await test _utils . openAndEnterChatRoom ( _converse , 'jdev@conference.jabber.org' , 'romeo' ) ;
const view = _converse . chatboxviews . get ( 'jdev@conference.jabber.org' ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( u . toStanza ( `
< message xmlns = "jabber:client" to = "${_converse.jid}" type = "groupchat" from = "jdev@conference.jabber.org/ralphm" >
< subject > This is an older topic < / s u b j e c t >
< delay xmlns = "urn:xmpp:delay" stamp = "2014-02-04T09:35:39Z" from = "jdev@conference.jabber.org" / >
< x xmlns = "jabber:x:delay" stamp = "20140204T09:35:39" from = "jdev@conference.jabber.org" / >
< / m e s s a g e > ` ) ) ) ;
await u . waitUntil ( ( ) => view . model . handleSubjectChange . calls . count ( ) ) ;
expect ( sizzle ( '.chat-info__message' , view . el ) . length ) . toBe ( 0 ) ;
const desc = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-head__desc' ) ) ;
expect ( desc . textContent . trim ( ) ) . toBe ( 'This is an older topic' ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( u . toStanza ( `
< message xmlns = "jabber:client" to = "${_converse.jid}" type = "groupchat" from = "jdev@conference.jabber.org/ralphm" >
< subject > This is a new topic < / s u b j e c t >
< / m e s s a g e > ` ) ) ) ;
await u . waitUntil ( ( ) => view . model . handleSubjectChange . calls . count ( ) === 2 ) ;
const el = sizzle ( '.chat-info__message' , view . el ) . pop ( ) ;
expect ( el . textContent . trim ( ) ) . toBe ( 'Topic set by ralphm' ) ;
await u . waitUntil ( ( ) => desc . textContent . trim ( ) === 'This is a new topic' ) ;
// Removes current topic
const stanza = u . toStanza (
` <message xmlns="jabber:client" to=" ${ _converse . jid } " type="groupchat" from="jdev@conference.jabber.org/ralphm">
< subject / >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
await u . waitUntil ( ( ) => view . model . handleSubjectChange . calls . count ( ) === 3 ) ;
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-head__desc' ) === null ) ;
expect ( view . el . querySelector ( '.chat-info:last-child' ) . textContent . trim ( ) ) . toBe ( "Topic cleared by ralphm" ) ;
done ( ) ;
} ) ) ;
2020-04-06 14:27:44 +02:00
} ) ;
2019-08-03 18:26:27 +02:00
it ( "clears cached messages when it gets closed and clear_messages_on_reconnection is true" ,
2019-05-16 08:24:25 +02:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { 'clear_messages_on_reconnection' : true } ,
2019-05-16 08:24:25 +02:00
async function ( done , _converse ) {
2019-07-26 13:32:21 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-05-16 08:24:25 +02:00
const message = 'Hello world' ,
nick = mock . chatroom _names [ 0 ] ,
msg = $msg ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/' + nick ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2019-05-16 08:24:25 +02:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( message ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2019-05-16 08:24:25 +02:00
spyOn ( view . model , 'clearMessages' ) . and . callThrough ( ) ;
2019-10-24 14:29:15 +02:00
await view . model . close ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . model . clearMessages . calls . count ( ) ) ;
2019-05-16 08:24:25 +02:00
expect ( view . model . messages . length ) . toBe ( 0 ) ;
2020-03-24 13:41:13 +01:00
expect ( view . msgs _container . innerHTML ) . toBe ( '' ) ;
2019-05-16 08:24:25 +02:00
done ( )
} ) ) ;
2018-10-13 20:09:01 +02:00
it ( "is opened when an xmpp: URI is clicked inside another groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2018-10-13 20:09:01 +02:00
2019-10-24 14:29:15 +02:00
await test _utils . waitForRoster ( _converse , 'current' ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-10-13 23:25:01 +02:00
if ( ! view . el . querySelectorAll ( '.chat-area' ) . length ) {
view . renderChatArea ( ) ;
}
expect ( _converse . chatboxes . length ) . toEqual ( 2 ) ;
const message = 'Please go to xmpp:coven@chat.shakespeare.lit?join' ,
nick = mock . chatroom _names [ 0 ] ,
msg = $msg ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/' + nick ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( message ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-02-04 13:46:43 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-msg__text a' ) ) ;
2018-10-13 23:25:01 +02:00
view . el . querySelector ( '.chat-msg__text a' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length === 3 )
2018-10-13 23:25:01 +02:00
expect ( _ . includes ( _converse . chatboxes . pluck ( 'id' ) , 'coven@chat.shakespeare.lit' ) ) . toBe ( true ) ;
done ( )
2018-10-13 20:09:01 +02:00
} ) ) ;
2019-06-11 12:16:27 +02:00
it ( "shows a notification if it's not anonymous" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2018-10-13 14:40:05 +02:00
2019-08-14 09:40:45 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
const nick = 'romeo' ;
await _converse . api . rooms . open ( muc _jid ) ;
2019-12-08 20:42:09 +01:00
await test _utils . getRoomFeatures ( _converse , muc _jid ) ;
2019-08-14 09:40:45 +02:00
await test _utils . waitForReservedNick ( _converse , muc _jid , nick ) ;
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-06-03 07:58:51 +02:00
/ * < p r e s e n c e t o = " r o m e o @ m o n t a g u e . l i t / _ c o n v e r s e . j s - 2 9 0 9 2 1 6 0 "
2018-11-09 11:55:34 +01:00
* from = "coven@chat.shakespeare.lit/some1" >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
2019-06-03 07:58:51 +02:00
* < item affiliation = "owner" jid = "romeo@montague.lit/_converse.js-29092160" role = "moderator" / >
2018-11-09 11:55:34 +01:00
* < status code = "110" / >
* < status code = "100" / >
* < / x >
* < / p r e s e n c e > < / b o d y >
* /
2019-06-11 12:16:27 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
2018-11-09 11:55:34 +01:00
from : 'coven@chat.shakespeare.lit/some1'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'owner' ,
2019-06-03 07:58:51 +02:00
'jid' : 'romeo@montague.lit/_converse.js-29092160' ,
2018-11-09 11:55:34 +01:00
'role' : 'moderator'
} ) . up ( )
. c ( 'status' , { code : '110' } ) . up ( )
. c ( 'status' , { code : '100' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-10-13 14:40:05 +02:00
2020-03-31 22:43:55 +02:00
const num _info _msgs = await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-content .chat-info' ) . length ) ;
expect ( num _info _msgs ) . toBe ( 1 ) ;
expect ( sizzle ( 'div.chat-info' , view . content ) . pop ( ) . textContent . trim ( ) ) . toBe ( "This groupchat is not anonymous" ) ;
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "some1 has entered the groupchat" ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2018-10-13 14:40:05 +02:00
} ) ) ;
2018-07-25 12:05:09 +02:00
it ( "shows join/leave messages when users enter or exit a groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-02-19 16:46:56 +01:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'muc_fetch_members' : false } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2019-12-08 20:42:09 +01:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2020-02-19 16:46:56 +01:00
const nick = 'some1' ;
const room _creation _promise = await _converse . api . rooms . open ( muc _jid , { nick } ) ;
2019-12-08 20:42:09 +01:00
await test _utils . getRoomFeatures ( _converse , muc _jid ) ;
2020-02-19 16:46:56 +01:00
const sent _stanzas = _converse . connection . sent _stanzas ;
await u . waitUntil ( ( ) => sent _stanzas . filter ( iq => sizzle ( 'presence history' , iq ) . length ) . pop ( ) ) ;
2019-11-22 13:31:35 +01:00
2018-10-13 23:25:01 +02:00
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2020-03-31 17:22:05 +02:00
await _converse . api . waitUntil ( 'chatRoomViewInitialized' ) ;
2018-10-13 23:25:01 +02:00
/ * W e d o n ' t s h o w j o i n / l e a v e m e s s a g e s f o r e x i s t i n g o c c u p a n t s . W e
* know about them because we receive their presences before we
* receive our own .
* /
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/oldguy'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'oldguy@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-06-03 07:58:51 +02:00
/ * < p r e s e n c e t o = " r o m e o @ m o n t a g u e . l i t / _ c o n v e r s e . j s - 2 9 0 9 2 1 6 0 "
2018-10-13 23:25:01 +02:00
* from = "coven@chat.shakespeare.lit/some1" >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
2019-06-03 07:58:51 +02:00
* < item affiliation = "owner" jid = "romeo@montague.lit/_converse.js-29092160" role = "moderator" / >
2018-10-13 23:25:01 +02:00
* < status code = "110" / >
* < / x >
* < / p r e s e n c e > < / b o d y >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/some1'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'owner' ,
2019-06-03 07:58:51 +02:00
'jid' : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
'role' : 'moderator'
} ) . up ( )
. c ( 'status' , { code : '110' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "some1 has entered the groupchat" ) ;
2018-10-13 23:25:01 +02:00
2020-02-19 16:46:56 +01:00
await room _creation _promise ;
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . ENTERED ) ) ;
await view . model . messages . fetched ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/newguy'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newguy have entered the groupchat" ) ;
2018-10-13 23:25:01 +02:00
const msg = $msg ( {
'from' : 'coven@chat.shakespeare.lit/some1' ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( 'hello world' ) . tree ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( msg ) ) ;
2019-10-09 16:01:38 +02:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2018-10-13 23:25:01 +02:00
// Add another entrant, otherwise the above message will be
// collapsed if "newguy" leaves immediately again
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/newgirl'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newgirl@montague.lit/_converse.js-213098781' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newguy and newgirl have entered the groupchat" ) ;
2018-10-13 23:25:01 +02:00
// Don't show duplicate join messages
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-290918392' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/newguy'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-07-30 18:16:32 +02:00
2018-10-13 23:25:01 +02:00
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop'
* type = 'unavailable' >
* < status > Disconnected : Replaced by new connection < / s t a t u s >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'none' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
type : 'unavailable' ,
from : 'coven@chat.shakespeare.lit/newguy'
} )
. c ( 'status' , 'Disconnected: Replaced by new connection' ) . up ( )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
2018-07-30 18:16:32 +02:00
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'none'
2018-07-30 18:16:32 +02:00
} ) ;
2018-10-13 23:25:01 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newgirl have entered the groupchat\n newguy has left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
// When the user immediately joins again, we collapse the
// multiple join/leave messages.
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/newguy'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newgirl and newguy have entered the groupchat" ) ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
type : 'unavailable' ,
from : 'coven@chat.shakespeare.lit/newguy'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
2018-01-03 13:04:06 +01:00
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2018-01-03 13:04:06 +01:00
'role' : 'none'
} ) ;
2018-10-13 23:25:01 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newgirl have entered the groupchat\n newguy has left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/nomorenicks'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'nomorenicks@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newgirl and nomorenicks have entered the groupchat\n newguy has left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-290918392' ,
2018-10-13 23:25:01 +02:00
type : 'unavailable' ,
from : 'coven@chat.shakespeare.lit/nomorenicks'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'nomorenicks@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'none'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newgirl have entered the groupchat\n newguy and nomorenicks have left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/nomorenicks'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'nomorenicks@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newgirl and nomorenicks have entered the groupchat\n newguy has left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
// Test a member joining and leaving
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-290918392' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/insider'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'member' ,
2019-06-03 07:58:51 +02:00
'jid' : 'insider@montague.lit/_converse.js-290929789' ,
2018-10-13 23:25:01 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-10-11 14:04:47 +02:00
2018-10-13 23:25:01 +02:00
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop'
* type = 'unavailable' >
* < status > Disconnected : Replaced by new connection < / s t a t u s >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'none' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
type : 'unavailable' ,
from : 'coven@chat.shakespeare.lit/insider'
} )
. c ( 'status' , 'Disconnected: Replaced by new connection' ) . up ( )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
2018-10-11 14:04:47 +02:00
. c ( 'item' , {
'affiliation' : 'member' ,
2019-06-03 07:58:51 +02:00
'jid' : 'insider@montague.lit/_converse.js-290929789' ,
2018-10-11 15:40:29 +02:00
'role' : 'none'
} ) ;
2018-10-13 23:25:01 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newgirl and nomorenicks have entered the groupchat\n newguy and insider have left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
expect ( view . model . occupants . length ) . toBe ( 5 ) ;
2019-06-03 07:58:51 +02:00
expect ( view . model . occupants . findWhere ( { 'jid' : 'insider@montague.lit' } ) . get ( 'show' ) ) . toBe ( 'offline' ) ;
2018-10-13 23:25:01 +02:00
// New girl leaves
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
'type' : 'unavailable' ,
'from' : 'coven@chat.shakespeare.lit/newgirl'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newgirl@montague.lit/_converse.js-213098781' ,
2018-10-13 23:25:01 +02:00
'role' : 'none'
} ) ;
2018-10-11 15:40:29 +02:00
2018-10-13 23:25:01 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and nomorenicks have entered the groupchat\n newguy, insider and newgirl have left the groupchat" ) ;
2018-10-13 23:25:01 +02:00
expect ( view . model . occupants . length ) . toBe ( 4 ) ;
done ( ) ;
2018-01-03 13:04:06 +01:00
} ) ) ;
2018-10-11 18:58:13 +02:00
it ( "combines subsequent join/leave messages when users enter or exit a groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2018-10-11 18:58:13 +02:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'coven@chat.shakespeare.lit' , 'romeo' )
2018-11-09 11:55:34 +01:00
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === "romeo has entered the groupchat" ) ;
2018-11-20 18:10:55 +01:00
2019-02-12 14:21:45 +01:00
let presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/fabio">
2018-11-09 11:55:34 +01:00
< c xmlns = "http://jabber.org/protocol/caps" node = "http://conversations.im" ver = "INI3xjRUioclBTP/aACfWi5m9UY=" hash = "sha-1" / >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fabio@montefuscolo.com.br/Conversations.ZvLu" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === "romeo and fabio have entered the groupchat" ) ;
2018-10-11 18:58:13 +02:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/Dele Olajide">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "deleo@traderlynk.4ng.net/converse.js-39320524" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === "romeo, fabio and Dele Olajide have entered the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/jcbrand">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "owner" jid = "jc@opkode.com/converse.js-30645022" role = "moderator" / >
< status code = "110" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === "romeo, fabio and others have entered the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "deleo@traderlynk.4ng.net/converse.js-39320524" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, fabio and jcbrand have entered the groupchat\n Dele Olajide has left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/Dele Olajide">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "deleo@traderlynk.4ng.net/converse.js-74567907" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, fabio and others have entered the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/fuvuv" xml:lang="en">
2018-11-09 11:55:34 +01:00
< c xmlns = "http://jabber.org/protocol/caps" node = "http://jabber.pix-art.de" ver = "5tOurnuFnp2h50hKafeUyeN4Yl8=" hash = "sha-1" / >
< x xmlns = "vcard-temp:x:update" / >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fuvuv@blabber.im/Pix-Art Messenger.8zoB" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, fabio and others have entered the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/fuvuv">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fuvuv@blabber.im/Pix-Art Messenger.8zoB" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, fabio and others have entered the groupchat\n fuvuv has left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
2018-11-09 11:55:34 +01:00
< status > Disconnected : Replaced by new connection < / s t a t u s >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fabio@montefuscolo.com.br/Conversations.ZvLu" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, jcbrand and Dele Olajide have entered the groupchat\n fuvuv and fabio have left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/fabio">
2018-11-09 11:55:34 +01:00
< c xmlns = "http://jabber.org/protocol/caps" node = "http://conversations.im" ver = "INI3xjRUioclBTP/aACfWi5m9UY=" hash = "sha-1" / >
2019-05-18 06:33:42 +02:00
< status > Ready for a new day < / s t a t u s >
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fabio@montefuscolo.com.br/Conversations.ZvLu" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, jcbrand and others have entered the groupchat\n fuvuv has left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
// XXX: hack so that we can test leave/enter of occupants
// who were already in the room when we joined.
2020-03-24 13:41:13 +01:00
view . msgs _container . innerHTML = '' ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
2018-11-09 11:55:34 +01:00
< status > Disconnected : closed < / s t a t u s >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fabio@montefuscolo.com.br/Conversations.ZvLu" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, jcbrand and Dele Olajide have entered the groupchat\n fuvuv and fabio have left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
2018-11-09 11:55:34 +01:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "deleo@traderlynk.4ng.net/converse.js-74567907" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo and jcbrand have entered the groupchat\n fuvuv, fabio and Dele Olajide have left the groupchat" ) ;
2018-11-09 11:55:34 +01:00
2019-02-12 14:21:45 +01:00
presence = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="coven@chat.shakespeare.lit/fabio">
2018-11-09 11:55:34 +01:00
< c xmlns = "http://jabber.org/protocol/caps" node = "http://conversations.im" ver = "INI3xjRUioclBTP/aACfWi5m9UY=" hash = "sha-1" / >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" jid = "fabio@montefuscolo.com.br/Conversations.ZvLu" role = "participant" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"romeo, jcbrand and fabio have entered the groupchat\n fuvuv and Dele Olajide have left the groupchat" ) ;
expect ( 1 ) . toBe ( 1 ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2018-10-11 18:58:13 +02:00
} ) ) ;
2020-03-31 22:43:55 +02:00
it ( "doesn't show the disconnection messages when muc_show_join_leave is false" ,
2019-05-14 13:01:07 +02:00
mock . initConverse (
2020-03-31 22:43:55 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'muc_show_join_leave' : false } ,
2019-05-14 13:01:07 +02:00
async function ( done , _converse ) {
2020-03-31 22:43:55 +02:00
spyOn ( _converse . ChatRoom . prototype , 'onOccupantAdded' ) . and . callThrough ( ) ;
spyOn ( _converse . ChatRoom . prototype , 'onOccupantRemoved' ) . and . callThrough ( ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'coven@chat.shakespeare.lit' , 'some1' ) ;
2019-05-14 13:01:07 +02:00
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
2019-05-14 13:01:07 +02:00
from : 'coven@chat.shakespeare.lit/newguy'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2019-05-14 13:01:07 +02:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . model . onOccupantAdded . calls . count ( ) === 2 ) ;
expect ( view . model . notifications . get ( 'entered' ) ) . toBeFalsy ( ) ;
expect ( view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ) . toBe ( '' ) ;
2019-05-18 06:33:42 +02:00
await test _utils . sendMessage ( view , 'hello world' ) ;
presence = u . toStanza (
2020-03-31 22:43:55 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="coven@chat.shakespeare.lit/newguy">
2019-05-18 06:33:42 +02:00
< status > Gotta go ! < / s t a t u s >
< x xmlns = "http://jabber.org/protocol/muc#user" >
2020-03-31 22:43:55 +02:00
< item affiliation = "none" jid = "newguy@montague.lit/_converse.js-290929789" role = "none" / >
2019-05-18 06:33:42 +02:00
< / x >
< / p r e s e n c e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . model . onOccupantRemoved . calls . count ( ) ) ;
expect ( view . model . onOccupantRemoved . calls . count ( ) ) . toBe ( 1 ) ;
expect ( view . model . notifications . get ( 'entered' ) ) . toBeFalsy ( ) ;
await test _utils . sendMessage ( view , 'hello world' ) ;
expect ( view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ) . toBe ( '' ) ;
2019-05-14 13:01:07 +02:00
done ( ) ;
} ) ) ;
2018-10-27 22:56:05 +02:00
it ( "role-change messages that follow a MUC leave are left out" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-27 22:56:05 +02:00
async function ( done , _converse ) {
// See https://github.com/conversejs/converse.js/issues/1259
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'conversations@conference.siacs.eu' , 'romeo' ) ;
2018-10-27 22:56:05 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
2018-10-27 22:56:05 +02:00
from : 'conversations@conference.siacs.eu/Guus'
} ) . c ( 'x' , {
'xmlns' : Strophe . NS . MUC _USER
} ) . c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'Guus@montague.lit/xxx' ,
2018-10-27 22:56:05 +02:00
'role' : 'visitor'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
const view = _converse . chatboxviews . get ( 'conversations@conference.siacs.eu' ) ;
const msg = $msg ( {
2019-06-03 07:58:51 +02:00
'from' : 'conversations@conference.siacs.eu/romeo' ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2018-10-27 22:56:05 +02:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( 'Some message' ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => sizzle ( '.chat-msg:last .chat-msg__text' , view . content ) . pop ( ) ) ;
2018-10-27 22:56:05 +02:00
2019-02-12 14:21:45 +01:00
let stanza = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="conversations@conference.siacs.eu/Guus">
2018-10-27 22:56:05 +02:00
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" role = "none" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-10-27 22:56:05 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
2019-02-12 14:21:45 +01:00
stanza = u . toStanza (
2019-06-03 07:58:51 +02:00
` <presence xmlns="jabber:client" to="romeo@montague.lit/orchard" from="conversations@conference.siacs.eu/Guus">
2018-10-27 22:56:05 +02:00
< c xmlns = "http://jabber.org/protocol/caps" node = "http://conversations.im" ver = "ISg6+9AoK1/cwhbNEDviSvjdPzI=" hash = "sha-1" / >
< x xmlns = "vcard-temp:x:update" >
< photo > bf987c486c51fbc05a6a4a9f20dd19b5efba3758 < / p h o t o >
< / x >
< x xmlns = "http://jabber.org/protocol/muc#user" >
< item affiliation = "none" role = "visitor" / >
< / x >
2019-02-12 14:21:45 +01:00
< / p r e s e n c e > ` ) ;
2018-10-27 22:56:05 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( )
=== "romeo and Guus have entered the groupchat" ) ;
expect ( 1 ) . toBe ( 1 ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2016-12-02 18:41:05 +01:00
} ) ) ;
2018-10-13 23:25:01 +02:00
it ( "supports the /me command" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2017-07-12 09:55:43 +02:00
2019-06-03 07:58:51 +02:00
await test _utils . waitUntilDiscoConfirmed ( _converse , 'montague.lit' , [ ] , [ 'vcard-temp' ] ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . xmppstatus . vcard . get ( 'fullname' ) ) ;
2019-10-24 14:29:15 +02:00
await test _utils . waitForRoster ( _converse , 'current' ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-10-13 23:25:01 +02:00
if ( ! view . el . querySelectorAll ( '.chat-area' ) . length ) {
view . renderChatArea ( ) ;
}
let message = '/me is tired' ;
const nick = mock . chatroom _names [ 0 ] ;
let msg = $msg ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/' + nick ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( message ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => sizzle ( '.chat-msg:last .chat-msg__text' , view . content ) . pop ( ) ) ;
2018-10-13 23:25:01 +02:00
expect ( _ . includes ( view . el . querySelector ( '.chat-msg__author' ) . textContent , '**Dyon van de Wege' ) ) . toBeTruthy ( ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chat-msg__text' ) . textContent . trim ( ) ) . toBe ( 'is tired' ) ;
2018-10-13 23:25:01 +02:00
message = '/me is as well' ;
msg = $msg ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/Romeo Montague' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
type : 'groupchat'
} ) . c ( 'body' ) . t ( message ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-msg' ) . length === 2 ) ;
expect ( sizzle ( '.chat-msg__author:last' , view . el ) . pop ( ) . textContent . includes ( '**Romeo Montague' ) ) . toBeTruthy ( ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.chat-msg__text:last' , view . el ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'is as well' ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2018-05-24 09:09:26 +02:00
} ) ) ;
2018-10-13 23:25:01 +02:00
it ( "can be configured if you're its owner" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2018-05-24 09:09:26 +02:00
2018-10-13 23:25:01 +02:00
let sent _IQ , IQ _id ;
const sendIQ = _converse . connection . sendIQ ;
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2018-05-24 09:09:26 +02:00
2018-10-13 23:25:01 +02:00
await _converse . api . rooms . open ( 'coven@chat.shakespeare.lit' , { 'nick' : 'some1' } ) ;
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( view . el ) ) ;
2018-10-13 23:25:01 +02:00
// We pretend this is a new room, so no disco info is returned.
const features _stanza = $iq ( {
from : 'coven@chat.shakespeare.lit' ,
'id' : IQ _id ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-10-13 23:25:01 +02:00
'type' : 'error'
} ) . c ( 'error' , { 'type' : 'cancel' } )
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-06-03 07:58:51 +02:00
/ * < p r e s e n c e t o = " r o m e o @ m o n t a g u e . l i t / _ c o n v e r s e . j s - 2 9 0 9 2 1 6 0 "
2018-10-13 23:25:01 +02:00
* from = "coven@chat.shakespeare.lit/some1" >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
2019-06-03 07:58:51 +02:00
* < item affiliation = "owner" jid = "romeo@montague.lit/_converse.js-29092160" role = "moderator" / >
2018-10-13 23:25:01 +02:00
* < status code = "110" / >
* < / x >
* < / p r e s e n c e > < / b o d y >
* /
2019-05-31 09:14:42 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
from : 'coven@chat.shakespeare.lit/some1'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'owner' ,
2019-06-03 07:58:51 +02:00
'jid' : 'romeo@montague.lit/_converse.js-29092160' ,
2018-10-13 23:25:01 +02:00
'role' : 'moderator'
} ) . up ( )
. c ( 'status' , { code : '110' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-02-10 11:23:55 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.configure-chatroom-button' ) !== null ) ;
2018-10-13 23:25:01 +02:00
view . el . querySelector ( '.configure-chatroom-button' ) . click ( ) ;
/ * C h e c k t h a t a n I Q i s s e n t o u t , a s k i n g f o r t h e
* configuration form .
2019-03-04 17:49:44 +01:00
* See : // https://xmpp.org/extensions/xep-0045.html#example-163
2018-10-13 23:25:01 +02:00
*
* < iq from = 'crone1@shakespeare.lit/desktop'
* id = 'config1'
* to = 'coven@chat.shakespeare.lit'
* type = 'get' >
* < query xmlns = 'http://jabber.org/protocol/muc#owner' / >
* < / i q >
* /
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
` <iq id=" ` + IQ _id + ` " to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#owner"/> ` +
` </iq> ` ) ;
/ * S e r v e r r e s p o n d s w i t h t h e c o n f i g u r a t i o n f o r m .
2019-03-04 17:49:44 +01:00
* See : // https://xmpp.org/extensions/xep-0045.html#example-165
2018-10-13 23:25:01 +02:00
* /
2019-04-06 16:31:42 +02:00
const config _stanza = $iq ( { from : 'coven@chat.shakespeare.lit' ,
2018-10-13 23:25:01 +02:00
'id' : IQ _id ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-10-13 23:25:01 +02:00
'type' : 'result' } )
. c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/muc#owner' } )
. c ( 'x' , { 'xmlns' : 'jabber:x:data' , 'type' : 'form' } )
. c ( 'title' ) . t ( 'Configuration for "coven" Room' ) . up ( )
. c ( 'instructions' ) . t ( 'Complete this form to modify the configuration of your room.' ) . up ( )
. c ( 'field' , { 'type' : 'hidden' , 'var' : 'FORM_TYPE' } )
. c ( 'value' ) . t ( 'http://jabber.org/protocol/muc#roomconfig' ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Natural-Language Room Name' ,
'type' : 'text-single' ,
'var' : 'muc#roomconfig_roomname' } )
. c ( 'value' ) . t ( 'A Dark Cave' ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Short Description of Room' ,
'type' : 'text-single' ,
'var' : 'muc#roomconfig_roomdesc' } )
. c ( 'value' ) . t ( 'The place for all good witches!' ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Enable Public Logging?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_enablelogging' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Allow Occupants to Change Subject?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_changesubject' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Allow Occupants to Invite Others?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_allowinvites' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Who Can Send Private Messages?' ,
'type' : 'list-single' ,
'var' : 'muc#roomconfig_allowpm' } )
. c ( 'value' ) . t ( 'anyone' ) . up ( )
. c ( 'option' , { 'label' : 'Anyone' } )
. c ( 'value' ) . t ( 'anyone' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Anyone with Voice' } )
. c ( 'value' ) . t ( 'participants' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Moderators Only' } )
. c ( 'value' ) . t ( 'moderators' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Nobody' } )
. c ( 'value' ) . t ( 'none' ) . up ( ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Roles for which Presence is Broadcasted' ,
'type' : 'list-multi' ,
'var' : 'muc#roomconfig_presencebroadcast' } )
. c ( 'value' ) . t ( 'moderator' ) . up ( )
. c ( 'value' ) . t ( 'participant' ) . up ( )
. c ( 'value' ) . t ( 'visitor' ) . up ( )
. c ( 'option' , { 'label' : 'Moderator' } )
. c ( 'value' ) . t ( 'moderator' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Participant' } )
. c ( 'value' ) . t ( 'participant' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Visitor' } )
. c ( 'value' ) . t ( 'visitor' ) . up ( ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Roles and Affiliations that May Retrieve Member List' ,
'type' : 'list-multi' ,
'var' : 'muc#roomconfig_getmemberlist' } )
. c ( 'value' ) . t ( 'moderator' ) . up ( )
. c ( 'value' ) . t ( 'participant' ) . up ( )
. c ( 'value' ) . t ( 'visitor' ) . up ( )
. c ( 'option' , { 'label' : 'Moderator' } )
. c ( 'value' ) . t ( 'moderator' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Participant' } )
. c ( 'value' ) . t ( 'participant' ) . up ( ) . up ( )
. c ( 'option' , { 'label' : 'Visitor' } )
. c ( 'value' ) . t ( 'visitor' ) . up ( ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Make Room Publicly Searchable?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_publicroom' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Make Room Publicly Searchable?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_publicroom' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Make Room Persistent?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_persistentroom' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Make Room Moderated?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_moderatedroom' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Make Room Members Only?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_membersonly' } )
. c ( 'value' ) . t ( 0 ) . up ( ) . up ( )
. c ( 'field' , {
'label' : 'Password Required for Entry?' ,
'type' : 'boolean' ,
'var' : 'muc#roomconfig_passwordprotectedroom' } )
. c ( 'value' ) . t ( 1 ) . up ( ) . up ( )
. c ( 'field' , { 'type' : 'fixed' } )
2019-07-11 12:30:14 +02:00
. c ( 'value' ) . t (
'If a password is required to enter this groupchat, you must specify the password below.'
) . up ( ) . up ( )
2018-10-13 23:25:01 +02:00
. c ( 'field' , {
'label' : 'Password' ,
'type' : 'text-private' ,
'var' : 'muc#roomconfig_roomsecret' } )
. c ( 'value' ) . t ( 'cauldronburn' ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( config _stanza ) ) ;
2020-01-26 18:36:25 +01:00
const form = await u . waitUntil ( ( ) => view . el . querySelector ( '.muc-config-form' ) ) ;
expect ( form . querySelectorAll ( 'fieldset' ) . length ) . toBe ( 2 ) ;
2019-07-01 10:44:59 +02:00
const membersonly = view . el . querySelectorAll ( 'input[name="muc#roomconfig_membersonly"]' ) ;
2018-10-13 23:25:01 +02:00
expect ( membersonly . length ) . toBe ( 1 ) ;
expect ( membersonly [ 0 ] . getAttribute ( 'type' ) ) . toBe ( 'checkbox' ) ;
membersonly [ 0 ] . checked = true ;
2019-07-01 10:44:59 +02:00
const moderated = view . el . querySelectorAll ( 'input[name="muc#roomconfig_moderatedroom"]' ) ;
2018-10-13 23:25:01 +02:00
expect ( moderated . length ) . toBe ( 1 ) ;
expect ( moderated [ 0 ] . getAttribute ( 'type' ) ) . toBe ( 'checkbox' ) ;
moderated [ 0 ] . checked = true ;
2019-07-01 10:44:59 +02:00
const password = view . el . querySelectorAll ( 'input[name="muc#roomconfig_roomsecret"]' ) ;
2018-10-13 23:25:01 +02:00
expect ( password . length ) . toBe ( 1 ) ;
expect ( password [ 0 ] . getAttribute ( 'type' ) ) . toBe ( 'password' ) ;
2019-07-01 10:44:59 +02:00
const allowpm = view . el . querySelectorAll ( 'select[name="muc#roomconfig_allowpm"]' ) ;
2018-10-13 23:25:01 +02:00
expect ( allowpm . length ) . toBe ( 1 ) ;
allowpm [ 0 ] . value = 'moderators' ;
2019-07-01 10:44:59 +02:00
const presencebroadcast = view . el . querySelectorAll ( 'select[name="muc#roomconfig_presencebroadcast"]' ) ;
2018-10-13 23:25:01 +02:00
expect ( presencebroadcast . length ) . toBe ( 1 ) ;
presencebroadcast [ 0 ] . value = [ 'moderator' ] ;
2019-11-28 17:01:08 +01:00
view . el . querySelector ( '.chatroom-form input[type="submit"]' ) . click ( ) ;
2018-10-13 23:25:01 +02:00
const sent _stanza = sent _IQ . nodeTree ;
2019-08-12 20:16:34 +02:00
expect ( sent _stanza . querySelector ( 'field[var="muc#roomconfig_membersonly"] value' ) . textContent . trim ( ) ) . toBe ( '1' ) ;
expect ( sent _stanza . querySelector ( 'field[var="muc#roomconfig_moderatedroom"] value' ) . textContent . trim ( ) ) . toBe ( '1' ) ;
expect ( sent _stanza . querySelector ( 'field[var="muc#roomconfig_allowpm"] value' ) . textContent . trim ( ) ) . toBe ( 'moderators' ) ;
expect ( sent _stanza . querySelector ( 'field[var="muc#roomconfig_presencebroadcast"] value' ) . textContent . trim ( ) ) . toBe ( 'moderator' ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2017-07-12 09:55:43 +02:00
} ) ) ;
2018-10-13 23:25:01 +02:00
it ( "shows all members even if they're not currently present in the groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2017-07-12 09:55:43 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'lounge@montague.lit'
2019-07-04 14:12:12 +02:00
const members = [ {
'nick' : 'juliet' ,
'jid' : 'juliet@capulet.lit' ,
'affiliation' : 'member'
} ] ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' , [ ] , members ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . model . occupants . length === 2 ) ;
2019-07-03 14:54:50 +02:00
2019-05-15 15:55:45 +02:00
const occupants = view . el . querySelector ( '.occupant-list' ) ;
2019-06-27 11:27:05 +02:00
for ( let i = 0 ; i < mock . chatroom _names . length ; i ++ ) {
2019-07-01 09:05:08 +02:00
const name = mock . chatroom _names [ i ] ;
const role = mock . chatroom _roles [ name ] . role ;
2019-03-04 17:49:44 +01:00
// See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
2019-07-01 09:05:08 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/' + name
2015-03-01 11:58:07 +01:00
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
2018-10-13 23:25:01 +02:00
affiliation : mock . chatroom _roles [ name ] . affiliation ,
2019-06-03 07:58:51 +02:00
jid : name . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ,
2018-10-13 23:25:01 +02:00
role : role
2019-06-26 17:31:53 +02:00
} ) ;
2016-12-20 10:30:20 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-10-13 23:25:01 +02:00
}
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => occupants . querySelectorAll ( 'li' ) . length > 2 , 500 ) ;
2019-07-03 14:54:50 +02:00
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( 2 + mock . chatroom _names . length ) ;
expect ( view . model . occupants . length ) . toBe ( 2 + mock . chatroom _names . length ) ;
2019-06-27 11:27:05 +02:00
mock . chatroom _names . forEach ( name => {
const model = view . model . occupants . findWhere ( { 'nick' : name } ) ;
const index = view . model . occupants . indexOf ( model ) ;
expect ( occupants . querySelectorAll ( 'li .occupant-nick' ) [ index ] . textContent . trim ( ) ) . toBe ( name ) ;
} ) ;
2018-10-13 23:25:01 +02:00
// Test users leaving the groupchat
2019-03-04 17:49:44 +01:00
// https://xmpp.org/extensions/xep-0045.html#exit
2019-06-27 11:27:05 +02:00
for ( let i = mock . chatroom _names . length - 1 ; i > - 1 ; i -- ) {
2019-07-01 09:05:08 +02:00
const name = mock . chatroom _names [ i ] ;
2019-03-04 17:49:44 +01:00
// See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
2019-07-01 09:05:08 +02:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/' + name ,
2018-10-13 23:25:01 +02:00
type : 'unavailable'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : mock . chatroom _roles [ name ] . affiliation ,
2019-06-03 07:58:51 +02:00
jid : name . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ,
2018-10-13 23:25:01 +02:00
role : 'none'
} ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-07-03 14:54:50 +02:00
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( 8 ) ;
2018-10-13 23:25:01 +02:00
}
2019-07-01 09:05:08 +02:00
const presence = $pres ( {
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/nonmember'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : null ,
jid : 'servant@montague.lit' ,
role : 'visitor'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => occupants . querySelectorAll ( 'li' ) . length > 8 , 500 ) ;
2019-07-03 14:54:50 +02:00
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( 9 ) ;
expect ( view . model . occupants . length ) . toBe ( 9 ) ;
expect ( view . model . occupants . filter ( o => o . isMember ( ) ) . length ) . toBe ( 8 ) ;
2019-12-08 20:42:09 +01:00
view . model . rejoin ( ) ;
2019-07-03 14:54:50 +02:00
// Test that members aren't removed when we reconnect
expect ( view . model . occupants . length ) . toBe ( 8 ) ;
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( 8 ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2017-02-13 09:23:42 +01:00
} ) ) ;
2015-03-01 11:58:07 +01:00
2018-10-13 23:25:01 +02:00
it ( "shows users currently present in the groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2018-05-09 12:28:34 +02:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
var view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ,
2018-10-13 23:25:01 +02:00
occupants = view . el . querySelector ( '.occupant-list' ) ;
2019-10-09 16:01:38 +02:00
var presence ;
2018-10-13 23:25:01 +02:00
for ( var i = 0 ; i < mock . chatroom _names . length ; i ++ ) {
2019-07-11 12:30:14 +02:00
const name = mock . chatroom _names [ i ] ;
const role = mock . chatroom _roles [ name ] . role ;
2019-03-04 17:49:44 +01:00
// See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/' + name
2017-07-12 09:55:43 +02:00
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
2018-10-13 23:25:01 +02:00
affiliation : 'none' ,
2019-06-03 07:58:51 +02:00
jid : name . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ,
2018-10-13 23:25:01 +02:00
role : role
2017-07-12 09:55:43 +02:00
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-10-13 23:25:01 +02:00
}
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => occupants . querySelectorAll ( 'li' ) . length > 1 , 500 ) ;
2019-06-27 11:27:05 +02:00
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( 1 + mock . chatroom _names . length ) ;
mock . chatroom _names . forEach ( name => {
const model = view . model . occupants . findWhere ( { 'nick' : name } ) ;
const index = view . model . occupants . indexOf ( model ) ;
expect ( occupants . querySelectorAll ( 'li .occupant-nick' ) [ index ] . textContent . trim ( ) ) . toBe ( name ) ;
} ) ;
2018-10-13 23:25:01 +02:00
// Test users leaving the groupchat
2019-03-04 17:49:44 +01:00
// https://xmpp.org/extensions/xep-0045.html#exit
2018-10-13 23:25:01 +02:00
for ( i = mock . chatroom _names . length - 1 ; i > - 1 ; i -- ) {
2019-07-11 12:30:14 +02:00
const name = mock . chatroom _names [ i ] ;
2019-03-04 17:49:44 +01:00
// See example 21 https://xmpp.org/extensions/xep-0045.html#enter-pres
2017-12-14 18:43:00 +01:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/' + name ,
2018-10-13 23:25:01 +02:00
type : 'unavailable'
2017-12-14 18:43:00 +01:00
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
2018-10-13 23:25:01 +02:00
affiliation : mock . chatroom _roles [ name ] . affiliation ,
2019-06-03 07:58:51 +02:00
jid : name . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ,
2018-10-13 23:25:01 +02:00
role : 'none'
} ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
expect ( occupants . querySelectorAll ( 'li' ) . length ) . toBe ( i + 1 ) ;
}
done ( ) ;
} ) ) ;
it ( "indicates moderators and visitors by means of a special css class and tooltip" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { 'view_mode' : 'fullscreen' } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
let contact _jid = mock . cur _names [ 2 ] . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ;
2018-10-13 23:25:01 +02:00
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.occupant-list li' ) . length , 500 ) ;
2019-06-27 11:27:05 +02:00
let occupants = view . el . querySelectorAll ( '.occupant-list li' ) ;
2018-10-13 23:25:01 +02:00
expect ( occupants . length ) . toBe ( 1 ) ;
2019-06-03 07:58:51 +02:00
expect ( occupants [ 0 ] . querySelector ( '.occupant-nick' ) . textContent . trim ( ) ) . toBe ( "romeo" ) ;
2018-10-13 23:25:01 +02:00
expect ( occupants [ 0 ] . querySelectorAll ( '.badge' ) . length ) . toBe ( 2 ) ;
2019-08-12 20:16:34 +02:00
expect ( occupants [ 0 ] . querySelectorAll ( '.badge' ) [ 0 ] . textContent . trim ( ) ) . toBe ( 'Owner' ) ;
expect ( sizzle ( '.badge:last' , occupants [ 0 ] ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'Moderator' ) ;
2018-10-13 23:25:01 +02:00
var presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/moderatorman'
2018-10-13 23:25:01 +02:00
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : 'admin' ,
jid : contact _jid ,
role : 'moderator' ,
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.occupant-list li' ) . length > 1 , 500 ) ;
2018-10-13 23:25:01 +02:00
occupants = view . el . querySelectorAll ( '.occupant-list li' ) ;
expect ( occupants . length ) . toBe ( 2 ) ;
2019-06-03 07:58:51 +02:00
expect ( occupants [ 0 ] . querySelector ( '.occupant-nick' ) . textContent . trim ( ) ) . toBe ( "moderatorman" ) ;
expect ( occupants [ 1 ] . querySelector ( '.occupant-nick' ) . textContent . trim ( ) ) . toBe ( "romeo" ) ;
expect ( occupants [ 0 ] . querySelectorAll ( '.badge' ) . length ) . toBe ( 2 ) ;
2019-08-12 20:16:34 +02:00
expect ( occupants [ 0 ] . querySelectorAll ( '.badge' ) [ 0 ] . textContent . trim ( ) ) . toBe ( 'Admin' ) ;
expect ( occupants [ 0 ] . querySelectorAll ( '.badge' ) [ 1 ] . textContent . trim ( ) ) . toBe ( 'Moderator' ) ;
2018-10-13 23:25:01 +02:00
2019-06-03 07:58:51 +02:00
expect ( occupants [ 0 ] . getAttribute ( 'title' ) ) . toBe (
2018-10-13 23:25:01 +02:00
contact _jid + ' This user is a moderator. Click to mention moderatorman in your message.'
) ;
2019-06-03 07:58:51 +02:00
contact _jid = mock . cur _names [ 3 ] . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ;
2018-10-13 23:25:01 +02:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
from : 'lounge@montague.lit/visitorwoman'
2018-10-13 23:25:01 +02:00
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
jid : contact _jid ,
role : 'visitor' ,
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.occupant-list li' ) . length > 2 , 500 ) ;
2018-10-13 23:25:01 +02:00
occupants = view . el . querySelector ( '.occupant-list' ) . querySelectorAll ( 'li' ) ;
expect ( occupants . length ) . toBe ( 3 ) ;
expect ( occupants [ 2 ] . querySelector ( '.occupant-nick' ) . textContent . trim ( ) ) . toBe ( "visitorwoman" ) ;
expect ( occupants [ 2 ] . querySelectorAll ( '.badge' ) . length ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.badge' , occupants [ 2 ] ) . pop ( ) . textContent . trim ( ) ) . toBe ( 'Visitor' ) ;
2018-10-13 23:25:01 +02:00
expect ( occupants [ 2 ] . getAttribute ( 'title' ) ) . toBe (
contact _jid + ' This user can NOT send messages in this groupchat. Click to mention visitorwoman in your message.'
) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:34:36 +02:00
2018-10-10 22:28:32 +02:00
it ( "properly handles notification that a room has been destroyed" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-23 03:41:38 +02:00
async function ( done , _converse ) {
2018-10-10 22:28:32 +02:00
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoomViaModal ( _converse , 'problematic@muc.montague.lit' , 'romeo' )
2018-10-23 03:41:38 +02:00
const presence = $pres ( ) . attrs ( {
2019-06-03 07:58:51 +02:00
from : 'problematic@muc.montague.lit' ,
2018-10-23 03:41:38 +02:00
id : 'n13mt3l' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-23 03:41:38 +02:00
type : 'error' } )
. c ( 'error' ) . attrs ( { 'type' : 'cancel' } )
. c ( 'gone' ) . attrs ( { 'xmlns' : 'urn:ietf:params:xml:ns:xmpp-stanzas' } )
. t ( 'xmpp:other-room@chat.jabberfr.org?join' ) . up ( )
. c ( 'text' ) . attrs ( { 'xmlns' : 'urn:ietf:params:xml:ns:xmpp-stanzas' } )
. t ( "We didn't like the name" ) . nodeTree ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'problematic@muc.montague.lit' ) ;
2018-10-23 03:41:38 +02:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-msg' ) . textContent . trim ( ) )
2018-12-16 09:56:55 +01:00
. toBe ( 'This groupchat no longer exists' ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .destroyed-reason' ) . textContent . trim ( ) )
2018-10-23 03:41:38 +02:00
. toBe ( ` "We didn't like the name" ` ) ;
expect ( view . el . querySelector ( '.chatroom-body .moved-label' ) . textContent . trim ( ) )
. toBe ( 'The conversation has moved. Click below to enter.' ) ;
expect ( view . el . querySelector ( '.chatroom-body .moved-link' ) . textContent . trim ( ) )
. toBe ( ` other-room@chat.jabberfr.org ` ) ;
done ( ) ;
2018-10-10 22:28:32 +02:00
} ) ) ;
2017-07-11 10:41:11 +02:00
it ( "will use the user's reserved nickname, if it exists" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2018-07-30 18:16:32 +02:00
const IQ _stanzas = _converse . connection . IQ _stanzas ;
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'lounge' , 'montague.lit' , 'romeo' ) ;
2018-12-17 14:36:55 +01:00
2020-03-02 16:59:18 +01:00
let stanza = await u . waitUntil ( ( ) => IQ _stanzas . filter (
2019-05-20 12:38:33 +02:00
iq => iq . querySelector (
2019-07-03 14:18:46 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-05-20 12:38:33 +02:00
) ) . pop ( )
2018-11-09 11:55:34 +01:00
) ;
// We pretend this is a new room, so no disco info is returned.
const features _stanza = $iq ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit' ,
2018-11-09 11:55:34 +01:00
'id' : stanza . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-09 11:55:34 +01:00
'type' : 'error'
} ) . c ( 'error' , { 'type' : 'cancel' } )
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
/ * < i q f r o m = ' h a g 6 6 @ s h a k e s p e a r e . l i t / p d a '
* id = 'getnick1'
* to = 'coven@chat.shakespeare.lit'
* type = 'get' >
* < query xmlns = 'http://jabber.org/protocol/disco#info'
* node = 'x-roomuser-item' / >
* < / i q >
* /
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2018-09-13 10:51:56 +02:00
IQ _stanzas ,
2019-07-03 14:18:46 +02:00
s => sizzle ( ` iq[to=" ${ muc _jid } "] query[node="x-roomuser-item"] ` , s ) . length
2018-11-09 11:55:34 +01:00
) . pop ( )
) ;
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( iq ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq from="romeo@montague.lit/orchard" id=" ${ iq . getAttribute ( 'id' ) } " to="lounge@montague.lit" ` +
2018-11-09 11:55:34 +01:00
` type="get" xmlns="jabber:client"> ` +
` <query node="x-roomuser-item" xmlns="http://jabber.org/protocol/disco#info"/></iq> ` ) ;
/ * < i q f r o m = ' c o v e n @ c h a t . s h a k e s p e a r e . l i t '
* id = 'getnick1'
* to = 'hag66@shakespeare.lit/pda'
* type = 'result' >
* < query xmlns = 'http://jabber.org/protocol/disco#info'
* node = 'x-roomuser-item' >
* < identity
* category = 'conference'
* name = 'thirdwitch'
* type = 'text' / >
* < / q u e r y >
* < / i q >
* /
2019-12-08 20:42:09 +01:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-09 11:55:34 +01:00
stanza = $iq ( {
'type' : 'result' ,
2019-05-20 12:38:33 +02:00
'id' : iq . getAttribute ( 'id' ) ,
2018-11-09 11:55:34 +01:00
'from' : view . model . get ( 'jid' ) ,
'to' : _converse . connection . jid
} ) . c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' , 'node' : 'x-roomuser-item' } )
. c ( 'identity' , { 'category' : 'conference' , 'name' : 'thirdwitch' , 'type' : 'text' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
// The user has just entered the groupchat (because join was called)
// and receives their own presence from the server.
// See example 24:
2019-03-04 17:49:44 +01:00
// https://xmpp.org/extensions/xep-0045.html#enter-pres
2018-11-09 11:55:34 +01:00
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
from : 'lounge@montague.lit/thirdwitch' ,
2018-11-09 11:55:34 +01:00
id : 'DC352437-C019-40EC-B590-AF29E879AF97'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
2017-07-12 09:55:43 +02:00
. c ( 'item' ) . attrs ( {
affiliation : 'member' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/orchard' ,
2017-12-22 13:02:24 +01:00
role : 'participant'
2017-07-12 09:55:43 +02:00
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . up ( )
. c ( 'status' ) . attrs ( { code : '210' } ) . nodeTree ;
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-content .chat-info' ) . length ) ;
2019-08-12 20:16:34 +02:00
const info _text = sizzle ( '.chat-content .chat-info:first' , view . el ) . pop ( ) . textContent . trim ( ) ;
2018-11-09 11:55:34 +01:00
expect ( info _text ) . toBe ( 'Your nickname has been automatically set to thirdwitch' ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-07-20 01:59:52 +02:00
2018-07-25 12:05:09 +02:00
it ( "allows the user to invite their roster contacts to enter the groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'view_mode' : 'fullscreen' } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-24 14:29:15 +02:00
// We need roster contacts, so that we have someone to invite
await test _utils . waitForRoster ( _converse , 'current' ) ;
2019-02-18 15:23:26 +01:00
const features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
'muc_passwordprotected' ,
'muc_hidden' ,
'muc_temporary' ,
'muc_membersonly' ,
'muc_unmoderated' ,
'muc_anonymous'
]
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' , features ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-07-10 09:47:13 +02:00
expect ( view . model . getOwnAffiliation ( ) ) . toBe ( 'owner' ) ;
2019-02-18 15:23:26 +01:00
expect ( view . model . features . get ( 'open' ) ) . toBe ( false ) ;
2018-11-09 11:55:34 +01:00
2020-01-28 19:25:21 +01:00
expect ( view . el . querySelector ( '.open-invite-modal' ) ) . not . toBe ( null ) ;
2020-01-27 13:20:23 +01:00
// Members can't invite if the room isn't open
2019-07-10 09:47:13 +02:00
view . model . getOwnOccupant ( ) . set ( 'affiliation' , 'member' ) ;
2020-02-10 11:23:55 +01:00
2020-01-28 19:25:21 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.open-invite-modal' ) === null ) ;
2018-11-09 11:55:34 +01:00
2019-02-18 15:23:26 +01:00
view . model . features . set ( 'open' , 'true' ) ;
2020-01-28 19:25:21 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.open-invite-modal' ) ) ;
2020-01-27 13:20:23 +01:00
2020-01-28 19:25:21 +01:00
view . el . querySelector ( '.open-invite-modal' ) . click ( ) ;
2020-02-10 11:23:55 +01:00
const modal = view . muc _invite _modal ;
2020-01-27 13:20:23 +01:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
expect ( modal . el . querySelectorAll ( '#invitee_jids' ) . length ) . toBe ( 1 ) ;
expect ( modal . el . querySelectorAll ( 'textarea' ) . length ) . toBe ( 1 ) ;
2018-11-09 11:55:34 +01:00
spyOn ( view . model , 'directInvite' ) . and . callThrough ( ) ;
2020-01-27 13:20:23 +01:00
const input = modal . el . querySelector ( '#invitee_jids' ) ;
2019-06-03 07:58:51 +02:00
input . value = "Balt" ;
2020-01-27 13:20:23 +01:00
modal . el . querySelector ( 'button[type="submit"]' ) . click ( ) ;
await u . waitUntil ( ( ) => modal . el . querySelector ( '.error' ) ) ;
const error = modal . el . querySelector ( '.error' ) ;
expect ( error . textContent ) . toBe ( 'Please enter a valid XMPP address' ) ;
2018-11-09 11:55:34 +01:00
let evt = new Event ( 'input' ) ;
input . dispatchEvent ( evt ) ;
let sent _stanza ;
2019-05-20 12:38:33 +02:00
spyOn ( _converse . connection , 'send' ) . and . callFake ( stanza => ( sent _stanza = stanza ) ) ;
2020-01-27 13:20:23 +01:00
const hint = await u . waitUntil ( ( ) => modal . el . querySelector ( '.suggestion-box__results li' ) ) ;
2019-06-03 07:58:51 +02:00
expect ( input . value ) . toBe ( 'Balt' ) ;
2019-08-12 20:16:34 +02:00
expect ( hint . textContent . trim ( ) ) . toBe ( 'Balthasar' ) ;
2018-11-09 11:55:34 +01:00
2019-02-18 15:23:26 +01:00
evt = new Event ( 'mousedown' , { 'bubbles' : true } ) ;
2019-03-28 15:07:06 +01:00
evt . button = 0 ;
2019-02-18 15:23:26 +01:00
hint . dispatchEvent ( evt ) ;
2020-01-27 13:20:23 +01:00
const textarea = modal . el . querySelector ( 'textarea' ) ;
textarea . value = "Please join!" ;
modal . el . querySelector ( 'button[type="submit"]' ) . click ( ) ;
2019-02-18 15:23:26 +01:00
expect ( view . model . directInvite ) . toHaveBeenCalled ( ) ;
expect ( sent _stanza . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <message from="romeo@montague.lit/orchard" ` +
2019-02-18 15:23:26 +01:00
` id=" ${ sent _stanza . nodeTree . getAttribute ( "id" ) } " ` +
2019-06-03 07:58:51 +02:00
` to="balthasar@montague.lit" ` +
2019-02-18 15:23:26 +01:00
` xmlns="jabber:client"> ` +
2019-06-03 07:58:51 +02:00
` <x jid="lounge@montague.lit" reason="Please join!" xmlns="jabber:x:conference"/> ` +
2019-02-18 15:23:26 +01:00
` </message> `
) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2014-08-31 19:25:54 +02:00
2017-07-11 10:41:11 +02:00
it ( "can be joined automatically, based upon a received invite" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-24 14:29:15 +02:00
await test _utils . waitForRoster ( _converse , 'current' ) ; // We need roster contacts, who can invite us
const name = mock . cur _names [ 0 ] ;
const from _jid = name . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ;
await u . waitUntil ( ( ) => _converse . roster . get ( from _jid ) . vcard . get ( 'fullname' ) ) ;
2019-04-25 10:34:17 +02:00
spyOn ( window , 'confirm' ) . and . callFake ( ( ) => true ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-10-24 14:29:15 +02:00
await view . close ( ) ; // Hack, otherwise we have to mock stanzas.
2018-11-20 18:10:55 +01:00
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
2018-11-20 18:10:55 +01:00
const reason = "Please join this groupchat" ;
expect ( _converse . chatboxes . models . length ) . toBe ( 1 ) ;
expect ( _converse . chatboxes . models [ 0 ] . id ) . toBe ( "controlbox" ) ;
2019-02-12 14:21:45 +01:00
const stanza = u . toStanza ( `
< message xmlns = "jabber:client" to = "${_converse.bare_jid}" from = "${from_jid}" id = "9bceb415-f34b-4fa4-80d5-c0d076a24231" >
2019-07-03 14:18:46 +02:00
< x xmlns = "jabber:x:conference" jid = "${muc_jid}" reason = "${reason}" / >
2019-02-12 14:21:45 +01:00
< / m e s s a g e > ` ) ;
2019-10-24 14:29:15 +02:00
await _converse . onDirectMUCInvitation ( stanza ) ;
2018-11-20 18:10:55 +01:00
expect ( window . confirm ) . toHaveBeenCalledWith (
2019-07-03 14:18:46 +02:00
name + ' has invited you to join a groupchat: ' + muc _jid +
2018-11-20 18:10:55 +01:00
', and left the following reason: "' + reason + '"' ) ;
expect ( _converse . chatboxes . models . length ) . toBe ( 2 ) ;
expect ( _converse . chatboxes . models [ 0 ] . id ) . toBe ( 'controlbox' ) ;
2019-07-03 14:18:46 +02:00
expect ( _converse . chatboxes . models [ 1 ] . id ) . toBe ( muc _jid ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2014-09-02 20:01:49 +02:00
2017-07-11 10:41:11 +02:00
it ( "shows received groupchat messages" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2018-08-18 11:28:51 +02:00
const text = 'This is a received message' ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-08-01 10:26:35 +02:00
spyOn ( _converse . api , "trigger" ) . and . callThrough ( ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-10-13 23:25:01 +02:00
if ( ! view . el . querySelectorAll ( '.chat-area' ) . length ) {
view . renderChatArea ( ) ;
}
var nick = mock . chatroom _names [ 0 ] ;
view . model . occupants . create ( {
'nick' : nick ,
'muc_jid' : ` ${ view . model . get ( 'jid' ) } / ${ nick } `
2018-05-01 09:47:45 +02:00
} ) ;
2018-10-13 23:25:01 +02:00
const message = $msg ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/' + nick ,
2018-10-13 23:25:01 +02:00
id : '1' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
type : 'groupchat'
} ) . c ( 'body' ) . t ( text ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( message . nodeTree ) ;
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-msg' ) . length ) ;
2020-03-24 10:20:11 +01:00
expect ( view . content . querySelectorAll ( '.chat-msg' ) . length ) . toBe ( 1 ) ;
expect ( view . content . querySelector ( '.chat-msg__text' ) . textContent . trim ( ) ) . toBe ( text ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'message' , jasmine . any ( Object ) ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-12-16 18:19:25 +01:00
2017-07-11 10:41:11 +02:00
it ( "shows sent groupchat messages" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-08-01 10:26:35 +02:00
spyOn ( _converse . api , "trigger" ) . and . callThrough ( ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-10-13 23:25:01 +02:00
if ( ! view . el . querySelectorAll ( '.chat-area' ) . length ) {
view . renderChatArea ( ) ;
}
const text = 'This is a sent message' ;
const textarea = view . el . querySelector ( '.chat-textarea' ) ;
textarea . value = text ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-10-13 23:25:01 +02:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-10-13 23:25:01 +02:00
keyCode : 13
2017-07-12 09:55:43 +02:00
} ) ;
2019-10-09 16:01:38 +02:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2018-10-13 23:25:01 +02:00
2019-07-30 15:50:46 +02:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'messageSend' , jasmine . any ( _converse . Message ) ) ;
2020-03-24 10:20:11 +01:00
expect ( view . content . querySelectorAll ( '.chat-msg' ) . length ) . toBe ( 1 ) ;
2018-10-13 23:25:01 +02:00
// Let's check that if we receive the same message again, it's
// not shown.
2019-02-14 11:32:45 +01:00
const stanza = u . toStanza ( `
< message xmlns = "jabber:client"
2019-06-03 07:58:51 +02:00
from = "lounge@montague.lit/romeo"
2019-02-14 11:32:45 +01:00
to = "${_converse.connection.jid}"
type = "groupchat" >
< body > $ { text } < / b o d y >
< stanza - id xmlns = "urn:xmpp:sid:0"
id = "5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
2019-06-03 07:58:51 +02:00
by = "lounge@montague.lit" / >
2019-02-14 11:32:45 +01:00
< origin - id xmlns = "urn:xmpp:sid:0" id = "${view.model.messages.at(0).get('origin_id')}" / >
< / m e s s a g e > ` ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( stanza ) ;
2020-03-24 10:20:11 +01:00
expect ( view . content . querySelectorAll ( '.chat-msg' ) . length ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.chat-msg__text:last' ) . pop ( ) . textContent . trim ( ) ) . toBe ( text ) ;
2018-10-13 23:25:01 +02:00
expect ( view . model . messages . length ) . toBe ( 1 ) ;
// We don't emit an event if it's our own message
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger . calls . count ( ) , 1 ) ;
2018-10-13 23:25:01 +02:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-05-25 11:22:27 +02:00
2017-07-11 10:41:11 +02:00
it ( "will cause the chat area to be scrolled down only if it was at the bottom already" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-13 23:25:01 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-24 14:29:15 +02:00
const message = 'This message is received while the chat area is scrolled up' ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-10-24 14:29:15 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-10-13 23:25:01 +02:00
spyOn ( view , 'scrollDown' ) . and . callThrough ( ) ;
// Create enough messages so that there's a scrollbar.
const promises = [ ] ;
2019-10-24 14:29:15 +02:00
for ( let i = 0 ; i < 20 ; i ++ ) {
promises . push (
2020-03-02 16:59:18 +01:00
view . model . queueMessage (
2019-10-24 14:29:15 +02:00
$msg ( {
from : 'lounge@montague.lit/someone' ,
to : 'romeo@montague.lit.com' ,
type : 'groupchat' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-10-24 14:29:15 +02:00
} ) . c ( 'body' ) . t ( 'Message: ' + i ) . tree ( ) )
) ;
2018-10-13 23:25:01 +02:00
}
await Promise . all ( promises ) ;
// Give enough time for `markScrolled` to have been called
setTimeout ( async ( ) => {
view . content . scrollTop = 0 ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage (
2018-10-13 23:25:01 +02:00
$msg ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/someone' ,
to : 'romeo@montague.lit.com' ,
2018-10-13 23:25:01 +02:00
type : 'groupchat' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2018-10-13 23:25:01 +02:00
} ) . c ( 'body' ) . t ( message ) . tree ( ) ) ;
2020-03-02 16:59:18 +01:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2018-10-13 23:25:01 +02:00
// Now check that the message appears inside the chatbox in the DOM
2020-03-24 10:20:11 +01:00
const msg _txt = sizzle ( '.chat-msg:last .chat-msg__text' , view . content ) . pop ( ) . textContent ;
2018-10-13 23:25:01 +02:00
expect ( msg _txt ) . toEqual ( message ) ;
expect ( view . content . scrollTop ) . toBe ( 0 ) ;
done ( ) ;
} , 500 ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-05-28 10:55:03 +02:00
2019-06-12 18:03:41 +02:00
it ( "reconnects when no-acceptable error is returned when sending a message" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2019-06-12 18:03:41 +02:00
async function ( done , _converse ) {
2019-07-03 14:54:50 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2019-12-08 20:42:09 +01:00
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . ENTERED ) ;
2019-06-12 18:03:41 +02:00
await test _utils . sendMessage ( view , 'hello world' ) ;
const stanza = u . toStanza ( `
< message xmlns = 'jabber:client'
2019-07-03 14:54:50 +02:00
from = '${muc_jid}'
2019-06-12 18:03:41 +02:00
type = 'error'
to = '${_converse.bare_jid}' >
< error type = 'cancel' >
< not - acceptable xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' / >
< / e r r o r >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
let sent _stanzas = _converse . connection . sent _stanzas ;
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => sent _stanzas . filter ( s => sizzle ( ` [xmlns=" ${ Strophe . NS . PING } "] ` , s ) . length ) . pop ( ) ) ;
2019-06-12 18:03:41 +02:00
expect ( Strophe . serialize ( iq ) ) . toBe (
` <iq id=" ${ iq . getAttribute ( 'id' ) } " to="coven@chat.shakespeare.lit/romeo" type="get" xmlns="jabber:client"> ` +
` <ping xmlns="urn:xmpp:ping"/> ` +
` </iq> ` ) ;
const result = u . toStanza ( `
2019-07-03 14:54:50 +02:00
< iq from = '${muc_jid}'
2019-06-12 18:03:41 +02:00
id = '${iq.getAttribute(' id ')}'
to = '${_converse.bare_jid}'
type = 'error' >
< error type = 'cancel' >
< not - acceptable xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' / >
< / e r r o r >
< / i q > ` ) ;
sent _stanzas = _converse . connection . sent _stanzas ;
2019-06-20 12:04:05 +02:00
const index = sent _stanzas . length - 1 ;
2019-12-08 20:42:09 +01:00
_converse . connection . IQ _stanzas = [ ] ;
2019-06-12 18:03:41 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
2019-12-08 20:42:09 +01:00
await test _utils . getRoomFeatures ( _converse , muc _jid ) ;
2019-06-20 12:04:05 +02:00
2019-07-11 22:50:30 +02:00
const pres = await u . waitUntil (
2019-06-20 12:04:05 +02:00
( ) => sent _stanzas . slice ( index ) . filter ( s => s . nodeName === 'presence' ) . pop ( ) ) ;
2019-06-12 18:03:41 +02:00
expect ( Strophe . serialize ( pres ) ) . toBe (
` <presence from=" ${ _converse . jid } " to="coven@chat.shakespeare.lit/romeo" xmlns="jabber:client"> ` +
` <x xmlns="http://jabber.org/protocol/muc"><history maxstanzas="0"/></x> ` +
` </presence> ` ) ;
done ( ) ;
} ) ) ;
it ( "informs users if the room configuration has changed" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2019-06-12 18:03:41 +02:00
async function ( done , _converse ) {
2019-07-03 14:54:50 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'coven@chat.shakespeare.lit' , 'romeo' ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . ENTERED ) ;
2019-06-12 18:03:41 +02:00
const stanza = u . toStanza ( `
2019-07-03 14:54:50 +02:00
< message from = '${muc_jid}'
2019-06-12 18:03:41 +02:00
id = '80349046-F26A-44F3-A7A6-54825064DD9E'
to = '${_converse.jid}'
type = 'groupchat' >
< x xmlns = 'http://jabber.org/protocol/muc#user' >
< status code = '170' / >
< / x >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-content .chat-info' ) . length ) ;
2019-06-12 18:03:41 +02:00
const info _messages = view . el . querySelectorAll ( '.chat-content .chat-info' ) ;
2020-03-31 22:43:55 +02:00
expect ( info _messages [ 0 ] . textContent . trim ( ) ) . toBe ( 'Groupchat logging is now enabled' ) ;
2019-06-12 18:03:41 +02:00
done ( ) ;
} ) ) ;
2019-06-11 12:16:27 +02:00
it ( "informs users if their nicknames have been changed." ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-09 11:55:34 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2014-09-06 12:25:37 +02:00
/ * T h e s e r v i c e t h e n s e n d s t w o p r e s e n c e s t a n z a s t o t h e f u l l J I D
* of each occupant ( including the occupant who is changing his
* or her room nickname ) , one of type "unavailable" for the old
* nickname and one indicating availability for the new
* nickname .
*
2019-03-04 17:49:44 +01:00
* See : https : //xmpp.org/extensions/xep-0045.html#changenick
2014-09-06 12:25:37 +02:00
*
* < presence
2019-06-03 07:58:51 +02:00
* from = 'coven@montague.lit/thirdwitch'
2014-09-06 12:25:37 +02:00
* id = 'DC352437-C019-40EC-B590-AF29E879AF98'
* to = 'hag66@shakespeare.lit/pda'
* type = 'unavailable' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* nick = 'oldhag'
2017-12-22 13:02:24 +01:00
* role = 'participant' / >
2014-09-06 12:25:37 +02:00
* < status code = '303' / >
* < status code = '110' / >
* < / x >
* < / p r e s e n c e >
2015-03-01 11:22:37 +01:00
*
2014-09-06 12:25:37 +02:00
* < presence
2019-06-03 07:58:51 +02:00
* from = 'coven@montague.lit/oldhag'
2014-09-06 12:25:37 +02:00
* id = '5B4F27A4-25ED-43F7-A699-382C6B4AFC67'
* to = 'hag66@shakespeare.lit/pda' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
2017-12-22 13:02:24 +01:00
* role = 'participant' / >
2014-09-06 12:25:37 +02:00
* < status code = '110' / >
* < / x >
* < / p r e s e n c e >
* /
2018-10-13 17:47:52 +02:00
const _ _ = _converse . _ _ ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'oldnick' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . ENTERED ) ;
2015-03-01 11:22:37 +01:00
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( 'li .occupant-nick' ) . length , 500 ) ;
2018-11-09 11:55:34 +01:00
let occupants = view . el . querySelector ( '.occupant-list' ) ;
2020-01-26 18:36:25 +01:00
expect ( occupants . childElementCount ) . toBe ( 1 ) ;
2018-11-09 11:55:34 +01:00
expect ( occupants . firstElementChild . querySelector ( '.occupant-nick' ) . textContent . trim ( ) ) . toBe ( "oldnick" ) ;
2016-07-19 15:24:22 +02:00
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "oldnick has entered the groupchat" ) ;
2014-09-06 12:25:37 +02:00
2018-11-09 11:55:34 +01:00
let presence = $pres ( ) . attrs ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/oldnick' ,
2018-11-09 11:55:34 +01:00
id : 'DC352437-C019-40EC-B590-AF29E879AF98' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-11-09 11:55:34 +01:00
type : 'unavailable'
} )
. c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : 'owner' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/pda' ,
2018-11-09 11:55:34 +01:00
nick : 'newnick' ,
role : 'moderator'
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '303' } ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . nodeTree ;
2015-03-01 11:22:37 +01:00
2018-11-09 11:55:34 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-info' ) . length ) ;
2019-06-11 12:16:27 +02:00
2019-08-12 20:16:34 +02:00
expect ( sizzle ( 'div.chat-info:last' ) . pop ( ) . textContent . trim ( ) ) . toBe (
2018-11-09 11:55:34 +01:00
_ _ ( _converse . muc . new _nickname _messages [ "303" ] , "newnick" )
) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . ENTERED ) ;
2017-07-12 09:55:43 +02:00
2018-11-09 11:55:34 +01:00
occupants = view . el . querySelector ( '.occupant-list' ) ;
2020-01-26 18:36:25 +01:00
expect ( occupants . childElementCount ) . toBe ( 1 ) ;
2017-07-12 09:55:43 +02:00
2018-11-09 11:55:34 +01:00
presence = $pres ( ) . attrs ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/newnick' ,
2018-11-09 11:55:34 +01:00
id : '5B4F27A4-25ED-43F7-A699-382C6B4AFC67' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda'
2018-11-09 11:55:34 +01:00
} )
. c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : 'owner' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/pda' ,
2018-11-09 11:55:34 +01:00
role : 'moderator'
} ) . up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-12-10 15:40:33 +01:00
expect ( view . model . session . get ( 'connection_status' ) ) . toBe ( converse . ROOMSTATUS . ENTERED ) ;
2020-03-31 22:43:55 +02:00
expect ( view . content . querySelectorAll ( 'div.chat-info' ) . length ) . toBe ( 1 ) ;
expect ( sizzle ( 'div.chat-info' , view . content ) [ 0 ] . textContent . trim ( ) ) . toBe (
2018-11-09 11:55:34 +01:00
_ _ ( _converse . muc . new _nickname _messages [ "303" ] , "newnick" )
) ;
occupants = view . el . querySelector ( '.occupant-list' ) ;
2020-01-26 18:36:25 +01:00
expect ( occupants . childElementCount ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.occupant-nick:first' , occupants ) . pop ( ) . textContent . trim ( ) ) . toBe ( "newnick" ) ;
2018-11-09 11:55:34 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2014-09-06 12:46:24 +02:00
2018-07-02 15:54:51 +02:00
it ( "queries for the groupchat information before attempting to join the user" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2018-09-13 10:51:56 +02:00
const IQ _stanzas = _converse . connection . IQ _stanzas ;
2019-07-03 14:18:46 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2016-12-05 07:03:44 +01:00
2019-07-03 14:18:46 +02:00
await _converse . api . rooms . open ( muc _jid , { 'nick' : 'some1' } ) ;
2019-07-11 22:50:30 +02:00
const stanza = await u . waitUntil ( ( ) => _ . filter (
2018-11-20 18:10:55 +01:00
IQ _stanzas ,
2019-05-20 12:38:33 +02:00
iq => iq . querySelector (
2019-07-03 14:18:46 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2018-11-20 18:10:55 +01:00
) ) . pop ( ) ) ;
// Check that the groupchat queried for the feautures.
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( stanza ) ) . toBe (
2019-07-03 14:18:46 +02:00
` <iq from="romeo@montague.lit/orchard" id=" ${ stanza . getAttribute ( "id" ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/disco#info"/> ` +
` </iq> ` ) ;
/ * < i q f r o m = ' c o v e n @ c h a t . s h a k e s p e a r e . l i t '
* id = 'ik3vs715'
* to = 'hag66@shakespeare.lit/pda'
* type = 'result' >
* < query xmlns = 'http://jabber.org/protocol/disco#info' >
* < identity
* category = 'conference'
* name = 'A Dark Cave'
* type = 'text' / >
* < feature var = 'http://jabber.org/protocol/muc' / >
* < feature var = 'muc_passwordprotected' / >
* < feature var = 'muc_hidden' / >
* < feature var = 'muc_temporary' / >
* < feature var = 'muc_open' / >
* < feature var = 'muc_unmoderated' / >
* < feature var = 'muc_nonanonymous' / >
* < / q u e r y >
* < / i q >
* /
const features _stanza = $iq ( {
2019-07-03 14:18:46 +02:00
'from' : muc _jid ,
2018-11-20 18:10:55 +01:00
'id' : stanza . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-20 18:10:55 +01:00
'type' : 'result'
} )
. c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , {
'category' : 'conference' ,
'name' : 'A Dark Cave' ,
'type' : 'text'
} ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_passwordprotected' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_hidden' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_temporary' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_open' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_unmoderated' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_nonanonymous' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
let view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2018-11-20 18:10:55 +01:00
view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2019-01-10 12:14:45 +01:00
expect ( view . model . features . get ( 'fetched' ) ) . toBeTruthy ( ) ;
expect ( view . model . features . get ( 'passwordprotected' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'hidden' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'temporary' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'open' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'unmoderated' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'nonanonymous' ) ) . toBe ( true ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2016-12-05 07:03:44 +01:00
} ) ) ;
2018-07-02 15:54:51 +02:00
it ( "updates the shown features when the groupchat configuration has changed" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { 'view_mode' : 'fullscreen' } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2018-12-17 14:39:58 +01:00
let features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
'muc_passwordprotected' ,
'muc_publicroom' ,
'muc_temporary' ,
'muc_open' ,
'muc_unmoderated' ,
'muc_nonanonymous'
] ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'room@conference.example.org' , 'romeo' , features ) ;
2018-12-17 14:39:58 +01:00
const jid = 'room@conference.example.org' ;
2020-01-28 19:25:21 +01:00
const view = _converse . chatboxviews . get ( jid ) ;
const info _el = view . el . querySelector ( ".show-room-details-modal" ) ;
info _el . click ( ) ;
const modal = view . model . room _details _modal ;
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
let features _list = modal . el . querySelector ( '.features-list' ) ;
2018-12-17 14:39:58 +01:00
let features _shown = features _list . textContent . split ( '\n' ) . map ( s => s . trim ( ) ) . filter ( s => s ) ;
2020-01-28 19:25:21 +01:00
expect ( features _shown . join ( ' ' ) ) . toBe (
'Password protected - This groupchat requires a password before entry ' +
'Open - Anyone can join this groupchat ' +
'Temporary - This groupchat will disappear once the last person leaves ' +
'Not anonymous - All other groupchat participants can see your XMPP address ' +
'Not moderated - Participants entering this groupchat can write right away' ) ;
expect ( view . model . features . get ( 'hidden' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'mam_enabled' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'membersonly' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'moderated' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'nonanonymous' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'open' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'passwordprotected' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'persistent' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'publicroom' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'semianonymous' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'temporary' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'unmoderated' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'unsecured' ) ) . toBe ( false ) ;
expect ( view . el . querySelector ( '.chatbox-title__text' ) . textContent . trim ( ) ) . toBe ( 'Room' ) ;
view . el . querySelector ( '.configure-chatroom-button' ) . click ( ) ;
2018-12-17 14:39:58 +01:00
const IQs = _converse . connection . IQ _stanzas ;
2019-07-11 22:50:30 +02:00
let iq = await u . waitUntil ( ( ) => _ . filter (
2018-12-17 14:39:58 +01:00
IQs ,
2019-05-20 12:38:33 +02:00
iq => iq . querySelector (
2018-12-17 14:39:58 +01:00
` iq[to=" ${ jid } "] query[xmlns=" ${ Strophe . NS . MUC _OWNER } "] `
) ) . pop ( ) ) ;
2019-02-12 14:21:45 +01:00
const response _el = u . toStanza (
2018-12-17 14:39:58 +01:00
` <iq xmlns="jabber:client"
type = "result"
2019-06-03 07:58:51 +02:00
to = "romeo@montague.lit/pda"
2019-05-20 12:38:33 +02:00
from = "room@conference.example.org" id = "${iq.getAttribute('id')}" >
2018-12-17 14:39:58 +01:00
< query xmlns = "http://jabber.org/protocol/muc#owner" >
< x xmlns = "jabber:x:data" type = "form" >
< title > Configuration for room @ conference . example . org < / t i t l e >
< instructions > Complete and submit this form to configure the room . < / i n s t r u c t i o n s >
< field var = "FORM_TYPE" type = "hidden" >
< value > http : //jabber.org/protocol/muc#roomconfig</value>
< / f i e l d >
< field type = "fixed" >
< value > Room information < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_roomname" type = "text-single" label = "Title" >
2018-12-18 11:21:36 +01:00
< value > Room < / v a l u e >
2018-12-17 14:39:58 +01:00
< / f i e l d >
< field var = "muc#roomconfig_roomdesc" type = "text-single" label = "Description" >
< desc > A brief description of the room < / d e s c >
< value > This room is used in tests < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_lang" type = "text-single" label = "Language tag for room (e.g. 'en', 'de', 'fr' etc.)" >
< desc > Indicate the primary language spoken in this room < / d e s c >
< value > en < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_persistentroom" type = "boolean" label = "Persistent (room should remain even when it is empty)" >
< desc > Rooms are automatically deleted when they are empty , unless this option is enabled < / d e s c >
< value > 1 < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_publicroom" type = "boolean" label = "Include room information in public lists" >
< desc > Enable this to allow people to find the room < / d e s c >
< value > 1 < / v a l u e >
< / f i e l d >
< field type = "fixed" > < value > Access to the room < / v a l u e > < / f i e l d >
< field var = "muc#roomconfig_roomsecret" type = "text-private" label = "Password" > < value / > < / f i e l d >
< field var = "muc#roomconfig_membersonly" type = "boolean" label = "Only allow members to join" >
< desc > Enable this to only allow access for room owners , admins and members < / d e s c >
< / f i e l d >
< field var = "{http://prosody.im/protocol/muc}roomconfig_allowmemberinvites" type = "boolean" label = "Allow members to invite new members" / >
< field type = "fixed" > < value > Permissions in the room < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_changesubject" type = "boolean" label = "Allow anyone to set the room's subject" >
< desc > Choose whether anyone , or only moderators , may set the room ' s subject < / d e s c >
< / f i e l d >
< field var = "muc#roomconfig_moderatedroom" type = "boolean" label = "Moderated (require permission to speak)" >
< desc > In moderated rooms occupants must be given permission to speak by a room moderator < / d e s c >
< / f i e l d >
< field var = "muc#roomconfig_whois" type = "list-single" label = "Addresses (JIDs) of room occupants may be viewed by:" >
< option label = "Moderators only" > < value > moderators < / v a l u e > < / o p t i o n >
< option label = "Anyone" > < value > anyone < / v a l u e > < / o p t i o n >
< value > anyone < / v a l u e >
< / f i e l d >
< field type = "fixed" > < value > Other options < / v a l u e > < / f i e l d >
< field var = "muc#roomconfig_historylength" type = "text-single" label = "Maximum number of history messages returned by room" >
< desc > Specify the maximum number of previous messages that should be sent to users when they join the room < / d e s c >
< value > 50 < / v a l u e >
< / f i e l d >
< field var = "muc#roomconfig_defaulthistorymessages" type = "text-single" label = "Default number of history messages returned by room" >
< desc > Specify the number of previous messages sent to new users when they join the room < / d e s c >
< value > 20 < / v a l u e >
< / f i e l d >
< / x >
< / q u e r y >
< / i q > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( response _el ) ) ;
2019-07-11 22:50:30 +02:00
const el = await u . waitUntil ( ( ) => document . querySelector ( '.chatroom-form legend' ) ) ;
2019-08-12 20:16:34 +02:00
expect ( el . textContent . trim ( ) ) . toBe ( "Configuration for room@conference.example.org" ) ;
2020-01-28 19:25:21 +01:00
sizzle ( '[name="muc#roomconfig_membersonly"]' , view . el ) . pop ( ) . click ( ) ;
sizzle ( '[name="muc#roomconfig_roomname"]' , view . el ) . pop ( ) . value = "New room name"
view . el . querySelector ( '.chatroom-form input[type="submit"]' ) . click ( ) ;
2018-12-17 14:39:58 +01:00
2019-07-11 22:50:30 +02:00
iq = await u . waitUntil ( ( ) => _ . filter ( IQs , iq => u . matchesSelector ( iq , ` iq[to=" ${ jid } "][type="set"] ` ) ) . pop ( ) ) ;
2018-12-17 14:39:58 +01:00
const result = $iq ( {
"xmlns" : "jabber:client" ,
"type" : "result" ,
2019-06-03 07:58:51 +02:00
"to" : "romeo@montague.lit/orchard" ,
"from" : "lounge@muc.montague.lit" ,
2019-05-20 12:38:33 +02:00
"id" : iq . getAttribute ( 'id' )
2018-11-20 18:10:55 +01:00
} ) ;
2018-12-17 14:39:58 +01:00
IQs . length = 0 ; // Empty the array
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
2018-11-20 18:10:55 +01:00
2019-07-11 22:50:30 +02:00
iq = await u . waitUntil ( ( ) => _ . filter (
2018-12-17 14:39:58 +01:00
IQs ,
2019-05-20 12:38:33 +02:00
iq => iq . querySelector (
2018-12-17 14:39:58 +01:00
` iq[to=" ${ jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
) ) . pop ( ) ) ;
2018-11-20 18:10:55 +01:00
2018-12-17 14:39:58 +01:00
const features _stanza = $iq ( {
'from' : jid ,
2019-05-20 12:38:33 +02:00
'id' : iq . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-12-17 14:39:58 +01:00
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , {
'category' : 'conference' ,
2018-12-18 11:21:36 +01:00
'name' : 'New room name' ,
2018-12-17 14:39:58 +01:00
'type' : 'text'
} ) . up ( ) ;
features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
'muc_passwordprotected' ,
'muc_hidden' ,
'muc_temporary' ,
2019-01-10 12:14:45 +01:00
'muc_membersonly' ,
2018-12-17 14:39:58 +01:00
'muc_unmoderated' ,
'muc_nonanonymous'
] ;
features . forEach ( f => features _stanza . c ( 'feature' , { 'var' : f } ) . up ( ) ) ;
features _stanza . c ( 'x' , { 'xmlns' : 'jabber:x:data' , 'type' : 'result' } )
. c ( 'field' , { 'var' : 'FORM_TYPE' , 'type' : 'hidden' } )
. c ( 'value' ) . t ( 'http://jabber.org/protocol/muc#roominfo' ) . up ( ) . up ( )
. c ( 'field' , { 'type' : 'text-single' , 'var' : 'muc#roominfo_description' , 'label' : 'Description' } )
. c ( 'value' ) . t ( 'This is the description' ) . up ( ) . up ( )
. c ( 'field' , { 'type' : 'text-single' , 'var' : 'muc#roominfo_occupants' , 'label' : 'Number of occupants' } )
. c ( 'value' ) . t ( 0 ) ;
2019-01-10 12:14:45 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2018-12-17 14:39:58 +01:00
2020-01-28 19:25:21 +01:00
await u . waitUntil ( ( ) => new Promise ( success => view . model . features . on ( 'change' , success ) ) ) ;
features _list = modal . el . querySelector ( '.features-list' ) ;
2018-12-17 14:39:58 +01:00
features _shown = features _list . textContent . split ( '\n' ) . map ( s => s . trim ( ) ) . filter ( s => s ) ;
2020-01-28 19:25:21 +01:00
expect ( features _shown . join ( ' ' ) ) . toBe (
'Password protected - This groupchat requires a password before entry ' +
'Hidden - This groupchat is not publicly searchable ' +
'Members only - This groupchat is restricted to members only ' +
'Temporary - This groupchat will disappear once the last person leaves ' +
'Not anonymous - All other groupchat participants can see your XMPP address ' +
'Not moderated - Participants entering this groupchat can write right away' ) ;
expect ( view . model . features . get ( 'hidden' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'mam_enabled' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'membersonly' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'moderated' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'nonanonymous' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'open' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'passwordprotected' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'persistent' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'publicroom' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'semianonymous' ) ) . toBe ( false ) ;
expect ( view . model . features . get ( 'temporary' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'unmoderated' ) ) . toBe ( true ) ;
expect ( view . model . features . get ( 'unsecured' ) ) . toBe ( false ) ;
2020-04-06 14:27:44 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chatbox-title__text' ) ? . textContent . trim ( ) === 'New room name' ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-03-19 19:23:02 +01:00
} ) ) ;
2017-07-11 10:41:11 +02:00
it ( "indicates when a room is no longer anonymous" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-09 16:01:38 +02:00
let IQ _id ;
2018-10-13 17:47:52 +02:00
const sendIQ = _converse . connection . sendIQ ;
2016-12-05 07:03:44 +01:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'coven@chat.shakespeare.lit' , 'some1' ) ;
2018-11-20 18:10:55 +01:00
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2016-12-05 07:03:44 +01:00
2018-11-20 18:10:55 +01:00
// We pretend this is a new room, so no disco info is returned.
const features _stanza = $iq ( {
from : 'coven@chat.shakespeare.lit' ,
'id' : IQ _id ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-20 18:10:55 +01:00
'type' : 'error'
} ) . c ( 'error' , { 'type' : 'cancel' } )
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
/ * < m e s s a g e x m l n s = " j a b b e r : c l i e n t "
* type = "groupchat"
2019-06-03 07:58:51 +02:00
* to = "romeo@montague.lit/_converse.js-27854181"
2018-11-20 18:10:55 +01:00
* from = "coven@chat.shakespeare.lit" >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
* < status code = "104" / >
* < status code = "172" / >
* < / x >
* < / m e s s a g e >
* /
const message = $msg ( {
type : 'groupchat' ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-27854181' ,
2018-11-20 18:10:55 +01:00
from : 'coven@chat.shakespeare.lit'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'status' , { code : '104' } ) . up ( )
. c ( 'status' , { code : '172' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( message ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-content .chat-info' ) . length ) ;
2018-11-20 18:10:55 +01:00
const chat _body = view . el . querySelector ( '.chatroom-body' ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.message:last' , chat _body ) . pop ( ) . textContent . trim ( ) )
2018-11-20 18:10:55 +01:00
. toBe ( 'This groupchat is now no longer anonymous' ) ;
done ( ) ;
2016-12-02 18:41:05 +01:00
} ) ) ;
2018-07-25 12:05:09 +02:00
it ( "informs users if they have been kicked out of the groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2014-09-06 12:46:24 +02:00
/ * < p r e s e n c e
* from = 'harfleur@chat.shakespeare.lit/pistol'
* to = 'pistol@shakespeare.lit/harfleur'
* type = 'unavailable' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'none' role = 'none' >
2016-12-03 17:39:59 +01:00
* < actor nick = 'Fluellen' / >
* < reason > Avaunt , you cullion ! < / r e a s o n >
2014-09-06 12:46:24 +02:00
* < / i t e m >
2016-12-03 17:39:59 +01:00
* < status code = '110' / >
2014-09-06 12:46:24 +02:00
* < status code = '307' / >
* < / x >
* < / p r e s e n c e >
* /
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2018-11-20 18:10:55 +01:00
var presence = $pres ( ) . attrs ( {
2019-06-03 07:58:51 +02:00
from : 'lounge@montague.lit/romeo' ,
to : 'romeo@montague.lit/pda' ,
2018-11-20 18:10:55 +01:00
type : 'unavailable'
} )
. c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' ) . attrs ( {
affiliation : 'none' ,
2019-06-03 07:58:51 +02:00
jid : 'romeo@montague.lit/pda' ,
2018-11-20 18:10:55 +01:00
role : 'none'
} )
. c ( 'actor' ) . attrs ( { nick : 'Fluellen' } ) . up ( )
. c ( 'reason' ) . t ( 'Avaunt, you cullion!' ) . up ( )
. up ( )
. c ( 'status' ) . attrs ( { code : '110' } ) . up ( )
. c ( 'status' ) . attrs ( { code : '307' } ) . nodeTree ;
2019-06-11 12:16:27 +02:00
2018-11-20 18:10:55 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2017-07-12 09:55:43 +02:00
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-20 18:10:55 +01:00
expect ( u . isVisible ( view . el . querySelector ( '.chat-area' ) ) ) . toBeFalsy ( ) ;
expect ( u . isVisible ( view . el . querySelector ( '.occupants' ) ) ) . toBeFalsy ( ) ;
const chat _body = view . el . querySelector ( '.chatroom-body' ) ;
expect ( chat _body . querySelectorAll ( '.disconnect-msg' ) . length ) . toBe ( 3 ) ;
2019-08-12 20:16:34 +02:00
expect ( chat _body . querySelector ( '.disconnect-msg:first-child' ) . textContent . trim ( ) ) . toBe (
2018-11-20 18:10:55 +01:00
'You have been kicked from this groupchat' ) ;
2019-08-12 20:16:34 +02:00
expect ( chat _body . querySelector ( '.disconnect-msg:nth-child(2)' ) . textContent . trim ( ) ) . toBe (
2018-11-20 18:10:55 +01:00
'This action was done by Fluellen.' ) ;
2019-08-12 20:16:34 +02:00
expect ( chat _body . querySelector ( '.disconnect-msg:nth-child(3)' ) . textContent . trim ( ) ) . toBe (
2018-11-20 18:10:55 +01:00
'The reason given is: "Avaunt, you cullion!".' ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2014-09-06 12:25:37 +02:00
2018-11-20 18:10:55 +01:00
2017-07-11 10:41:11 +02:00
it ( "can be saved to, and retrieved from, browserStorage" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'lounge' , 'montague.lit' , 'romeo' ) ;
2018-11-20 18:10:55 +01:00
// We instantiate a new ChatBoxes collection, which by default
// will be empty.
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2018-11-20 18:10:55 +01:00
const newchatboxes = new _converse . ChatBoxes ( ) ;
expect ( newchatboxes . length ) . toEqual ( 0 ) ;
// The chatboxes will then be fetched from browserStorage inside the
// onConnected method
newchatboxes . onConnected ( ) ;
2019-10-24 14:29:15 +02:00
await new Promise ( resolve => _converse . api . listen . once ( 'chatBoxesFetched' , resolve ) ) ;
2018-11-20 18:10:55 +01:00
expect ( newchatboxes . length ) . toEqual ( 2 ) ;
// Check that the chatrooms retrieved from browserStorage
// have the same attributes values as the original ones.
const attrs = [ 'id' , 'box_id' , 'visible' ] ;
let new _attrs , old _attrs ;
for ( var i = 0 ; i < attrs . length ; i ++ ) {
new _attrs = _ . map ( _ . map ( newchatboxes . models , 'attributes' ) , attrs [ i ] ) ;
old _attrs = _ . map ( _ . map ( _converse . chatboxes . models , 'attributes' ) , attrs [ i ] ) ;
// FIXME: should have have to sort here? Order must
// probably be the same...
// This should be fixed once the controlbox always opens
// only on the right.
expect ( _ . isEqual ( new _attrs . sort ( ) , old _attrs . sort ( ) ) ) . toEqual ( true ) ;
}
_converse . rosterview . render ( ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2017-07-11 10:41:11 +02:00
it ( "can be minimized by clicking a DOM element with class 'toggle-chatbox-button'" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-26 10:15:01 +02:00
async function ( done , _converse ) {
2017-08-29 12:29:16 +02:00
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'lounge' , 'montague.lit' , 'romeo' ) ;
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ,
2018-10-26 10:15:01 +02:00
trimmed _chatboxes = _converse . minimized _chats ;
2018-07-30 18:16:32 +02:00
2019-06-26 17:31:53 +02:00
spyOn ( view , 'onMinimized' ) . and . callThrough ( ) ;
spyOn ( view , 'onMaximized' ) . and . callThrough ( ) ;
2019-08-01 10:26:35 +02:00
spyOn ( _converse . api , "trigger" ) . and . callThrough ( ) ;
2018-10-26 10:15:01 +02:00
view . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
2020-03-31 22:43:55 +02:00
const button = await u . waitUntil ( ( ) => view . el . querySelector ( '.toggle-chatbox-button' ) ) ;
button . click ( ) ;
2018-10-26 10:15:01 +02:00
2019-06-26 17:31:53 +02:00
expect ( view . onMinimized ) . toHaveBeenCalled ( ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'chatBoxMinimized' , jasmine . any ( Object ) ) ;
2018-10-26 10:15:01 +02:00
expect ( u . isVisible ( view . el ) ) . toBeFalsy ( ) ;
expect ( view . model . get ( 'minimized' ) ) . toBeTruthy ( ) ;
2019-06-26 17:31:53 +02:00
expect ( view . onMinimized ) . toHaveBeenCalled ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => trimmed _chatboxes . get ( view . model . get ( 'id' ) ) ) ;
2018-10-26 10:15:01 +02:00
const trimmedview = trimmed _chatboxes . get ( view . model . get ( 'id' ) ) ;
trimmedview . el . querySelector ( "a.restore-chat" ) . click ( ) ;
2019-06-26 17:31:53 +02:00
expect ( view . onMaximized ) . toHaveBeenCalled ( ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'chatBoxMaximized' , jasmine . any ( Object ) ) ;
2018-10-26 10:15:01 +02:00
expect ( view . model . get ( 'minimized' ) ) . toBeFalsy ( ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger . calls . count ( ) , 3 ) ;
2018-10-26 10:15:01 +02:00
done ( ) ;
2018-08-09 14:52:03 +02:00
2016-11-03 11:01:09 +01:00
} ) ) ;
2014-03-14 20:35:43 +01:00
2017-07-11 10:41:11 +02:00
it ( "can be closed again by clicking a DOM element with class 'close-chatbox-button'" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'lounge' , 'montague.lit' , 'romeo' ) ;
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view , 'close' ) . and . callThrough ( ) ;
2019-08-01 10:26:35 +02:00
spyOn ( _converse . api , "trigger" ) . and . callThrough ( ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view . model , 'leave' ) ;
view . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
2020-02-10 11:23:55 +01:00
spyOn ( _converse . api , 'confirm' ) . and . callFake ( ( ) => Promise . resolve ( true ) ) ;
2020-03-31 22:43:55 +02:00
const button = await u . waitUntil ( ( ) => view . el . querySelector ( '.close-chatbox-button' ) ) ;
button . click ( ) ;
2020-02-10 11:23:55 +01:00
await u . waitUntil ( ( ) => view . close . calls . count ( ) ) ;
2018-11-20 18:10:55 +01:00
expect ( view . model . leave ) . toHaveBeenCalled ( ) ;
2019-10-24 14:29:15 +02:00
await u . waitUntil ( ( ) => _converse . api . trigger . calls . count ( ) ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'chatBoxClosed' , jasmine . any ( Object ) ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2019-07-22 17:52:06 +02:00
it ( "informs users of role and affiliation changes" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2019-07-22 17:52:06 +02:00
async function ( done , _converse ) {
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
let presence = $pres ( {
'from' : 'lounge@montague.lit/annoyingGuy' ,
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
'to' : 'romeo@montague.lit/desktop'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'annoyingguy@montague.lit' ,
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "romeo and annoyingGuy have entered the groupchat" ) ;
2019-07-22 17:52:06 +02:00
presence = $pres ( {
'from' : 'lounge@montague.lit/annoyingGuy' ,
'to' : 'romeo@montague.lit/desktop'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'annoyingguy@montague.lit' ,
'affiliation' : 'member' ,
'role' : 'visitor'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
let info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "annoyingGuy has been muted" ) ;
2019-07-22 17:52:06 +02:00
presence = $pres ( {
'from' : 'lounge@montague.lit/annoyingGuy' ,
'to' : 'romeo@montague.lit/desktop'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'annoyingguy@montague.lit' ,
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "annoyingGuy has been given a voice" ) ;
2019-07-22 17:52:06 +02:00
// Check that we don't see an info message concerning the role,
// if the affiliation has changed.
presence = $pres ( {
'from' : 'lounge@montague.lit/annoyingGuy' ,
'to' : 'romeo@montague.lit/desktop'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'annoyingguy@montague.lit' ,
'affiliation' : 'none' ,
'role' : 'visitor'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "annoyingGuy is no longer a member of this groupchat" ) ;
2019-07-22 17:52:06 +02:00
done ( ) ;
} ) ) ;
2019-11-29 12:21:38 +01:00
2019-12-06 13:09:09 +01:00
it ( "notifies users of role and affiliation changes for members not currently in the groupchat" ,
2019-11-29 12:21:38 +01:00
mock . initConverse (
[ 'rosterGroupsFetched' ] , { } ,
async function ( done , _converse ) {
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
let message = $msg ( {
from : 'lounge@montague.lit' ,
id : '2CF9013B-E8A8-42A1-9633-85AD7CA12F40' ,
to : 'romeo@montague.lit'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-12-06 13:09:09 +01:00
'jid' : 'absentguy@montague.lit' ,
2019-11-29 12:21:38 +01:00
'affiliation' : 'member' ,
'role' : 'none'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( message ) ) ;
await u . waitUntil ( ( ) => view . model . occupants . length > 1 ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
2019-12-06 13:09:09 +01:00
expect ( view . model . occupants . findWhere ( { 'jid' : 'absentguy@montague.lit' } ) . get ( 'affiliation' ) ) . toBe ( 'member' ) ;
2019-11-29 12:21:38 +01:00
message = $msg ( {
from : 'lounge@montague.lit' ,
id : '2CF9013B-E8A8-42A1-9633-85AD7CA12F41' ,
to : 'romeo@montague.lit'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-12-06 13:09:09 +01:00
'jid' : 'absentguy@montague.lit' ,
2019-11-29 12:21:38 +01:00
'affiliation' : 'none' ,
'role' : 'none'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( message ) ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
2019-12-06 13:09:09 +01:00
expect ( view . model . occupants . findWhere ( { 'jid' : 'absentguy@montague.lit' } ) . get ( 'affiliation' ) ) . toBe ( 'none' ) ;
2019-11-29 12:21:38 +01:00
done ( ) ;
} ) ) ;
2016-11-03 11:01:09 +01:00
} ) ;
2016-05-28 10:55:03 +02:00
2018-07-02 15:54:51 +02:00
describe ( "Each chat groupchat can take special commands" , function ( ) {
2015-10-12 16:23:05 +02:00
2018-08-09 14:52:03 +02:00
it ( "takes /help to show the available commands" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2018-01-03 20:02:05 +01:00
2019-04-25 10:34:17 +02:00
spyOn ( window , 'confirm' ) . and . callFake ( ( ) => true ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-10-29 11:30:31 +01:00
let textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-08-05 11:14:49 +02:00
const enter = { 'target' : textarea , 'preventDefault' : function preventDefault ( ) { } , 'keyCode' : 13 } ;
2019-04-25 10:34:17 +02:00
textarea . value = '/help' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-04-25 10:34:17 +02:00
2019-10-29 11:30:31 +01:00
let info _messages = sizzle ( '.chat-info:not(.chat-event)' , view . el ) ;
2019-07-04 14:12:12 +02:00
expect ( info _messages . length ) . toBe ( 20 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/voice: Allow muted user to post messages' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/topic: Set groupchat subject (alias for /subject)' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/subject: Set groupchat subject' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/revoke: Revoke the user\'s current affiliation' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/register: Register your nickname' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/owner: Grant ownership of this groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/op: Grant moderator role to user' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/nick: Change your nickname' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/mute: Remove user\'s ability to post messages' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/modtools: Opens up the moderator tools GUI' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/member: Grant membership to a user' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/me: Write in 3rd person' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/kick: Kick user from groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/help: Show this menu' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/destroy: Remove this groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/deop: Change user role to participant' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/clear: Clear the chat area' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/ban: Ban user by changing their affiliation to outcast' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/admin: Change user\'s affiliation to admin' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( 'You can run the following commands' ) ;
2019-04-25 10:34:17 +02:00
const occupant = view . model . occupants . findWhere ( { 'jid' : _converse . bare _jid } ) ;
occupant . set ( 'affiliation' , 'admin' ) ;
2019-10-29 11:30:31 +01:00
textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-04-25 10:34:17 +02:00
textarea . value = '/clear' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-10-24 14:29:15 +02:00
await u . waitUntil ( ( ) => sizzle ( '.chat-info:not(.chat-event)' , view . el ) . length === 0 ) ;
2019-04-25 10:34:17 +02:00
textarea . value = '/help' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-10-24 14:29:15 +02:00
info _messages = sizzle ( '.chat-info:not(.chat-event)' , view . el ) ;
2020-01-17 14:50:25 +01:00
expect ( info _messages . length ) . toBe ( 19 ) ;
2019-04-25 10:34:17 +02:00
let commands = info _messages . map ( m => m . textContent . replace ( /:.*$/ , '' ) ) ;
expect ( commands ) . toEqual ( [
2019-10-24 14:29:15 +02:00
"You can run the following commands" ,
2019-04-25 10:34:17 +02:00
"/admin" , "/ban" , "/clear" , "/deop" , "/destroy" ,
2019-07-04 14:12:12 +02:00
"/help" , "/kick" , "/me" , "/member" , "/modtools" , "/mute" , "/nick" ,
2020-01-17 14:50:25 +01:00
"/op" , "/register" , "/revoke" , "/subject" , "/topic" , "/voice"
2019-04-25 10:34:17 +02:00
] ) ;
occupant . set ( 'affiliation' , 'member' ) ;
textarea . value = '/clear' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-10-29 11:30:31 +01:00
await u . waitUntil ( ( ) => sizzle ( '.chat-info:not(.chat-event)' , view . el ) . length === 0 ) ;
2019-04-25 10:34:17 +02:00
textarea . value = '/help' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-04-25 10:34:17 +02:00
info _messages = sizzle ( '.chat-info' , view . el ) . slice ( 1 ) ;
2020-01-16 13:01:57 +01:00
expect ( info _messages . length ) . toBe ( 9 ) ;
2019-04-25 10:34:17 +02:00
commands = info _messages . map ( m => m . textContent . replace ( /:.*$/ , '' ) ) ;
2020-01-16 13:01:57 +01:00
expect ( commands ) . toEqual ( [ "/clear" , "/help" , "/kick" , "/me" , "/modtools" , "/mute" , "/nick" , "/register" , "/voice" ] ) ;
2019-04-25 10:34:17 +02:00
occupant . set ( 'role' , 'participant' ) ;
2019-10-29 11:30:31 +01:00
textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-04-25 10:34:17 +02:00
textarea . value = '/clear' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-10-29 11:30:31 +01:00
await u . waitUntil ( ( ) => sizzle ( '.chat-info:not(.chat-event)' , view . el ) . length === 0 ) ;
2020-01-16 13:01:57 +01:00
textarea . value = '/help' ;
view . onKeyDown ( enter ) ;
info _messages = sizzle ( '.chat-info' , view . el ) . slice ( 1 ) ;
expect ( info _messages . length ) . toBe ( 5 ) ;
commands = info _messages . map ( m => m . textContent . replace ( /:.*$/ , '' ) ) ;
expect ( commands ) . toEqual ( [ "/clear" , "/help" , "/me" , "/nick" , "/register" ] ) ;
// Test that /topic is available if all users may change the subject
// Note: we're making a shortcut here, this value should never be set manually
view . model . config . set ( 'changesubject' , true ) ;
textarea . value = '/clear' ;
view . onKeyDown ( enter ) ;
await u . waitUntil ( ( ) => sizzle ( '.chat-info:not(.chat-event)' , view . el ) . length === 0 ) ;
2019-04-25 10:34:17 +02:00
textarea . value = '/help' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-04-25 10:34:17 +02:00
info _messages = sizzle ( '.chat-info' , view . el ) . slice ( 1 ) ;
expect ( info _messages . length ) . toBe ( 7 ) ;
commands = info _messages . map ( m => m . textContent . replace ( /:.*$/ , '' ) ) ;
expect ( commands ) . toEqual ( [ "/clear" , "/help" , "/me" , "/nick" , "/register" , "/subject" , "/topic" ] ) ;
2019-01-14 09:59:54 +01:00
done ( ) ;
} ) ) ;
it ( "takes /help to show the available commands and commands can be disabled by config" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { muc _disable _slash _commands : [ 'mute' , 'voice' ] } ,
2019-01-14 09:59:54 +01:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2019-01-14 09:59:54 +01:00
var textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-08-08 15:12:18 +02:00
const enter = { 'target' : textarea , 'preventDefault' : function ( ) { } , 'keyCode' : 13 } ;
2019-04-25 10:59:16 +02:00
spyOn ( window , 'confirm' ) . and . callFake ( ( ) => true ) ;
textarea . value = '/clear' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-04-25 10:59:16 +02:00
textarea . value = '/help' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( enter ) ;
2019-01-14 09:59:54 +01:00
2019-10-24 14:29:15 +02:00
const info _messages = sizzle ( '.chat-info:not(.chat-event)' , view . el ) ;
2019-07-04 14:12:12 +02:00
expect ( info _messages . length ) . toBe ( 18 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/topic: Set groupchat subject (alias for /subject)' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/subject: Set groupchat subject' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/revoke: Revoke the user\'s current affiliation' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/register: Register your nickname' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/owner: Grant ownership of this groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/op: Grant moderator role to user' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/nick: Change your nickname' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/modtools: Opens up the moderator tools GUI' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/member: Grant membership to a user' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/me: Write in 3rd person' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/kick: Kick user from groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/help: Show this menu' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/destroy: Remove this groupchat' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/deop: Change user role to participant' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/clear: Clear the chat area' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/ban: Ban user by changing their affiliation to outcast' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( '/admin: Change user\'s affiliation to admin' ) ;
expect ( info _messages . pop ( ) . textContent . trim ( ) ) . toBe ( 'You can run the following commands' ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-02-01 18:36:20 +01:00
} ) ) ;
2018-08-09 14:52:03 +02:00
it ( "takes /member to make an occupant a member" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2018-08-09 14:52:03 +02:00
2018-11-20 18:10:55 +01:00
let iq _stanza ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@muc.montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@muc.montague.lit' ) ;
2018-11-20 18:10:55 +01:00
/ * W e d o n ' t s h o w j o i n / l e a v e m e s s a g e s f o r e x i s t i n g o c c u p a n t s . W e
* know about them because we receive their presences before we
* receive our own .
* /
const presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/orchard' ,
from : 'lounge@muc.montague.lit/marc'
2018-11-20 18:10:55 +01:00
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'marc@montague.lit/_converse.js-290929789' ,
2018-11-20 18:10:55 +01:00
'role' : 'participant'
2018-08-09 14:52:03 +02:00
} ) ;
2018-11-20 18:10:55 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
const textarea = view . el . querySelector ( '.chat-textarea' ) ;
let sent _stanza ;
spyOn ( _converse . connection , 'send' ) . and . callFake ( ( stanza ) => {
sent _stanza = stanza ;
} ) ;
// First check that an error message appears when a
// non-existent nick is used.
textarea . value = '/member chris Welcome to the club!' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
expect ( _converse . connection . send ) . not . toHaveBeenCalled ( ) ;
expect ( view . el . querySelectorAll ( '.chat-error' ) . length ) . toBe ( 1 ) ;
expect ( view . el . querySelector ( '.chat-error' ) . textContent . trim ( ) )
2019-05-26 17:53:32 +02:00
. toBe ( 'Error: couldn\'t find a groupchat participant based on your arguments' ) ;
2018-11-20 18:10:55 +01:00
// Now test with an existing nick
textarea . value = '/member marc Welcome to the club!' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
expect ( _converse . connection . send ) . toHaveBeenCalled ( ) ;
expect ( Strophe . serialize ( sent _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ sent _stanza . getAttribute ( 'id' ) } " to="lounge@muc.montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
2019-06-03 07:58:51 +02:00
` <item affiliation="member" jid="marc@montague.lit"> ` +
2018-11-20 18:10:55 +01:00
` <reason>Welcome to the club!</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
let result = $iq ( {
"xmlns" : "jabber:client" ,
"type" : "result" ,
2019-06-03 07:58:51 +02:00
"to" : "romeo@montague.lit/orchard" ,
"from" : "lounge@muc.montague.lit" ,
2018-11-20 18:10:55 +01:00
"id" : sent _stanza . getAttribute ( 'id' )
} ) ;
_converse . connection . IQ _stanzas = [ ] ;
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
2019-07-11 22:50:30 +02:00
iq _stanza = await u . waitUntil ( ( ) => _ . filter (
2018-11-20 18:10:55 +01:00
_converse . connection . IQ _stanzas ,
2019-06-03 07:58:51 +02:00
iq => iq . querySelector ( 'iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="member"]' ) ) . pop ( )
2018-11-20 18:10:55 +01:00
) ;
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( iq _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ iq _stanza . getAttribute ( 'id' ) } " to="lounge@muc.montague.lit" type="get" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item affiliation="member"/> ` +
` </query> ` +
` </iq> ` )
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
result = $iq ( {
"xmlns" : "jabber:client" ,
"type" : "result" ,
2019-06-03 07:58:51 +02:00
"to" : "romeo@montague.lit/orchard" ,
"from" : "lounge@muc.montague.lit" ,
2018-11-20 18:10:55 +01:00
"id" : iq _stanza . getAttribute ( "id" )
} ) . c ( "query" , { "xmlns" : "http://jabber.org/protocol/muc#admin" } )
. c ( "item" , { "jid" : "marc" , "affiliation" : "member" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
2019-07-11 22:50:30 +02:00
iq _stanza = await u . waitUntil ( ( ) => _ . filter (
2018-11-20 18:10:55 +01:00
_converse . connection . IQ _stanzas ,
2019-06-03 07:58:51 +02:00
iq => iq . querySelector ( 'iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="owner"]' ) ) . pop ( )
2018-11-20 18:10:55 +01:00
) ;
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( iq _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ iq _stanza . getAttribute ( 'id' ) } " to="lounge@muc.montague.lit" type="get" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item affiliation="owner"/> ` +
` </query> ` +
` </iq> ` )
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
result = $iq ( {
"xmlns" : "jabber:client" ,
"type" : "result" ,
2019-06-03 07:58:51 +02:00
"to" : "romeo@montague.lit/orchard" ,
"from" : "lounge@muc.montague.lit" ,
2018-11-20 18:10:55 +01:00
"id" : iq _stanza . getAttribute ( "id" )
} ) . c ( "query" , { "xmlns" : "http://jabber.org/protocol/muc#admin" } )
2019-06-03 07:58:51 +02:00
. c ( "item" , { "jid" : "romeo@montague.lit" , "affiliation" : "owner" } ) ;
2018-11-20 18:10:55 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
2019-07-11 22:50:30 +02:00
iq _stanza = await u . waitUntil ( ( ) => _ . filter (
2018-11-20 18:10:55 +01:00
_converse . connection . IQ _stanzas ,
2019-06-03 07:58:51 +02:00
iq => iq . querySelector ( 'iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="admin"]' ) ) . pop ( )
2018-11-20 18:10:55 +01:00
) ;
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( iq _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ iq _stanza . getAttribute ( 'id' ) } " to="lounge@muc.montague.lit" type="get" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item affiliation="admin"/> ` +
` </query> ` +
` </iq> ` )
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
result = $iq ( {
"xmlns" : "jabber:client" ,
"type" : "result" ,
2019-06-03 07:58:51 +02:00
"to" : "romeo@montague.lit/orchard" ,
"from" : "lounge@muc.montague.lit" ,
2018-11-20 18:10:55 +01:00
"id" : iq _stanza . getAttribute ( "id" )
} ) . c ( "query" , { "xmlns" : "http://jabber.org/protocol/muc#admin" } )
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.occupant' ) . length , 500 ) ;
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.badge' ) . length > 1 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . model . occupants . length ) . toBe ( 2 ) ;
expect ( view . el . querySelectorAll ( '.occupant' ) . length ) . toBe ( 2 ) ;
done ( ) ;
2018-08-09 14:52:03 +02:00
} ) ) ;
it ( "takes /topic to set the groupchat topic" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-14 16:37:16 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-14 16:37:16 +01:00
spyOn ( view , 'clearMessages' ) ;
let sent _stanza ;
spyOn ( _converse . connection , 'send' ) . and . callFake ( function ( stanza ) {
sent _stanza = stanza ;
} ) ;
// Check the alias /topic
const textarea = view . el . querySelector ( '.chat-textarea' ) ;
textarea . value = '/topic This is the groupchat subject' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-14 16:37:16 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-14 16:37:16 +01:00
keyCode : 13
} ) ;
expect ( _converse . connection . send ) . toHaveBeenCalled ( ) ;
2019-08-12 20:16:34 +02:00
expect ( sent _stanza . textContent . trim ( ) ) . toBe ( 'This is the groupchat subject' ) ;
2017-12-06 22:10:54 +01:00
2018-11-14 16:37:16 +01:00
// Check /subject
textarea . value = '/subject This is a new subject' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-14 16:37:16 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-14 16:37:16 +01:00
keyCode : 13
} ) ;
2018-01-03 20:02:05 +01:00
2019-08-12 20:16:34 +02:00
expect ( sent _stanza . textContent . trim ( ) ) . toBe ( 'This is a new subject' ) ;
2018-11-14 16:37:16 +01:00
expect ( Strophe . serialize ( sent _stanza ) . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
'<message from="romeo@montague.lit/orchard" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client">' +
2018-11-14 16:37:16 +01:00
'<subject xmlns="jabber:client">This is a new subject</subject>' +
'</message>' ) ;
2017-12-06 22:10:54 +01:00
2018-11-14 16:37:16 +01:00
// Check case insensitivity
textarea . value = '/Subject This is yet another subject' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-14 16:37:16 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-14 16:37:16 +01:00
keyCode : 13
} ) ;
2019-08-12 20:16:34 +02:00
expect ( sent _stanza . textContent . trim ( ) ) . toBe ( 'This is yet another subject' ) ;
2018-11-14 16:37:16 +01:00
expect ( Strophe . serialize ( sent _stanza ) . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
'<message from="romeo@montague.lit/orchard" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client">' +
2018-11-14 16:37:16 +01:00
'<subject xmlns="jabber:client">This is yet another subject</subject>' +
'</message>' ) ;
2020-01-14 10:06:01 +01:00
// Check unsetting the topic
textarea . value = '/topic' ;
view . onKeyDown ( {
target : textarea ,
preventDefault : function preventDefault ( ) { } ,
keyCode : 13
} ) ;
expect ( Strophe . serialize ( sent _stanza ) . toLocaleString ( ) ) . toBe (
'<message from="romeo@montague.lit/orchard" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client">' +
'<subject xmlns="jabber:client"></subject>' +
'</message>' ) ;
2018-11-14 16:37:16 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2015-10-12 16:23:05 +02:00
2018-08-09 14:52:03 +02:00
it ( "takes /clear to clear messages" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2018-01-03 20:02:05 +01:00
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view , 'clearMessages' ) ;
const textarea = view . el . querySelector ( '.chat-textarea' )
textarea . value = '/clear' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
expect ( view . clearMessages ) . toHaveBeenCalled ( ) ;
done ( ) ;
2016-12-08 08:28:20 +01:00
} ) ) ;
2018-08-09 14:52:03 +02:00
it ( "takes /owner to make a user an owner" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2018-09-07 11:53:50 +02:00
let sent _IQ , IQ _id ;
const sendIQ = _converse . connection . sendIQ ;
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view . model , 'setAffiliation' ) . and . callThrough ( ) ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
2019-05-26 17:53:32 +02:00
spyOn ( view , 'validateRoleOrAffiliationChangeArgs' ) . and . callThrough ( ) ;
2017-12-06 22:10:54 +01:00
2018-11-20 18:10:55 +01:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2017-12-06 22:10:54 +01:00
2018-11-20 18:10:55 +01:00
var textarea = view . el . querySelector ( '.chat-textarea' )
textarea . value = '/owner' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
2018-09-07 11:53:50 +02:00
} ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage ) . toHaveBeenCalledWith (
"Error: the \"owner\" command takes two arguments, the user's nickname and optionally a reason." ) ;
expect ( view . model . setAffiliation ) . not . toHaveBeenCalled ( ) ;
2018-12-20 12:29:55 +01:00
// XXX: Calling onFormSubmitted directly, trying
// again via triggering Event doesn't work for some weird
// reason.
textarea . value = '/owner nobody You\'re responsible' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage ) . toHaveBeenCalledWith (
2019-05-26 17:53:32 +02:00
"Error: couldn't find a groupchat participant based on your arguments" ) ;
2018-11-20 18:10:55 +01:00
expect ( view . model . setAffiliation ) . not . toHaveBeenCalled ( ) ;
2018-12-20 12:29:55 +01:00
// Call now with the correct of arguments.
// XXX: Calling onFormSubmitted directly, trying
2018-11-20 18:10:55 +01:00
// again via triggering Event doesn't work for some weird
// reason.
2018-12-20 12:29:55 +01:00
textarea . value = '/owner annoyingGuy You\'re responsible' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 3 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . model . setAffiliation ) . toHaveBeenCalled ( ) ;
expect ( view . showErrorMessage . calls . count ( ) ) . toBe ( 2 ) ;
// Check that the member list now gets updated
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
2019-06-03 07:58:51 +02:00
` <item affiliation="owner" jid="annoyingguy@montague.lit"> ` +
2018-11-20 18:10:55 +01:00
` <reason>You're responsible</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
2018-09-07 11:53:50 +02:00
2018-11-20 18:10:55 +01:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D628' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'owner' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
expect ( view . el . querySelectorAll ( '.chat-info' ) [ 2 ] . textContent . trim ( ) ) . toBe ( "annoyingGuy is now an owner of this groupchat" ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-12-06 22:10:54 +01:00
} ) ) ;
2018-11-20 18:10:55 +01:00
it ( "takes /ban to ban a user" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-12-06 22:10:54 +01:00
2018-09-07 11:53:50 +02:00
let sent _IQ , IQ _id ;
const sendIQ = _converse . connection . sendIQ ;
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , 'lounge@montague.lit' , 'romeo' ) ;
2019-06-03 07:58:51 +02:00
const view = _converse . chatboxviews . get ( 'lounge@montague.lit' ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view . model , 'setAffiliation' ) . and . callThrough ( ) ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
2019-05-26 17:53:32 +02:00
spyOn ( view , 'validateRoleOrAffiliationChangeArgs' ) . and . callThrough ( ) ;
2018-09-07 11:53:50 +02:00
2018-11-20 18:10:55 +01:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
const textarea = view . el . querySelector ( '.chat-textarea' )
textarea . value = '/ban' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs ) . toHaveBeenCalled ( ) ;
2019-06-18 12:36:16 +02:00
expect ( view . showErrorMessage ) . toHaveBeenCalled ( ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.message:last-child' ) . textContent . trim ( ) ) . toBe (
2018-11-20 18:10:55 +01:00
"Error: the \"ban\" command takes two arguments, the user's nickname and optionally a reason." ) ;
2019-06-18 12:36:16 +02:00
2018-11-20 18:10:55 +01:00
expect ( view . model . setAffiliation ) . not . toHaveBeenCalled ( ) ;
// Call now with the correct amount of arguments.
2018-12-20 12:29:55 +01:00
// XXX: Calling onFormSubmitted directly, trying
2018-11-20 18:10:55 +01:00
// again via triggering Event doesn't work for some weird
// reason.
2018-12-20 12:29:55 +01:00
textarea . value = '/ban annoyingGuy You\'re annoying' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 2 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage . calls . count ( ) ) . toBe ( 1 ) ;
expect ( view . model . setAffiliation ) . toHaveBeenCalled ( ) ;
// Check that the member list now gets updated
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
2019-06-03 07:58:51 +02:00
` <item affiliation="outcast" jid="annoyingguy@montague.lit"> ` +
2018-11-20 18:10:55 +01:00
` <reason>You're annoying</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
presence = $pres ( {
2020-02-14 13:19:12 +01:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
'id' : '27C55F89-1C6A-459A-9EB5-77690145D628' ,
'to' : 'romeo@montague.lit/desktop'
} ) . c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'annoyingguy@montague.lit' ,
'affiliation' : 'outcast' ,
'role' : 'participant'
} ) . c ( 'actor' , { 'nick' : 'romeo' } ) . up ( )
. c ( 'reason' ) . t ( "You're annoying" ) . up ( ) . up ( )
. c ( 'status' , { 'code' : '301' } ) ;
2018-11-20 18:10:55 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-06-18 12:36:16 +02:00
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-info' ) . length === 2 ) ;
expect ( view . el . querySelectorAll ( '.chat-info__message' ) [ 0 ] . textContent . trim ( ) ) . toBe ( "annoyingGuy has been banned by romeo" ) ;
2020-02-14 13:19:12 +01:00
expect ( view . el . querySelector ( '.chat-info:last-child q' ) . textContent . trim ( ) ) . toBe ( "You're annoying" ) ;
2019-06-18 12:36:16 +02:00
presence = $pres ( {
'from' : 'lounge@montague.lit/joe2' ,
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
'to' : 'romeo@montague.lit/desktop'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'jid' : 'joe2@montague.lit' ,
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
textarea . value = '/ban joe22' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.message:last-child' ) . textContent . trim ( ) ) . toBe (
2019-06-18 12:36:16 +02:00
"Error: couldn't find a groupchat participant based on your arguments" ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
} ) ) ;
2019-06-18 12:36:16 +02:00
2019-05-26 17:53:32 +02:00
it ( "takes a /kick command to kick a user" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
let sent _IQ , IQ _id ;
const sendIQ = _converse . connection . sendIQ ;
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2019-05-26 16:39:17 +02:00
spyOn ( view . model , 'setRole' ) . and . callThrough ( ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
2019-05-26 17:53:32 +02:00
spyOn ( view , 'validateRoleOrAffiliationChangeArgs' ) . and . callThrough ( ) ;
2018-11-20 18:10:55 +01:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoying guy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'none' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-05-26 16:39:17 +02:00
const textarea = view . el . querySelector ( '.chat-textarea' )
2018-11-20 18:10:55 +01:00
textarea . value = '/kick' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage ) . toHaveBeenCalledWith (
"Error: the \"kick\" command takes two arguments, the user's nickname and optionally a reason." ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . not . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
// Call now with the correct amount of arguments.
2018-12-20 12:29:55 +01:00
// XXX: Calling onFormSubmitted directly, trying
2018-11-20 18:10:55 +01:00
// again via triggering Event doesn't work for some weird
// reason.
2019-05-27 12:24:46 +02:00
textarea . value = '/kick @annoying guy You\'re annoying' ;
2018-12-20 12:29:55 +01:00
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 2 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage . calls . count ( ) ) . toBe ( 1 ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
2019-05-26 17:53:32 +02:00
` <item nick="annoying guy" role="none"> ` +
2018-11-20 18:10:55 +01:00
` <reason>You're annoying</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
/ * < p r e s e n c e
* from = 'harfleur@chat.shakespeare.lit/pistol'
* to = 'gower@shakespeare.lit/cell'
* type = 'unavailable' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'none' role = 'none' / >
* < status code = '307' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoying guy' ,
'to' : 'romeo@montague.lit/desktop' ,
2018-11-20 18:10:55 +01:00
'type' : 'unavailable'
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
'affiliation' : 'none' ,
'role' : 'none'
2020-02-14 13:19:12 +01:00
} ) . c ( 'actor' , { 'nick' : 'romeo' } ) . up ( )
. c ( 'reason' ) . t ( "You're annoying" ) . up ( ) . up ( )
2018-11-20 18:10:55 +01:00
. c ( 'status' , { 'code' : '307' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-06-11 12:16:27 +02:00
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelectorAll ( '.chat-info' ) . length === 2 ) ;
expect ( view . el . querySelectorAll ( '.chat-info__message' ) [ 0 ] . textContent . trim ( ) ) . toBe ( "annoying guy has been kicked out by romeo" ) ;
2020-02-14 13:19:12 +01:00
expect ( view . el . querySelector ( '.chat-info:last-child q' ) . textContent . trim ( ) ) . toBe ( "You're annoying" ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-12-06 22:10:54 +01:00
} ) ) ;
2017-12-14 14:23:14 +01:00
2018-08-09 14:52:03 +02:00
it ( "takes /op and /deop to make a user a moderator or not" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-12-14 14:23:14 +01:00
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2020-03-31 22:43:55 +02:00
let sent _IQ , IQ _id ;
const sendIQ = _converse . connection . sendIQ ;
2018-11-20 18:10:55 +01:00
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2019-05-26 16:39:17 +02:00
spyOn ( view . model , 'setRole' ) . and . callThrough ( ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
spyOn ( view , 'showChatEvent' ) . and . callThrough ( ) ;
2019-05-26 17:53:32 +02:00
spyOn ( view , 'validateRoleOrAffiliationChangeArgs' ) . and . callThrough ( ) ;
2018-01-03 20:02:05 +01:00
2018-11-20 18:10:55 +01:00
// New user enters the groupchat
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* id = '27C55F89-1C6A-459A-9EB5-77690145D624'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member' role = 'moderator' / >
* < / x >
* < / p r e s e n c e >
* /
2019-05-26 17:53:32 +02:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/trustworthyguy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'trustworthyguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "romeo and trustworthyguy have entered the groupchat" ) ;
2018-11-20 18:10:55 +01:00
2020-03-31 22:43:55 +02:00
const textarea = view . el . querySelector ( '.chat-textarea' )
2018-11-20 18:10:55 +01:00
textarea . value = '/op' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage ) . toHaveBeenCalledWith (
"Error: the \"op\" command takes two arguments, the user's nickname and optionally a reason." ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . not . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
// Call now with the correct amount of arguments.
2018-12-20 12:29:55 +01:00
// XXX: Calling onFormSubmitted directly, trying
2018-11-20 18:10:55 +01:00
// again via triggering Event doesn't work for some weird
// reason.
2018-12-20 12:29:55 +01:00
textarea . value = '/op trustworthyguy You\'re trustworthy' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 2 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage . calls . count ( ) ) . toBe ( 1 ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item nick="trustworthyguy" role="moderator"> ` +
` <reason>You're trustworthy</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'moderator' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/trustworthyguy' ,
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'trustworthyguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'moderator'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
let info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "trustworthyguy is now a moderator" ) ;
2018-12-20 12:29:55 +01:00
// Call now with the correct amount of arguments.
// XXX: Calling onFormSubmitted directly, trying
// again via triggering Event doesn't work for some weird
// reason.
textarea . value = '/deop trustworthyguy Perhaps not' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2018-11-20 18:10:55 +01:00
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 3 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showChatEvent . calls . count ( ) ) . toBe ( 1 ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item nick="trustworthyguy" role="participant"> ` +
` <reason>Perhaps not</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'participant' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/trustworthyguy' ,
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} ) . c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'trustworthyguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "trustworthyguy is no longer a moderator" ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-12-14 14:23:14 +01:00
} ) ) ;
2018-08-09 14:52:03 +02:00
it ( "takes /mute and /voice to mute and unmute a user" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-12-06 22:10:54 +01:00
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2018-11-20 18:10:55 +01:00
var sent _IQ , IQ _id ;
var sendIQ = _converse . connection . sendIQ ;
spyOn ( _converse . connection , 'sendIQ' ) . and . callFake ( function ( iq , callback , errback ) {
sent _IQ = iq ;
IQ _id = sendIQ . bind ( this ) ( iq , callback , errback ) ;
} ) ;
2019-05-26 16:39:17 +02:00
spyOn ( view . model , 'setRole' ) . and . callThrough ( ) ;
2018-11-20 18:10:55 +01:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
spyOn ( view , 'showChatEvent' ) . and . callThrough ( ) ;
2019-05-26 17:53:32 +02:00
spyOn ( view , 'validateRoleOrAffiliationChangeArgs' ) . and . callThrough ( ) ;
2018-01-03 20:02:05 +01:00
2018-11-20 18:10:55 +01:00
// New user enters the groupchat
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* id = '27C55F89-1C6A-459A-9EB5-77690145D624'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member' role = 'participant' / >
* < / x >
* < / p r e s e n c e >
* /
2019-06-19 11:04:09 +02:00
var presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
2018-11-20 18:10:55 +01:00
'id' : '27C55F89-1C6A-459A-9EB5-77690145D624' ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "romeo and annoyingGuy have entered the groupchat" ) ;
2018-11-20 18:10:55 +01:00
2018-12-20 12:29:55 +01:00
const textarea = view . el . querySelector ( '.chat-textarea' )
2018-11-20 18:10:55 +01:00
textarea . value = '/mute' ;
2019-05-26 10:58:52 +02:00
view . onKeyDown ( {
2018-11-20 18:10:55 +01:00
target : textarea ,
2019-08-05 11:14:49 +02:00
preventDefault : function preventDefault ( ) { } ,
2018-11-20 18:10:55 +01:00
keyCode : 13
} ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage ) . toHaveBeenCalledWith (
"Error: the \"mute\" command takes two arguments, the user's nickname and optionally a reason." ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . not . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
// Call now with the correct amount of arguments.
2018-12-20 12:29:55 +01:00
// XXX: Calling onFormSubmitted directly, trying
2018-11-20 18:10:55 +01:00
// again via triggering Event doesn't work for some weird
// reason.
2018-12-20 12:29:55 +01:00
textarea . value = '/mute annoyingGuy You\'re annoying' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 2 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showErrorMessage . calls . count ( ) ) . toBe ( 1 ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item nick="annoyingGuy" role="visitor"> ` +
` <reason>You're annoying</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'visitor' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'visitor'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
let info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "annoyingGuy has been muted" ) ;
2018-11-20 18:10:55 +01:00
2018-12-20 12:29:55 +01:00
// Call now with the correct of arguments.
// XXX: Calling onFormSubmitted directly, trying
// again via triggering Event doesn't work for some weird
// reason.
textarea . value = '/voice annoyingGuy Now you can talk again' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-05-26 17:53:32 +02:00
expect ( view . validateRoleOrAffiliationChangeArgs . calls . count ( ) ) . toBe ( 3 ) ;
2018-11-20 18:10:55 +01:00
expect ( view . showChatEvent . calls . count ( ) ) . toBe ( 1 ) ;
2019-05-26 16:39:17 +02:00
expect ( view . model . setRole ) . toHaveBeenCalled ( ) ;
2018-11-20 18:10:55 +01:00
expect ( sent _IQ . toLocaleString ( ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq id=" ${ IQ _id } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item nick="annoyingGuy" role="participant"> ` +
` <reason>Now you can talk again</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* to = 'crone1@shakespeare.lit/desktop' >
* < x xmlns = 'http://jabber.org/protocol/muc#user' >
* < item affiliation = 'member'
* jid = 'hag66@shakespeare.lit/pda'
* role = 'visitor' / >
* < / x >
* < / p r e s e n c e >
* /
presence = $pres ( {
2019-06-03 07:58:51 +02:00
'from' : 'lounge@montague.lit/annoyingGuy' ,
'to' : 'romeo@montague.lit/desktop'
2018-11-20 18:10:55 +01:00
} )
. c ( 'x' , { 'xmlns' : 'http://jabber.org/protocol/muc#user' } )
. c ( 'item' , {
2019-06-03 07:58:51 +02:00
'jid' : 'annoyingguy@montague.lit' ,
2018-11-20 18:10:55 +01:00
'affiliation' : 'member' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
info _msgs = Array . prototype . slice . call ( view . el . querySelectorAll ( '.chat-info' ) , 0 ) ;
2019-08-12 20:16:34 +02:00
expect ( info _msgs . pop ( ) . textContent . trim ( ) ) . toBe ( "annoyingGuy has been given a voice" ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2018-12-22 18:27:07 +01:00
it ( "takes /destroy to destroy a muc" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-12-22 18:27:07 +01:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
const muc _jid = 'lounge@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2020-02-22 20:14:12 +01:00
spyOn ( _converse . api , 'confirm' ) . and . callFake ( ( ) => Promise . resolve ( true ) ) ;
2018-12-22 18:27:07 +01:00
const textarea = view . el . querySelector ( '.chat-textarea' ) ;
textarea . value = '/destroy bored' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2020-02-22 20:14:12 +01:00
const sent _IQs = _converse . connection . IQ _stanzas ;
const sent _IQ = await u . waitUntil ( ( ) => sent _IQs . filter ( iq => iq . querySelector ( 'destroy' ) ) . pop ( ) ) ;
expect ( Strophe . serialize ( sent _IQ ) ) . toBe (
` <iq id=" ${ sent _IQ . getAttribute ( 'id' ) } " to="lounge@montague.lit" type="set" xmlns="jabber:client"> ` +
2018-12-22 18:27:07 +01:00
` <query xmlns="http://jabber.org/protocol/muc#owner"> ` +
` <destroy> ` +
` <reason> ` +
` bored ` +
` </reason> ` +
` </destroy> ` +
` </query> ` +
` </iq> ` ) ;
const result _stanza = $iq ( {
'type' : 'result' ,
2020-02-22 20:14:12 +01:00
'id' : sent _IQ . getAttribute ( 'id' ) ,
2018-12-22 18:27:07 +01:00
'from' : view . model . get ( 'jid' ) ,
'to' : _converse . connection . jid
} ) ;
2019-08-01 10:26:35 +02:00
spyOn ( _converse . api , "trigger" ) . and . callThrough ( ) ;
2019-03-22 15:53:03 +01:00
expect ( _converse . chatboxes . length ) . toBe ( 2 ) ;
2018-12-22 18:27:07 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( result _stanza ) ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . DISCONNECTED ) ) ;
2019-10-24 14:29:15 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length === 1 ) ;
2019-03-29 21:10:45 +01:00
expect ( _converse . api . trigger ) . toHaveBeenCalledWith ( 'chatBoxClosed' , jasmine . any ( Object ) ) ;
2018-12-22 18:27:07 +01:00
done ( ) ;
} ) ) ;
2016-11-03 11:01:09 +01:00
} ) ;
2013-05-11 14:20:07 +02:00
2018-07-02 15:54:51 +02:00
describe ( "When attempting to enter a groupchat" , function ( ) {
2016-11-21 13:55:19 +01:00
2018-08-07 08:52:28 +02:00
it ( "will use the nickname set in the global settings if the user doesn't have a VCard nickname" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'nickname' : 'Benedict-Cucumberpatch' } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2018-08-07 08:52:28 +02:00
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoomViaModal ( _converse , 'roomy@muc.montague.lit' ) ;
const view = _converse . chatboxviews . get ( 'roomy@muc.montague.lit' ) ;
2018-10-22 09:59:53 +02:00
expect ( view . model . get ( 'nick' ) ) . toBe ( 'Benedict-Cucumberpatch' ) ;
done ( ) ;
2018-08-07 08:52:28 +02:00
} ) ) ;
2018-07-02 15:54:51 +02:00
it ( "will show an error message if the groupchat requires a password" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2018-04-08 19:44:53 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'protected' ;
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . chatboxviews . get ( muc _jid ) ;
2018-10-22 09:59:53 +02:00
spyOn ( view , 'renderPasswordForm' ) . and . callThrough ( ) ;
2018-03-11 13:56:53 +01:00
2019-04-24 11:03:27 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
'from' : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/pda' ,
2018-10-22 09:59:53 +02:00
'type' : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'auth' } )
2018-10-22 09:59:53 +02:00
. c ( 'not-authorized' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) ;
2018-03-11 13:56:53 +01:00
2018-10-22 09:59:53 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2018-03-11 13:56:53 +01:00
2018-10-22 09:59:53 +02:00
const chat _body = view . el . querySelector ( '.chatroom-body' ) ;
expect ( view . renderPasswordForm ) . toHaveBeenCalled ( ) ;
expect ( chat _body . querySelectorAll ( 'form.chatroom-form' ) . length ) . toBe ( 1 ) ;
2019-08-21 16:32:32 +02:00
expect ( chat _body . querySelector ( '.chatroom-form label' ) . textContent . trim ( ) )
2018-10-22 09:59:53 +02:00
. toBe ( 'This groupchat requires a password' ) ;
// Let's submit the form
2019-05-20 10:06:37 +02:00
spyOn ( view . model , 'join' ) ;
2018-10-22 09:59:53 +02:00
const input _el = view . el . querySelector ( '[name="password"]' ) ;
input _el . value = 'secret' ;
view . el . querySelector ( 'input[type=submit]' ) . click ( ) ;
2019-06-03 07:58:51 +02:00
expect ( view . model . join ) . toHaveBeenCalledWith ( 'romeo' , 'secret' ) ;
2018-10-22 09:59:53 +02:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2018-07-02 15:54:51 +02:00
it ( "will show an error message if the groupchat is members-only and the user not included" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'members-only@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
// State that the chat is members-only via the features IQ
const features _stanza = $iq ( {
2019-07-03 14:54:50 +02:00
'from' : muc _jid ,
2019-06-11 12:16:27 +02:00
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'result'
} )
. c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , {
'category' : 'conference' ,
'name' : 'A Dark Cave' ,
'type' : 'text'
} ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_hidden' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_temporary' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_membersonly' } ) . up ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ;
2019-06-11 12:16:27 +02:00
2018-10-22 09:59:53 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:59:53 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'auth' } )
2018-10-22 09:59:53 +02:00
. c ( 'registration-required' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:59:53 +02:00
. toBe ( 'You are not on the member list of this groupchat.' ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2017-07-11 10:41:11 +02:00
it ( "will show an error message if the user has been banned" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'off-limits@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
2019-06-11 12:16:27 +02:00
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
const features _stanza = $iq ( {
2019-07-03 14:54:50 +02:00
'from' : muc _jid ,
2019-06-11 12:16:27 +02:00
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'result'
} )
. c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , { 'category' : 'conference' , 'name' : 'A Dark Cave' , 'type' : 'text' } ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_hidden' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_temporary' } ) . up ( )
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ;
2019-06-11 12:16:27 +02:00
2018-10-22 09:59:53 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:59:53 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'auth' } )
2018-10-22 09:59:53 +02:00
. c ( 'forbidden' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:59:53 +02:00
. toBe ( 'You have been banned from this groupchat.' ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2017-07-11 10:41:11 +02:00
it ( "will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'conflicted@muc.montague.lit' ;
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
2018-10-22 09:59:53 +02:00
var presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:59:53 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'cancel' } )
2018-10-22 09:59:53 +02:00
. c ( 'conflict' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
2018-03-11 13:56:53 +01:00
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2018-10-22 09:59:53 +02:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( sizzle ( '.chatroom-body form.chatroom-form label:first' , view . el ) . pop ( ) . textContent . trim ( ) )
2018-10-22 09:59:53 +02:00
. toBe ( 'Please choose your nickname' ) ;
const input = sizzle ( '.chatroom-body form.chatroom-form input:first' , view . el ) . pop ( ) ;
input . value = 'nicky' ;
view . el . querySelector ( 'input[type=submit]' ) . click ( ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2016-08-11 14:00:52 +02:00
2019-06-11 12:16:27 +02:00
2017-07-11 10:41:11 +02:00
it ( "will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-22 09:59:53 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'conflicting@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
2018-10-22 09:59:53 +02:00
/ * < p r e s e n c e
* from = 'coven@chat.shakespeare.lit/thirdwitch'
* id = 'n13mt3l'
* to = 'hag66@shakespeare.lit/pda'
* type = 'error' >
* < x xmlns = 'http://jabber.org/protocol/muc' / >
* < error by = 'coven@chat.shakespeare.lit' type = 'cancel' >
* < conflict xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' / >
* < / e r r o r >
* < / p r e s e n c e >
* /
_converse . muc _nickname _from _jid = true ;
const attrs = {
2019-07-03 14:54:50 +02:00
'from' : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/pda' ,
2018-10-22 09:59:53 +02:00
'type' : 'error'
} ;
let presence = $pres ( ) . attrs ( attrs )
. c ( 'x' ) . attrs ( { 'xmlns' : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-07-03 14:54:50 +02:00
. c ( 'error' ) . attrs ( { 'by' : muc _jid , 'type' : 'cancel' } )
2018-10-22 09:59:53 +02:00
. c ( 'conflict' ) . attrs ( { 'xmlns' : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
2016-08-11 14:00:52 +02:00
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2018-10-22 09:59:53 +02:00
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
2019-05-20 10:06:37 +02:00
spyOn ( view . model , 'join' ) . and . callThrough ( ) ;
2018-03-11 13:56:53 +01:00
2018-10-22 09:59:53 +02:00
// Simulate repeatedly that there's already someone in the groupchat
// with that nickname
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-06-03 07:58:51 +02:00
expect ( view . model . join ) . toHaveBeenCalledWith ( 'romeo-2' ) ;
2016-08-11 14:00:52 +02:00
2019-07-03 14:54:50 +02:00
attrs . from = ` ${ muc _jid } /romeo-2 ` ;
2018-10-22 09:59:53 +02:00
attrs . id = u . getUniqueId ( ) ;
presence = $pres ( ) . attrs ( attrs )
. c ( 'x' ) . attrs ( { 'xmlns' : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-07-03 14:54:50 +02:00
. c ( 'error' ) . attrs ( { 'by' : muc _jid , type : 'cancel' } )
2018-10-22 09:59:53 +02:00
. c ( 'conflict' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2016-08-11 14:00:52 +02:00
2019-06-03 07:58:51 +02:00
expect ( view . model . join ) . toHaveBeenCalledWith ( 'romeo-3' ) ;
2018-10-22 09:59:53 +02:00
2019-07-03 14:54:50 +02:00
attrs . from = ` ${ muc _jid } /romeo-3 ` ;
2018-10-22 09:59:53 +02:00
attrs . id = new Date ( ) . getTime ( ) ;
presence = $pres ( ) . attrs ( attrs )
. c ( 'x' ) . attrs ( { 'xmlns' : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-07-03 14:54:50 +02:00
. c ( 'error' ) . attrs ( { 'by' : muc _jid , 'type' : 'cancel' } )
2018-10-22 09:59:53 +02:00
. c ( 'conflict' ) . attrs ( { 'xmlns' : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-06-03 07:58:51 +02:00
expect ( view . model . join ) . toHaveBeenCalledWith ( 'romeo-4' ) ;
2018-10-22 09:59:53 +02:00
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2018-07-02 15:54:51 +02:00
it ( "will show an error message if the user is not allowed to have created the groupchat" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:40:24 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'impermissable@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' )
2019-06-11 12:16:27 +02:00
// We pretend this is a new room, so no disco info is returned.
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
const features _stanza = $iq ( {
'from' : 'room@conference.example.org' ,
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'error'
} ) . c ( 'error' , { 'type' : 'cancel' } )
. c ( 'item-not-found' , { 'xmlns' : "urn:ietf:params:xml:ns:xmpp-stanzas" } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2019-06-11 12:16:27 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:59:53 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:40:24 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'cancel' } )
2018-10-22 09:40:24 +02:00
. c ( 'not-allowed' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:40:24 +02:00
. toBe ( 'You are not allowed to create new groupchats.' ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2018-10-22 09:40:24 +02:00
it ( "will show an error message if the user's nickname doesn't conform to groupchat policy" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:40:24 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'conformist@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
2019-06-11 12:16:27 +02:00
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
const features _stanza = $iq ( {
2019-07-03 14:54:50 +02:00
'from' : muc _jid ,
2019-06-11 12:16:27 +02:00
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , { 'category' : 'conference' , 'name' : 'A Dark Cave' , 'type' : 'text' } ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2019-06-11 12:16:27 +02:00
2018-10-22 09:59:53 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:40:24 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:40:24 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'cancel' } )
2018-10-22 09:40:24 +02:00
. c ( 'not-acceptable' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:40:24 +02:00
. toBe ( "Your nickname doesn't conform to this groupchat's policies." ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2018-07-02 15:54:51 +02:00
it ( "will show an error message if the groupchat doesn't yet exist" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:40:24 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'nonexistent@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' ) ;
2019-06-11 12:16:27 +02:00
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
const features _stanza = $iq ( {
2019-07-03 14:54:50 +02:00
'from' : muc _jid ,
2019-06-11 12:16:27 +02:00
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , { 'category' : 'conference' , 'name' : 'A Dark Cave' , 'type' : 'text' } ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2019-06-11 12:16:27 +02:00
2018-10-22 09:40:24 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:40:24 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:40:24 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'cancel' } )
2018-10-22 09:40:24 +02:00
. c ( 'item-not-found' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:40:24 +02:00
. toBe ( "This groupchat does not (yet) exist." ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
2013-05-11 14:20:07 +02:00
2018-07-02 15:54:51 +02:00
it ( "will show an error message if the groupchat has reached its maximum number of participants" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-10-22 09:40:24 +02:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-07-03 14:54:50 +02:00
const muc _jid = 'maxed-out@muc.montague.lit'
await test _utils . openChatRoomViaModal ( _converse , muc _jid , 'romeo' )
2019-06-11 12:16:27 +02:00
2019-07-11 22:50:30 +02:00
const iq = await u . waitUntil ( ( ) => _ . filter (
2019-06-11 12:16:27 +02:00
_converse . connection . IQ _stanzas ,
iq => iq . querySelector (
2019-07-03 14:54:50 +02:00
` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] `
2019-06-11 12:16:27 +02:00
) ) . pop ( ) ) ;
const features _stanza = $iq ( {
2019-07-03 14:54:50 +02:00
'from' : muc _jid ,
2019-06-11 12:16:27 +02:00
'id' : iq . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/desktop' ,
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , { 'category' : 'conference' , 'name' : 'A Dark Cave' , 'type' : 'text' } ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-07-03 14:54:50 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2019-06-11 12:16:27 +02:00
2018-10-22 09:40:24 +02:00
const presence = $pres ( ) . attrs ( {
2019-07-03 14:54:50 +02:00
from : ` ${ muc _jid } /romeo ` ,
2018-10-22 09:40:24 +02:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/pda' ,
2018-10-22 09:40:24 +02:00
type : 'error'
} ) . c ( 'x' ) . attrs ( { xmlns : 'http://jabber.org/protocol/muc' } ) . up ( )
2019-06-03 07:58:51 +02:00
. c ( 'error' ) . attrs ( { by : 'lounge@montague.lit' , type : 'cancel' } )
2018-10-22 09:40:24 +02:00
. c ( 'service-unavailable' ) . attrs ( { xmlns : 'urn:ietf:params:xml:ns:xmpp-stanzas' } ) . nodeTree ;
spyOn ( view , 'showErrorMessage' ) . and . callThrough ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chatroom-body .disconnect-container .disconnect-msg:last-child' ) . textContent . trim ( ) )
2018-10-22 09:40:24 +02:00
. toBe ( "This groupchat has reached its maximum number of participants." ) ;
done ( ) ;
2016-11-03 11:01:09 +01:00
} ) ) ;
} ) ;
2016-12-05 11:50:01 +01:00
2018-07-25 12:05:09 +02:00
describe ( "Someone being invited to a groupchat" , function ( ) {
2016-12-05 11:50:01 +01:00
2018-07-25 12:05:09 +02:00
it ( "will first be added to the member list if the groupchat is members only" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-24 14:29:15 +02:00
await test _utils . waitForRoster ( _converse , 'current' , 0 ) ;
2019-07-26 13:32:21 +02:00
spyOn ( _converse . ChatRoomOccupants . prototype , 'fetchMembers' ) . and . callThrough ( ) ;
2019-08-08 15:12:18 +02:00
const sent _IQs = _converse . connection . IQ _stanzas ;
2019-07-03 14:18:46 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2016-12-05 11:50:01 +01:00
2019-12-08 20:42:09 +01:00
const room _creation _promise = _converse . api . rooms . open ( muc _jid , { 'nick' : 'romeo' } ) ;
2019-08-08 15:12:18 +02:00
2019-12-08 20:42:09 +01:00
// Check that the groupchat queried for the features.
2019-08-08 15:12:18 +02:00
let stanza = await u . waitUntil ( ( ) => sent _IQs . filter ( iq => iq . querySelector ( ` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/disco#info"] ` ) ) . pop ( ) ) ;
2019-05-20 12:38:33 +02:00
expect ( Strophe . serialize ( stanza ) ) . toBe (
2019-07-03 14:18:46 +02:00
` <iq from="romeo@montague.lit/orchard" id=" ${ stanza . getAttribute ( "id" ) } " to=" ${ muc _jid } " type="get" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/disco#info"/> ` +
` </iq> ` ) ;
// State that the chat is members-only via the features IQ
2019-08-08 15:12:18 +02:00
const view = _converse . chatboxviews . get ( muc _jid ) ;
2019-05-20 12:38:33 +02:00
const features _stanza = $iq ( {
2018-11-20 18:10:55 +01:00
from : 'coven@chat.shakespeare.lit' ,
2019-08-08 15:12:18 +02:00
'id' : stanza . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/desktop' ,
2018-11-20 18:10:55 +01:00
'type' : 'result'
} )
. c ( 'query' , { 'xmlns' : 'http://jabber.org/protocol/disco#info' } )
. c ( 'identity' , {
'category' : 'conference' ,
'name' : 'A Dark Cave' ,
'type' : 'text'
} ) . up ( )
. c ( 'feature' , { 'var' : 'http://jabber.org/protocol/muc' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_hidden' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_temporary' } ) . up ( )
. c ( 'feature' , { 'var' : 'muc_membersonly' } ) . up ( ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( features _stanza ) ) ;
2019-12-10 15:40:33 +01:00
await u . waitUntil ( ( ) => ( view . model . session . get ( 'connection_status' ) === converse . ROOMSTATUS . CONNECTING ) ) ;
2019-01-10 12:14:45 +01:00
expect ( view . model . features . get ( 'membersonly' ) ) . toBeTruthy ( ) ;
2018-11-20 18:10:55 +01:00
2019-12-08 20:42:09 +01:00
await room _creation _promise ;
2019-10-24 14:29:15 +02:00
await test _utils . createContacts ( _converse , 'current' ) ;
2018-11-20 18:10:55 +01:00
let sent _stanza , sent _id ;
spyOn ( _converse . connection , 'send' ) . and . callFake ( function ( stanza ) {
if ( stanza . nodeTree && stanza . nodeTree . nodeName === 'message' ) {
sent _id = stanza . nodeTree . getAttribute ( 'id' ) ;
sent _stanza = stanza ;
}
} ) ;
2019-08-08 15:12:18 +02:00
const invitee _jid = mock . cur _names [ 0 ] . replace ( / /g , '.' ) . toLowerCase ( ) + '@montague.lit' ;
const reason = "Please join this groupchat" ;
2018-11-20 18:10:55 +01:00
view . model . directInvite ( invitee _jid , reason ) ;
// Check in reverse order that we requested all three lists
2019-07-26 13:32:21 +02:00
const owner _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( owner _iq ) ) . toBe (
` <iq id=" ${ owner _iq . getAttribute ( 'id' ) } " to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client"> ` +
2019-08-08 15:12:18 +02:00
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="owner"/></query> ` +
2018-11-20 18:10:55 +01:00
` </iq> ` ) ;
2019-08-08 15:12:18 +02:00
const admin _iq = sent _IQs . pop ( ) ;
expect ( Strophe . serialize ( admin _iq ) ) . toBe (
` <iq id=" ${ admin _iq . getAttribute ( 'id' ) } " to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="admin"/></query> ` +
` </iq> ` ) ;
const member _iq = sent _IQs . pop ( ) ;
2019-07-26 13:32:21 +02:00
expect ( Strophe . serialize ( member _iq ) ) . toBe (
` <iq id=" ${ member _iq . getAttribute ( 'id' ) } " to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client"> ` +
2019-08-08 15:12:18 +02:00
` <query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="member"/></query> ` +
2018-11-20 18:10:55 +01:00
` </iq> ` ) ;
2019-08-08 15:12:18 +02:00
// Now the service sends the member lists to the user
2019-07-26 13:32:21 +02:00
const member _list _stanza = $iq ( {
2018-11-20 18:10:55 +01:00
'from' : 'coven@chat.shakespeare.lit' ,
2019-07-26 13:32:21 +02:00
'id' : member _iq . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/orchard' ,
2018-11-20 18:10:55 +01:00
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : Strophe . NS . MUC _ADMIN } )
. c ( 'item' , {
'affiliation' : 'member' ,
'jid' : 'hag66@shakespeare.lit' ,
'nick' : 'thirdwitch' ,
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( member _list _stanza ) ) ;
2019-07-26 13:32:21 +02:00
const admin _list _stanza = $iq ( {
2018-11-20 18:10:55 +01:00
'from' : 'coven@chat.shakespeare.lit' ,
2019-07-26 13:32:21 +02:00
'id' : admin _iq . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/orchard' ,
2018-11-20 18:10:55 +01:00
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : Strophe . NS . MUC _ADMIN } )
. c ( 'item' , {
'affiliation' : 'admin' ,
'jid' : 'wiccarocks@shakespeare.lit' ,
'nick' : 'secondwitch'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( admin _list _stanza ) ) ;
2019-07-26 13:32:21 +02:00
const owner _list _stanza = $iq ( {
2018-11-20 18:10:55 +01:00
'from' : 'coven@chat.shakespeare.lit' ,
2019-07-26 13:32:21 +02:00
'id' : owner _iq . getAttribute ( 'id' ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit/orchard' ,
2018-11-20 18:10:55 +01:00
'type' : 'result'
} ) . c ( 'query' , { 'xmlns' : Strophe . NS . MUC _ADMIN } )
. c ( 'item' , {
'affiliation' : 'owner' ,
'jid' : 'crone1@shakespeare.lit' ,
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( owner _list _stanza ) ) ;
2019-07-26 13:32:21 +02:00
2019-08-08 15:12:18 +02:00
// Converse puts the user on the member list
stanza = await u . waitUntil ( ( ) => sent _IQs . filter ( iq => iq . querySelector ( ` iq[to=" ${ muc _jid } "] query[xmlns="http://jabber.org/protocol/muc#admin"] ` ) ) . pop ( ) ) ;
2018-11-20 18:10:55 +01:00
expect ( stanza . outerHTML ,
2019-07-26 13:32:21 +02:00
` <iq id=" ${ stanza . getAttribute ( 'id' ) } " to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <query xmlns="http://jabber.org/protocol/muc#admin"> ` +
` <item affiliation="member" jid=" ${ invitee _jid } "> ` +
` <reason>Please join this groupchat</reason> ` +
` </item> ` +
` </query> ` +
` </iq> ` ) ;
2019-07-26 13:32:21 +02:00
const result = $iq ( {
'from' : 'coven@chat.shakespeare.lit' ,
'id' : stanza . getAttribute ( 'id' ) ,
'to' : 'romeo@montague.lit/orchard' ,
'type' : 'result'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( result ) ) ;
await u . waitUntil ( ( ) => view . model . occupants . fetchMembers . calls . count ( ) ) ;
2018-11-20 18:10:55 +01:00
// Finally check that the user gets invited.
expect ( sent _stanza . toLocaleString ( ) ) . toBe ( // Strophe adds the xmlns attr (although not in spec)
2019-06-03 07:58:51 +02:00
` <message from="romeo@montague.lit/orchard" id=" ${ sent _id } " to=" ${ invitee _jid } " xmlns="jabber:client"> ` +
2018-11-20 18:10:55 +01:00
` <x jid="coven@chat.shakespeare.lit" reason="Please join this groupchat" xmlns="jabber:x:conference"/> ` +
` </message> `
) ;
done ( ) ;
2016-12-05 11:50:01 +01:00
} ) ) ;
} ) ;
2016-12-08 13:44:18 +01:00
describe ( "The affiliations delta" , function ( ) {
2017-07-11 10:41:11 +02:00
it ( "can be computed in various ways" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-06-03 07:58:51 +02:00
await test _utils . openChatRoom ( _converse , 'coven' , 'chat.shakespeare.lit' , 'romeo' ) ;
2016-12-08 13:44:18 +01:00
var exclude _existing = false ;
var remove _absentees = false ;
var new _list = [ ] ;
var old _list = [ ] ;
2019-11-07 09:08:13 +01:00
const muc _utils = converse . env . muc _utils ;
var delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 0 ) ;
new _list = [ { 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'member' } ] ;
old _list = [ { 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'member' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 0 ) ;
// When remove_absentees is false, then affiliations in the old
// list which are not in the new one won't be removed.
old _list = [ { 'jid' : 'oldhag666@shakespeare.lit' , 'affiliation' : 'owner' } ,
{ 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'member' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 0 ) ;
// With exclude_existing set to false, any changed affiliations
2019-08-08 15:12:18 +02:00
// will be included in the delta (i.e. existing affiliations are included in the comparison).
2016-12-08 13:44:18 +01:00
old _list = [ { 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'owner' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 1 ) ;
expect ( delta [ 0 ] . jid ) . toBe ( 'wiccarocks@shakespeare.lit' ) ;
expect ( delta [ 0 ] . affiliation ) . toBe ( 'member' ) ;
// To also remove affiliations from the old list which are not
// in the new list, we set remove_absentees to true
remove _absentees = true ;
old _list = [ { 'jid' : 'oldhag666@shakespeare.lit' , 'affiliation' : 'owner' } ,
{ 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'member' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 1 ) ;
expect ( delta [ 0 ] . jid ) . toBe ( 'oldhag666@shakespeare.lit' ) ;
expect ( delta [ 0 ] . affiliation ) . toBe ( 'none' ) ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , [ ] , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 2 ) ;
expect ( delta [ 0 ] . jid ) . toBe ( 'oldhag666@shakespeare.lit' ) ;
expect ( delta [ 0 ] . affiliation ) . toBe ( 'none' ) ;
expect ( delta [ 1 ] . jid ) . toBe ( 'wiccarocks@shakespeare.lit' ) ;
expect ( delta [ 1 ] . affiliation ) . toBe ( 'none' ) ;
// To only add a user if they don't already have an
// affiliation, we set 'exclude_existing' to true
exclude _existing = true ;
old _list = [ { 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'owner' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2016-12-08 13:44:18 +01:00
expect ( delta . length ) . toBe ( 0 ) ;
2019-08-08 15:12:18 +02:00
old _list = [ { 'jid' : 'wiccarocks@shakespeare.lit' , 'affiliation' : 'admin' } ] ;
2019-11-07 09:08:13 +01:00
delta = muc _utils . computeAffiliationsDelta ( exclude _existing , remove _absentees , new _list , old _list ) ;
2019-08-08 15:12:18 +02:00
expect ( delta . length ) . toBe ( 0 ) ;
2017-07-11 10:41:11 +02:00
done ( ) ;
2016-12-08 13:44:18 +01:00
} ) ) ;
} ) ;
2017-06-05 14:50:29 +02:00
2019-02-25 18:57:09 +01:00
describe ( "The \"Groupchats\" Add modal" , function ( ) {
2017-06-05 21:42:25 +02:00
2019-02-25 18:57:09 +01:00
it ( "can be opened from a link in the \"Groupchats\" section of the controlbox" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2017-07-11 10:41:11 +02:00
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-26 10:34:41 +01:00
await test _utils . waitForRoster ( _converse , 'current' , 0 ) ;
2018-07-30 18:16:32 +02:00
2019-02-01 15:22:45 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
2018-05-30 16:38:51 +02:00
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
2018-03-11 13:56:53 +01:00
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-02-26 10:34:41 +01:00
let label _name = modal . el . querySelector ( 'label[for="chatroom"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _name . textContent . trim ( ) ) . toBe ( 'Groupchat address:' ) ;
2019-02-26 10:34:41 +01:00
let name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
expect ( name _input . placeholder ) . toBe ( 'name@conference.example.org' ) ;
2019-03-26 11:31:11 +01:00
const label _nick = modal . el . querySelector ( 'label[for="nickname"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _nick . textContent . trim ( ) ) . toBe ( 'Nickname:' ) ;
2019-03-26 11:31:11 +01:00
const nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
expect ( nick _input . value ) . toBe ( '' ) ;
2019-06-03 07:58:51 +02:00
nick _input . value = 'romeo' ;
2019-03-26 11:31:11 +01:00
2019-08-12 20:16:34 +02:00
expect ( modal . el . querySelector ( '.modal-title' ) . textContent . trim ( ) ) . toBe ( 'Enter a new Groupchat' ) ;
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2018-11-20 18:10:55 +01:00
roomspanel . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
2019-06-03 07:58:51 +02:00
modal . el . querySelector ( 'input[name="chatroom"]' ) . value = 'lounce@muc.montague.lit' ;
2018-11-20 18:10:55 +01:00
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length ) ;
await u . waitUntil ( ( ) => sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length === 1 ) ;
2019-02-26 10:34:41 +01:00
roomspanel . model . set ( 'muc_domain' , 'muc.example.org' ) ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
label _name = modal . el . querySelector ( 'label[for="chatroom"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _name . textContent . trim ( ) ) . toBe ( 'Groupchat address:' ) ;
2019-02-26 10:34:41 +01:00
name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
expect ( name _input . placeholder ) . toBe ( 'name@muc.example.org' ) ;
done ( ) ;
} ) ) ;
2019-03-26 13:29:33 +01:00
it ( "doesn't show the nickname field if locked_muc_nickname is true" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'locked_muc_nickname' : true , 'muc_nickname_from_jid' : true } ,
2019-03-26 13:29:33 +01:00
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-03-26 13:29:33 +01:00
await test _utils . waitForRoster ( _converse , 'current' , 0 ) ;
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-03-26 13:29:33 +01:00
const name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
2019-06-03 07:58:51 +02:00
name _input . value = 'lounge@montague.lit' ;
2019-03-26 13:29:33 +01:00
expect ( modal . el . querySelector ( 'label[for="nickname"]' ) ) . toBe ( null ) ;
expect ( modal . el . querySelector ( 'input[name="nickname"]' ) ) . toBe ( null ) ;
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length > 1 ) ;
2019-06-03 07:58:51 +02:00
const chatroom = _converse . chatboxes . get ( 'lounge@montague.lit' ) ;
expect ( chatroom . get ( 'nick' ) ) . toBe ( 'romeo' ) ;
2019-03-26 13:29:33 +01:00
done ( ) ;
} ) ) ;
2019-03-26 11:31:11 +01:00
it ( "uses the JID node if muc_nickname_from_jid is set to true" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'muc_nickname_from_jid' : true } ,
2019-03-26 11:31:11 +01:00
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-03-26 11:31:11 +01:00
await test _utils . waitForRoster ( _converse , 'current' , 0 ) ;
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-03-26 11:31:11 +01:00
const label _nick = modal . el . querySelector ( 'label[for="nickname"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _nick . textContent . trim ( ) ) . toBe ( 'Nickname:' ) ;
2019-03-26 11:31:11 +01:00
const nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
2019-06-03 07:58:51 +02:00
expect ( nick _input . value ) . toBe ( 'romeo' ) ;
2019-03-26 11:31:11 +01:00
done ( ) ;
} ) ) ;
it ( "uses the nickname passed in to converse.initialize" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'nickname' : 'st.nick' } ,
2019-03-26 11:31:11 +01:00
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-03-26 11:31:11 +01:00
await test _utils . waitForRoster ( _converse , 'current' , 0 ) ;
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-03-26 11:31:11 +01:00
const label _nick = modal . el . querySelector ( 'label[for="nickname"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _nick . textContent . trim ( ) ) . toBe ( 'Nickname:' ) ;
2019-03-26 11:31:11 +01:00
const nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
expect ( nick _input . value ) . toBe ( 'st.nick' ) ;
done ( ) ;
} ) ) ;
2019-02-26 10:34:41 +01:00
it ( "doesn't require the domain when muc_domain is set" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'muc_domain' : 'muc.example.org' } ,
2019-02-26 10:34:41 +01:00
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-26 10:34:41 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-08-12 20:16:34 +02:00
expect ( modal . el . querySelector ( '.modal-title' ) . textContent . trim ( ) ) . toBe ( 'Enter a new Groupchat' ) ;
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2019-02-26 10:34:41 +01:00
roomspanel . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
const label _name = modal . el . querySelector ( 'label[for="chatroom"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _name . textContent . trim ( ) ) . toBe ( 'Groupchat name:' ) ;
2019-02-26 10:34:41 +01:00
let name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
expect ( name _input . placeholder ) . toBe ( 'name@muc.example.org' ) ;
name _input . value = 'lounge' ;
2019-03-26 12:16:18 +01:00
let nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
nick _input . value = 'max' ;
2019-02-26 10:34:41 +01:00
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length ) ;
await u . waitUntil ( ( ) => sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length === 1 ) ;
2019-02-26 10:34:41 +01:00
expect ( _ . includes ( _converse . chatboxes . models . map ( m => m . get ( 'id' ) ) , 'lounge@muc.example.org' ) ) . toBe ( true ) ;
// However, you can still open MUCs with different domains
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
2019-02-26 10:34:41 +01:00
name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
name _input . value = 'lounge@conference.example.org' ;
2019-03-26 12:16:18 +01:00
nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
nick _input . value = 'max' ;
2019-02-26 10:34:41 +01:00
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . models . filter ( c => c . get ( 'type' ) === 'chatroom' ) . length === 2 ) ;
await u . waitUntil ( ( ) => sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length === 2 ) ;
2019-02-26 10:34:41 +01:00
expect ( _ . includes ( _converse . chatboxes . models . map ( m => m . get ( 'id' ) ) , 'lounge@conference.example.org' ) ) . toBe ( true ) ;
done ( ) ;
} ) ) ;
it ( "only uses the muc_domain is locked_muc_domain is true" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { 'muc_domain' : 'muc.example.org' , 'locked_muc_domain' : true } ,
2019-02-26 10:34:41 +01:00
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-26 10:34:41 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
const modal = roomspanel . add _room _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 )
2019-08-12 20:16:34 +02:00
expect ( modal . el . querySelector ( '.modal-title' ) . textContent . trim ( ) ) . toBe ( 'Enter a new Groupchat' ) ;
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2019-02-26 10:34:41 +01:00
roomspanel . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
const label _name = modal . el . querySelector ( 'label[for="chatroom"]' ) ;
2019-08-12 20:16:34 +02:00
expect ( label _name . textContent . trim ( ) ) . toBe ( 'Groupchat name:' ) ;
2019-02-26 10:34:41 +01:00
let name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
expect ( name _input . placeholder ) . toBe ( '' ) ;
name _input . value = 'lounge' ;
2019-03-26 12:16:18 +01:00
let nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
nick _input . value = 'max' ;
2019-02-26 10:34:41 +01:00
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length ) ;
await u . waitUntil ( ( ) => sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length === 1 ) ;
2019-02-26 10:34:41 +01:00
expect ( _ . includes ( _converse . chatboxes . models . map ( m => m . get ( 'id' ) ) , 'lounge@muc.example.org' ) ) . toBe ( true ) ;
// However, you can still open MUCs with different domains
roomspanel . el . querySelector ( '.show-add-muc-modal' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
2019-02-26 10:34:41 +01:00
name _input = modal . el . querySelector ( 'input[name="chatroom"]' ) ;
name _input . value = 'lounge@conference' ;
2019-03-26 12:16:18 +01:00
nick _input = modal . el . querySelector ( 'input[name="nickname"]' ) ;
nick _input . value = 'max' ;
2019-02-26 10:34:41 +01:00
modal . el . querySelector ( 'form input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . models . filter ( c => c . get ( 'type' ) === 'chatroom' ) . length === 2 ) ;
await u . waitUntil ( ( ) => sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length === 2 ) ;
2019-02-26 10:34:41 +01:00
expect ( _ . includes ( _converse . chatboxes . models . map ( m => m . get ( 'id' ) ) , 'lounge\\40conference@muc.example.org' ) ) . toBe ( true ) ;
2018-11-20 18:10:55 +01:00
done ( ) ;
2017-06-05 21:42:25 +02:00
} ) ) ;
2019-02-26 11:05:15 +01:00
} ) ;
describe ( "The \"Groupchats\" List modal" , function ( ) {
2017-06-05 21:42:25 +02:00
2019-02-26 11:05:15 +01:00
it ( "can be opened from a link in the \"Groupchats\" section of the controlbox" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2018-10-25 07:32:44 +02:00
async function ( done , _converse ) {
2018-03-11 13:56:53 +01:00
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-25 18:57:09 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
2018-05-30 16:38:51 +02:00
roomspanel . el . querySelector ( '.show-list-muc-modal' ) . click ( ) ;
2018-03-11 13:56:53 +01:00
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . list _rooms _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2018-10-25 07:32:44 +02:00
roomspanel . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
2019-03-04 17:49:44 +01:00
// See: https://xmpp.org/extensions/xep-0045.html#disco-rooms
2018-10-25 07:32:44 +02:00
expect ( modal . el . querySelectorAll ( '.available-chatrooms li' ) . length ) . toBe ( 0 ) ;
2019-02-26 10:34:41 +01:00
const server _input = modal . el . querySelector ( 'input[name="server"]' ) ;
expect ( server _input . placeholder ) . toBe ( 'conference.example.org' ) ;
2019-10-09 16:01:38 +02:00
server _input . value = 'chat.shakespeare.lit' ;
2018-10-25 07:32:44 +02:00
modal . el . querySelector ( 'input[type="submit"]' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length ) ;
2019-05-20 12:38:33 +02:00
const IQ _stanzas = _converse . connection . IQ _stanzas ;
2019-07-11 22:50:30 +02:00
const sent _stanza = await u . waitUntil (
2019-05-20 12:38:33 +02:00
( ) => IQ _stanzas . filter ( s => sizzle ( ` query[xmlns=" ${ Strophe . NS . DISCO _ITEMS } "] ` , s ) . length ) . pop ( )
) ;
const id = sent _stanza . getAttribute ( 'id' ) ;
expect ( Strophe . serialize ( sent _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq from="romeo@montague.lit/orchard" id=" ${ id } " ` +
2019-05-20 12:38:33 +02:00
` to="chat.shakespeare.lit" ` +
` type="get" ` +
` xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/disco#items"/> ` +
2018-10-25 07:32:44 +02:00
` </iq> `
) ;
const iq = $iq ( {
2019-06-03 07:58:51 +02:00
'from' : 'muc.montague.lit' ,
'to' : 'romeo@montague.lit/pda' ,
2019-05-20 12:38:33 +02:00
'id' : id ,
'type' : 'result'
2018-10-25 07:32:44 +02:00
} ) . c ( 'query' )
. c ( 'item' , { jid : 'heath@chat.shakespeare.lit' , name : 'A Lonely Heath' } ) . up ( )
. c ( 'item' , { jid : 'coven@chat.shakespeare.lit' , name : 'A Dark Cave' } ) . up ( )
. c ( 'item' , { jid : 'forres@chat.shakespeare.lit' , name : 'The Palace' } ) . up ( )
2019-02-26 11:05:15 +01:00
. c ( 'item' , { jid : 'inverness@chat.shakespeare.lit' , name : 'Macbeth's Castle' } ) . up ( )
. c ( 'item' , { jid : 'orchard@chat.shakespeare.lit' , name : 'Capulet\'s Orchard' } ) . up ( )
. c ( 'item' , { jid : 'friar@chat.shakespeare.lit' , name : 'Friar Laurence\'s cell' } ) . up ( )
. c ( 'item' , { jid : 'hall@chat.shakespeare.lit' , name : 'Hall in Capulet\'s house' } ) . up ( )
. c ( 'item' , { jid : 'chamber@chat.shakespeare.lit' , name : 'Juliet\'s chamber' } ) . up ( )
. c ( 'item' , { jid : 'public@chat.shakespeare.lit' , name : 'A public place' } ) . up ( )
. c ( 'item' , { jid : 'street@chat.shakespeare.lit' , name : 'A street' } ) . nodeTree ;
2018-10-25 07:32:44 +02:00
_converse . connection . _dataRecv ( test _utils . createRequest ( iq ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => modal . el . querySelectorAll ( '.available-chatrooms li' ) . length === 11 ) ;
2018-10-25 07:32:44 +02:00
const rooms = modal . el . querySelectorAll ( '.available-chatrooms li' ) ;
expect ( rooms [ 0 ] . textContent . trim ( ) ) . toBe ( "Groupchats found:" ) ;
expect ( rooms [ 1 ] . textContent . trim ( ) ) . toBe ( "A Lonely Heath" ) ;
expect ( rooms [ 2 ] . textContent . trim ( ) ) . toBe ( "A Dark Cave" ) ;
expect ( rooms [ 3 ] . textContent . trim ( ) ) . toBe ( "The Palace" ) ;
expect ( rooms [ 4 ] . textContent . trim ( ) ) . toBe ( "Macbeth's Castle" ) ;
2019-02-26 10:34:41 +01:00
expect ( rooms [ 5 ] . textContent . trim ( ) ) . toBe ( 'Capulet\'s Orchard' ) ;
expect ( rooms [ 6 ] . textContent . trim ( ) ) . toBe ( 'Friar Laurence\'s cell' ) ;
expect ( rooms [ 7 ] . textContent . trim ( ) ) . toBe ( 'Hall in Capulet\'s house' ) ;
expect ( rooms [ 8 ] . textContent . trim ( ) ) . toBe ( 'Juliet\'s chamber' ) ;
expect ( rooms [ 9 ] . textContent . trim ( ) ) . toBe ( 'A public place' ) ;
expect ( rooms [ 10 ] . textContent . trim ( ) ) . toBe ( 'A street' ) ;
2018-10-25 07:32:44 +02:00
rooms [ 4 ] . querySelector ( '.open-room' ) . click ( ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length > 1 ) ;
2018-10-25 07:32:44 +02:00
expect ( sizzle ( '.chatroom' , _converse . el ) . filter ( u . isVisible ) . length ) . toBe ( 1 ) ; // There should now be an open chatroom
var view = _converse . chatboxviews . get ( 'inverness@chat.shakespeare.lit' ) ;
2020-02-10 11:23:55 +01:00
expect ( view . el . querySelector ( '.chatbox-title__text' ) . textContent . trim ( ) ) . toBe ( "Macbeth's Castle" ) ;
2018-10-25 07:32:44 +02:00
done ( ) ;
2018-03-11 13:56:53 +01:00
} ) ) ;
2019-02-26 10:34:41 +01:00
it ( "is pre-filled with the muc_domain" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] ,
2019-02-26 10:34:41 +01:00
{ 'muc_domain' : 'muc.example.org' } ,
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-26 10:34:41 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-list-muc-modal' ) . click ( ) ;
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . list _rooms _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
2019-02-26 10:34:41 +01:00
const server _input = modal . el . querySelector ( 'input[name="server"]' ) ;
expect ( server _input . value ) . toBe ( 'muc.example.org' ) ;
done ( ) ;
} ) ) ;
it ( "doesn't let you set the MUC domain if it's locked" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] ,
2019-02-26 10:34:41 +01:00
{ 'muc_domain' : 'chat.shakespeare.lit' , 'locked_muc_domain' : true } ,
async function ( done , _converse ) {
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2019-02-26 10:34:41 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
roomspanel . el . querySelector ( '.show-list-muc-modal' ) . click ( ) ;
test _utils . closeControlBox ( _converse ) ;
const modal = roomspanel . list _rooms _modal ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => u . isVisible ( modal . el ) , 1000 ) ;
2020-01-16 13:01:57 +01:00
spyOn ( _converse . ChatRoom . prototype , 'getDiscoInfo' ) . and . callFake ( ( ) => Promise . resolve ( ) ) ;
2019-02-26 10:34:41 +01:00
roomspanel . delegateEvents ( ) ; // We need to rebind all events otherwise our spy won't be called
expect ( modal . el . querySelector ( 'input[name="server"]' ) ) . toBe ( null ) ;
expect ( modal . el . querySelector ( 'input[type="submit"]' ) ) . toBe ( null ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => _converse . chatboxes . length ) ;
const sent _stanza = await u . waitUntil ( ( ) =>
2019-02-26 10:34:41 +01:00
_converse . connection . sent _stanzas . filter (
s => sizzle ( ` query[xmlns="http://jabber.org/protocol/disco#items"] ` , s ) . length ) . pop ( )
) ;
expect ( Strophe . serialize ( sent _stanza ) ) . toBe (
2019-06-03 07:58:51 +02:00
` <iq from="romeo@montague.lit/orchard" id=" ${ sent _stanza . getAttribute ( 'id' ) } " ` +
2019-02-26 10:34:41 +01:00
` to="chat.shakespeare.lit" type="get" xmlns="jabber:client"> ` +
` <query xmlns="http://jabber.org/protocol/disco#items"/> ` +
` </iq> `
) ;
const iq = $iq ( {
2019-06-03 07:58:51 +02:00
from : 'muc.montague.lit' ,
to : 'romeo@montague.lit/pda' ,
2019-02-26 10:34:41 +01:00
id : sent _stanza . getAttribute ( 'id' ) ,
type : 'result'
} ) . c ( 'query' )
. c ( 'item' , { jid : 'heath@chat.shakespeare.lit' , name : 'A Lonely Heath' } ) . up ( )
. c ( 'item' , { jid : 'coven@chat.shakespeare.lit' , name : 'A Dark Cave' } ) . up ( )
. c ( 'item' , { jid : 'forres@chat.shakespeare.lit' , name : 'The Palace' } ) . up ( )
_converse . connection . _dataRecv ( test _utils . createRequest ( iq ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => modal . el . querySelectorAll ( '.available-chatrooms li' ) . length === 4 ) ;
2019-02-26 10:34:41 +01:00
const rooms = modal . el . querySelectorAll ( '.available-chatrooms li' ) ;
expect ( rooms [ 0 ] . textContent . trim ( ) ) . toBe ( "Groupchats found:" ) ;
expect ( rooms [ 1 ] . textContent . trim ( ) ) . toBe ( "A Lonely Heath" ) ;
expect ( rooms [ 2 ] . textContent . trim ( ) ) . toBe ( "A Dark Cave" ) ;
expect ( rooms [ 3 ] . textContent . trim ( ) ) . toBe ( "The Palace" ) ;
done ( ) ;
} ) ) ;
2019-02-25 18:57:09 +01:00
} ) ;
describe ( "The \"Groupchats\" section" , function ( ) {
2017-06-05 21:42:25 +02:00
2017-07-11 10:41:11 +02:00
it ( "shows the number of unread mentions received" ,
2019-02-12 14:21:45 +01:00
mock . initConverse (
2020-01-21 12:45:34 +01:00
[ 'rosterGroupsFetched' ] , { 'allow_bookmarks' : false } ,
2018-11-20 18:10:55 +01:00
async function ( done , _converse ) {
2018-03-11 13:56:53 +01:00
2019-10-24 14:29:15 +02:00
await test _utils . openControlBox ( _converse ) ;
2018-11-20 18:10:55 +01:00
const roomspanel = _converse . chatboxviews . get ( 'controlbox' ) . roomspanel ;
2018-03-11 13:56:53 +01:00
expect ( roomspanel . el . querySelectorAll ( '.available-room' ) . length ) . toBe ( 0 ) ;
2017-07-11 10:41:11 +02:00
2019-07-03 14:18:46 +02:00
const muc _jid = 'kitchen@conference.shakespeare.lit' ;
2018-08-18 11:28:51 +02:00
const message = 'fires: Your attention is required' ;
2019-07-03 14:18:46 +02:00
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'fires' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2019-07-11 12:30:51 +02:00
await u . waitUntil ( ( ) => roomspanel . el . querySelectorAll ( '.available-room' ) . length ) ;
2018-11-20 18:10:55 +01:00
expect ( roomspanel . el . querySelectorAll ( '.available-room' ) . length ) . toBe ( 1 ) ;
expect ( roomspanel . el . querySelectorAll ( '.msgs-indicator' ) . length ) . toBe ( 0 ) ;
2017-06-05 14:50:29 +02:00
2018-11-20 18:10:55 +01:00
view . model . set ( { 'minimized' : true } ) ;
2017-06-05 14:50:29 +02:00
2018-11-20 18:10:55 +01:00
const nick = mock . chatroom _names [ 0 ] ;
2018-04-30 15:24:37 +02:00
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( $msg ( {
2019-07-03 14:18:46 +02:00
from : muc _jid + '/' + nick ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2018-11-20 18:10:55 +01:00
type : 'groupchat'
2018-04-30 15:24:37 +02:00
} ) . c ( 'body' ) . t ( message ) . tree ( ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . model . messages . length ) ;
2018-11-20 18:10:55 +01:00
expect ( roomspanel . el . querySelectorAll ( '.available-room' ) . length ) . toBe ( 1 ) ;
expect ( roomspanel . el . querySelectorAll ( '.msgs-indicator' ) . length ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( roomspanel . el . querySelector ( '.msgs-indicator' ) . textContent . trim ( ) ) . toBe ( '1' ) ;
2018-11-20 18:10:55 +01:00
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( $msg ( {
2019-07-03 14:18:46 +02:00
'from' : muc _jid + '/' + nick ,
2020-02-07 12:24:02 +01:00
'id' : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
'to' : 'romeo@montague.lit' ,
2018-11-20 18:10:55 +01:00
'type' : 'groupchat'
} ) . c ( 'body' ) . t ( message ) . tree ( ) ) ;
2019-07-11 22:50:30 +02:00
await u . waitUntil ( ( ) => view . model . messages . length > 1 ) ;
2018-11-20 18:10:55 +01:00
expect ( roomspanel . el . querySelectorAll ( '.available-room' ) . length ) . toBe ( 1 ) ;
expect ( roomspanel . el . querySelectorAll ( '.msgs-indicator' ) . length ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( roomspanel . el . querySelector ( '.msgs-indicator' ) . textContent . trim ( ) ) . toBe ( '2' ) ;
2018-11-20 18:10:55 +01:00
view . model . set ( { 'minimized' : false } ) ;
expect ( roomspanel . el . querySelectorAll ( '.available-room' ) . length ) . toBe ( 1 ) ;
expect ( roomspanel . el . querySelectorAll ( '.msgs-indicator' ) . length ) . toBe ( 0 ) ;
done ( ) ;
2017-06-05 14:50:29 +02:00
} ) ) ;
2019-02-25 18:57:09 +01:00
} ) ;
2019-07-10 09:47:13 +02:00
describe ( "A XEP-0085 Chat Status Notification" , function ( ) {
it ( "is is not sent out to a MUC if the user is a visitor in a moderated room" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2019-07-10 09:47:13 +02:00
async function ( done , _converse ) {
spyOn ( _converse . ChatRoom . prototype , 'sendChatState' ) . and . callThrough ( ) ;
const muc _jid = 'lounge@montague.lit' ;
const features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
'muc_passwordprotected' ,
'muc_hidden' ,
'muc_temporary' ,
'muc_membersonly' ,
'muc_moderated' ,
'muc_anonymous'
]
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'romeo' , features ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
view . model . setChatState ( _converse . ACTIVE ) ;
expect ( view . model . sendChatState ) . toHaveBeenCalled ( ) ;
const last _stanza = _converse . connection . sent _stanzas . pop ( ) ;
expect ( Strophe . serialize ( last _stanza ) ) . toBe (
` <message to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> ` +
` <active xmlns="http://jabber.org/protocol/chatstates"/> ` +
` <no-store xmlns="urn:xmpp:hints"/> ` +
` <no-permanent-store xmlns="urn:xmpp:hints"/> ` +
` </message> ` ) ;
// Romeo loses his voice
const presence = $pres ( {
to : 'romeo@montague.lit/orchard' ,
2019-10-24 14:29:15 +02:00
from : ` ${ muc _jid } /romeo `
2019-07-10 09:47:13 +02:00
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , { 'affiliation' : 'none' , 'role' : 'visitor' } ) . up ( )
. c ( 'status' , { code : '110' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
const occupant = view . model . occupants . findWhere ( { 'jid' : _converse . bare _jid } ) ;
expect ( occupant . get ( 'role' ) ) . toBe ( 'visitor' ) ;
spyOn ( _converse . connection , 'send' ) ;
view . model . setChatState ( _converse . INACTIVE ) ;
expect ( view . model . sendChatState . calls . count ( ) ) . toBe ( 2 ) ;
expect ( _converse . connection . send ) . not . toHaveBeenCalled ( ) ;
done ( ) ;
} ) ) ;
2019-02-25 18:57:09 +01:00
describe ( "A composing notification" , function ( ) {
it ( "will be shown if received" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' ] , { } ,
2019-02-25 18:57:09 +01:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2020-03-18 19:32:03 +01:00
const members = [
{ 'affiliation' : 'member' , 'nick' : 'majortom' , 'jid' : 'majortom@example.org' } ,
{ 'affiliation' : 'admin' , 'nick' : 'groundcontrol' , 'jid' : 'groundcontrol@example.org' }
] ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'some1' , [ ] , members ) ;
2019-07-03 14:18:46 +02:00
const view = _converse . api . chatviews . get ( muc _jid ) ;
2019-02-25 18:57:09 +01:00
2020-03-31 22:43:55 +02:00
let csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "some1 has entered the groupchat" ) ;
2018-04-06 13:56:14 +02:00
2019-02-25 18:57:09 +01:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
from : 'coven@chat.shakespeare.lit/newguy'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2019-02-25 18:57:09 +01:00
'role' : 'participant'
2018-10-13 23:25:01 +02:00
} ) ;
2019-02-25 18:57:09 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newguy have entered the groupchat" ) ;
2018-10-13 23:25:01 +02:00
2019-02-25 18:57:09 +01:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
from : 'coven@chat.shakespeare.lit/nomorenicks'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'nomorenicks@montague.lit/_converse.js-290929789' ,
2019-02-25 18:57:09 +01:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newguy and nomorenicks have entered the groupchat" ) ;
// Manually clear so that we can more easily test
view . model . notifications . set ( 'entered' , [ ] ) ;
await u . waitUntil ( ( ) => ! view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
2019-02-25 18:57:09 +01:00
2019-03-04 17:49:44 +01:00
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
2019-02-25 18:57:09 +01:00
2020-03-18 19:32:03 +01:00
const timeout _functions = [ ] ;
spyOn ( window , 'setTimeout' ) . and . callFake ( f => {
2020-03-31 22:43:55 +02:00
if ( f . toString ( ) === "() => this.removeNotification(actor, state)" ) {
2020-03-18 19:32:03 +01:00
timeout _functions . push ( f )
}
} ) ;
2019-02-25 18:57:09 +01:00
// <composing> state
let msg = $msg ( {
2019-07-03 14:18:46 +02:00
from : muc _jid + '/newguy' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2018-10-13 23:25:01 +02:00
type : 'groupchat'
2019-02-25 18:57:09 +01:00
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-18 19:32:03 +01:00
_converse . connection . _dataRecv ( test _utils . createRequest ( msg ) ) ;
2018-04-06 13:56:14 +02:00
2020-03-31 22:43:55 +02:00
csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
2020-03-18 19:32:03 +01:00
expect ( csntext . trim ( ) ) . toEqual ( 'newguy is typing' ) ;
expect ( timeout _functions . length ) . toBe ( 1 ) ;
2019-02-25 18:57:09 +01:00
2020-03-24 10:20:11 +01:00
expect ( view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ) . toEqual ( 'newguy is typing' ) ;
2019-02-25 18:57:09 +01:00
2020-03-18 19:32:03 +01:00
// <composing> state for a different occupant
2019-02-25 18:57:09 +01:00
msg = $msg ( {
2020-03-18 19:32:03 +01:00
from : muc _jid + '/nomorenicks' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === 'newguy and nomorenicks are typing' ) ;
2019-02-25 18:57:09 +01:00
// <composing> state for a different occupant
msg = $msg ( {
2020-03-18 19:32:03 +01:00
from : muc _jid + '/majortom' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === 'newguy, nomorenicks and majortom are typing' ) ;
2019-02-25 18:57:09 +01:00
2020-03-18 19:32:03 +01:00
// <composing> state for a different occupant
msg = $msg ( {
from : muc _jid + '/groundcontrol' ,
id : u . getUniqueId ( ) ,
to : 'romeo@montague.lit' ,
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === 'newguy, nomorenicks and others are typing' ) ;
2019-02-25 18:57:09 +01:00
2019-03-05 18:11:10 +01:00
// Check that new messages appear under the chat state notifications
2019-02-25 18:57:09 +01:00
msg = $msg ( {
2019-07-03 14:18:46 +02:00
from : ` ${ muc _jid } /some1 ` ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . t ( 'hello world' ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2019-02-25 18:57:09 +01:00
const messages = view . el . querySelectorAll ( '.message' ) ;
2020-03-31 22:43:55 +02:00
expect ( messages . length ) . toBe ( 2 ) ;
2019-02-25 18:57:09 +01:00
expect ( view . el . querySelectorAll ( '.chat-msg' ) . length ) . toBe ( 1 ) ;
2019-08-12 20:16:34 +02:00
expect ( view . el . querySelector ( '.chat-msg .chat-msg__text' ) . textContent . trim ( ) ) . toBe ( 'hello world' ) ;
2019-02-25 18:57:09 +01:00
2019-03-05 18:11:10 +01:00
// Test that the composing notifications get removed via timeout.
2019-02-25 18:57:09 +01:00
timeout _functions [ 0 ] ( ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) === 'nomorenicks, majortom and groundcontrol are typing' ) ;
2019-02-25 18:57:09 +01:00
done ( ) ;
} ) ) ;
} ) ;
describe ( "A paused notification" , function ( ) {
2020-02-19 16:46:56 +01:00
2019-02-25 18:57:09 +01:00
it ( "will be shown if received" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2019-02-25 18:57:09 +01:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
const muc _jid = 'coven@chat.shakespeare.lit' ;
2020-02-19 16:46:56 +01:00
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'some1' ) ;
2019-02-25 18:57:09 +01:00
const view = _converse . chatboxviews . get ( 'coven@chat.shakespeare.lit' ) ;
2019-06-03 07:58:51 +02:00
/ * < p r e s e n c e t o = " r o m e o @ m o n t a g u e . l i t / _ c o n v e r s e . j s - 2 9 0 9 2 1 6 0 "
2020-03-18 19:32:03 +01:00
* from = "coven@chat.shakespeare.lit/some1" >
* < x xmlns = "http://jabber.org/protocol/muc#user" >
* < item affiliation = "owner" jid = "romeo@montague.lit/_converse.js-29092160" role = "moderator" / >
* < status code = "110" / >
* < / x >
* < / p r e s e n c e > < / b o d y >
* /
2019-02-25 18:57:09 +01:00
let presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
from : 'coven@chat.shakespeare.lit/some1'
} ) . c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'owner' ,
2019-06-03 07:58:51 +02:00
'jid' : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
'role' : 'moderator'
} ) . up ( )
. c ( 'status' , { code : '110' } ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
const csntext = await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( csntext . trim ( ) ) . toEqual ( "some1 has entered the groupchat" ) ;
2019-02-25 18:57:09 +01:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
from : 'coven@chat.shakespeare.lit/newguy'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'newguy@montague.lit/_converse.js-290929789' ,
2019-02-25 18:57:09 +01:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1 and newguy have entered the groupchat" ) ;
2019-02-25 18:57:09 +01:00
presence = $pres ( {
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit/_converse.js-29092160' ,
2019-02-25 18:57:09 +01:00
from : 'coven@chat.shakespeare.lit/nomorenicks'
} )
. c ( 'x' , { xmlns : Strophe . NS . MUC _USER } )
. c ( 'item' , {
'affiliation' : 'none' ,
2019-06-03 07:58:51 +02:00
'jid' : 'nomorenicks@montague.lit/_converse.js-290929789' ,
2019-02-25 18:57:09 +01:00
'role' : 'participant'
} ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( presence ) ) ;
2020-03-31 22:43:55 +02:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ===
"some1, newguy and nomorenicks have entered the groupchat" ) ;
// Manually clear so that we can more easily test
view . model . notifications . set ( 'entered' , [ ] ) ;
await u . waitUntil ( ( ) => ! view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
2019-02-25 18:57:09 +01:00
2019-03-04 17:49:44 +01:00
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
2019-02-25 18:57:09 +01:00
// <composing> state
var msg = $msg ( {
2019-07-03 14:18:46 +02:00
from : muc _jid + '/newguy' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent ) ;
expect ( view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) ) . toBe ( 'newguy is typing' ) ;
2019-02-25 18:57:09 +01:00
// <composing> state for a different occupant
msg = $msg ( {
2019-07-03 14:18:46 +02:00
from : muc _jid + '/nomorenicks' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'composing' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2019-02-25 18:57:09 +01:00
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) == 'newguy and nomorenicks are typing' ) ;
2019-02-25 18:57:09 +01:00
// <paused> state from occupant who typed first
msg = $msg ( {
2019-07-03 14:18:46 +02:00
from : muc _jid + '/newguy' ,
2020-02-07 12:24:02 +01:00
id : u . getUniqueId ( ) ,
2019-06-03 07:58:51 +02:00
to : 'romeo@montague.lit' ,
2019-02-25 18:57:09 +01:00
type : 'groupchat'
} ) . c ( 'body' ) . c ( 'paused' , { 'xmlns' : Strophe . NS . CHATSTATES } ) . tree ( ) ;
2020-03-02 16:59:18 +01:00
await view . model . queueMessage ( msg ) ;
2020-03-24 10:20:11 +01:00
await u . waitUntil ( ( ) => view . el . querySelector ( '.chat-content__notifications' ) . textContent . trim ( ) == 'nomorenicks is typing\n newguy has stopped typing' ) ;
2019-02-25 18:57:09 +01:00
done ( ) ;
} ) ) ;
2018-04-06 13:56:14 +02:00
} ) ;
2017-06-05 14:50:29 +02:00
} ) ;
2019-04-10 22:03:00 +02:00
describe ( "A muted user" , function ( ) {
it ( "will receive a user-friendly error message when trying to send a message" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2019-04-10 22:03:00 +02:00
async function ( done , _converse ) {
2019-07-03 14:18:46 +02:00
const muc _jid = 'trollbox@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'troll' ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2019-04-10 22:03:00 +02:00
const textarea = view . el . querySelector ( '.chat-textarea' ) ;
textarea . value = 'Hello world' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-09-24 15:33:41 +02:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2019-04-10 22:03:00 +02:00
2020-01-17 14:43:33 +01:00
let stanza = u . toStanza ( `
2019-06-03 07:58:51 +02:00
< message xmlns = "jabber:client" type = "error" to = "troll@montague.lit/resource" from = "trollbox@montague.lit" >
2019-04-10 22:03:00 +02:00
< error type = "auth" > < forbidden xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" / > < / e r r o r >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
2020-01-17 14:43:33 +01:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
expect ( view . el . querySelector ( '.chat-error' ) . textContent . trim ( ) ) . toBe (
"Your message was not delivered because you weren't allowed to send it." ) ;
2019-04-10 22:03:00 +02:00
2020-01-17 14:43:33 +01:00
textarea . value = 'Hello again' ;
view . onFormSubmitted ( new Event ( 'submit' ) ) ;
2019-10-09 16:01:38 +02:00
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
2019-09-24 15:33:41 +02:00
2020-01-17 14:43:33 +01:00
stanza = u . toStanza ( `
< message xmlns = "jabber:client" type = "error" to = "troll@montague.lit/resource" from = "trollbox@montague.lit" >
< error type = "auth" >
< forbidden xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" / >
< text xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" > Thou shalt not ! < / t e x t >
< / e r r o r >
< / m e s s a g e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
await new Promise ( resolve => view . once ( 'messageInserted' , resolve ) ) ;
expect ( view . el . querySelector ( '.message:last-child' ) . textContent . trim ( ) ) . toBe (
'Your message was not delivered because you weren\'t allowed to send it. ' +
'The message from the server is: "Thou shalt not!"' )
2019-04-10 22:03:00 +02:00
done ( ) ;
} ) ) ;
2019-04-10 23:56:06 +02:00
it ( "will see an explanatory message instead of a textarea" ,
mock . initConverse (
2019-10-11 16:38:01 +02:00
[ 'rosterGroupsFetched' , 'chatBoxesFetched' ] , { } ,
2019-04-10 23:56:06 +02:00
async function ( done , _converse ) {
2019-04-11 23:10:57 +02:00
const features = [
'http://jabber.org/protocol/muc' ,
'jabber:iq:register' ,
Strophe . NS . SID ,
'muc_moderated' ,
]
2019-07-03 14:18:46 +02:00
const muc _jid = 'trollbox@montague.lit' ;
await test _utils . openAndEnterChatRoom ( _converse , muc _jid , 'troll' , features ) ;
const view = _converse . api . chatviews . get ( muc _jid ) ;
2019-04-11 23:10:57 +02:00
expect ( _ . isNull ( view . el . querySelector ( '.chat-textarea' ) ) ) . toBe ( false ) ;
2019-04-10 23:56:06 +02:00
let stanza = u . toStanza ( `
< presence
2019-06-03 07:58:51 +02:00
from = 'trollbox@montague.lit/troll'
to = 'romeo@montague.lit/orchard' >
2019-04-10 23:56:06 +02:00
< x xmlns = 'http://jabber.org/protocol/muc#user' >
2019-07-22 17:52:06 +02:00
< item affiliation = 'none'
2019-04-10 23:56:06 +02:00
nick = 'troll'
role = 'visitor' / >
< status code = '110' / >
< / x >
< / p r e s e n c e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
2019-04-11 23:10:57 +02:00
expect ( view . el . querySelector ( '.chat-textarea' ) ) . toBe ( null ) ;
let bottom _panel = view . el . querySelector ( '.muc-bottom-panel' ) ;
expect ( bottom _panel . textContent . trim ( ) ) . toBe ( "You're not allowed to send messages in this room" ) ;
// This only applies to moderated rooms, so let's check that
// the textarea becomes visible when the room's
// configuration changes to be non-moderated
view . model . features . set ( 'moderated' , false ) ;
expect ( view . el . querySelector ( '.muc-bottom-panel' ) ) . toBe ( null ) ;
let textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-08-05 01:39:57 +02:00
expect ( textarea === null ) . toBe ( false ) ;
2019-04-11 23:10:57 +02:00
view . model . features . set ( 'moderated' , true ) ;
expect ( view . el . querySelector ( '.chat-textarea' ) ) . toBe ( null ) ;
bottom _panel = view . el . querySelector ( '.muc-bottom-panel' ) ;
expect ( bottom _panel . textContent . trim ( ) ) . toBe ( "You're not allowed to send messages in this room" ) ;
// Check now that things get restored when the user is given a voice
2019-04-10 23:56:06 +02:00
let info _msgs = sizzle ( '.chat-info' , view . el ) ;
2020-03-31 22:43:55 +02:00
expect ( info _msgs . length ) . toBe ( 1 ) ;
expect ( info _msgs [ 0 ] . textContent . trim ( ) ) . toBe ( "troll is no longer an owner of this groupchat" ) ;
2019-04-10 23:56:06 +02:00
stanza = u . toStanza ( `
< presence
2019-06-03 07:58:51 +02:00
from = 'trollbox@montague.lit/troll'
to = 'romeo@montague.lit/orchard' >
2019-04-10 23:56:06 +02:00
< x xmlns = 'http://jabber.org/protocol/muc#user' >
2019-07-22 17:52:06 +02:00
< item affiliation = 'none'
2019-04-10 23:56:06 +02:00
nick = 'troll'
role = 'participant' / >
< status code = '110' / >
< / x >
< / p r e s e n c e > ` ) ;
_converse . connection . _dataRecv ( test _utils . createRequest ( stanza ) ) ;
info _msgs = sizzle ( '.chat-info' , view . el ) ;
2019-04-11 23:10:57 +02:00
bottom _panel = view . el . querySelector ( '.muc-bottom-panel' ) ;
expect ( bottom _panel ) . toBe ( null ) ;
textarea = view . el . querySelector ( '.chat-textarea' ) ;
2019-08-05 01:39:57 +02:00
expect ( textarea === null ) . toBe ( false ) ;
2019-04-11 23:10:57 +02:00
2020-03-31 22:43:55 +02:00
expect ( info _msgs . length ) . toBe ( 2 ) ;
expect ( info _msgs [ 1 ] . textContent . trim ( ) ) . toBe ( "troll has been given a voice" ) ;
2019-04-10 23:56:06 +02:00
done ( ) ;
} ) ) ;
2019-04-10 22:03:00 +02:00
} ) ;
2016-11-03 11:01:09 +01:00
} ) ;
2013-05-11 14:20:07 +02:00
} ) ) ;