Fix broken tests and update changelog

This commit is contained in:
JC Brand 2017-07-12 09:55:43 +02:00
parent 6af029048d
commit 397927b189
7 changed files with 1132 additions and 1078 deletions

View File

@ -2,7 +2,9 @@
## 3.2.0 (Unreleased) ## 3.2.0 (Unreleased)
- #866 Add babel in order to support ES2015 syntax - All promises are now native (or polyfilled) ES2015 Promises
instead of jQuery's Deferred. [jcbrand]
- #866 Add babel in order to support ES2015 syntax [jcbrand]
## 3.1.0 (2017-07-05) ## 3.1.0 (2017-07-05)

View File

@ -6,6 +6,7 @@
var $iq = converse.env.$iq; var $iq = converse.env.$iq;
var $msg = converse.env.$msg; var $msg = converse.env.$msg;
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
var Promise = converse.env.Promise;
return describe("ChatRooms", function () { return describe("ChatRooms", function () {
describe("The \"rooms\" API", function () { describe("The \"rooms\" API", function () {
@ -16,9 +17,9 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy').then(function () {
test_utils.openAndEnterChatRoom(_converse, 'news', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'news', 'localhost', 'dummy').then(function () {
expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy(); expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy(); expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
expect(_converse.chatboxviews.get('news@localhost').$el.is(':visible')).toBeTruthy(); expect(_converse.chatboxviews.get('news@localhost').$el.is(':visible')).toBeTruthy();
@ -38,8 +39,8 @@
expect(_converse.chatboxviews.get('leisure@localhost')).toBeUndefined(); expect(_converse.chatboxviews.get('leisure@localhost')).toBeUndefined();
expect(_converse.chatboxviews.get('news@localhost')).toBeUndefined(); expect(_converse.chatboxviews.get('news@localhost')).toBeUndefined();
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy').then(function () {
expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy(); expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy(); expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
@ -47,15 +48,24 @@
expect(_converse.chatboxviews.get('lounge@localhost')).toBeUndefined(); expect(_converse.chatboxviews.get('lounge@localhost')).toBeUndefined();
expect(_converse.chatboxviews.get('leisure@localhost')).toBeUndefined(); expect(_converse.chatboxviews.get('leisure@localhost')).toBeUndefined();
done(); done();
});
});
});
});
});
})); }));
it("has a method 'get' which returns a wrapped chat room (if it exists)", mock.initConverseWithAsync(function (done, _converse) { it("has a method 'get' which returns a wrapped chat room (if it exists)",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return _converse.rosterview.$el.find('dt').length; return _converse.rosterview.$el.find('dt').length;
}, 300) }, 300)
.then(function () { .then(function () {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var jid = 'lounge@localhost'; var jid = 'lounge@localhost';
var room = _converse.api.rooms.get(jid); var room = _converse.api.rooms.get(jid);
expect(room instanceof Object).toBeTruthy(); expect(room instanceof Object).toBeTruthy();
@ -65,7 +75,7 @@
chatroomview.close(); chatroomview.close();
// Test with mixed case // Test with mixed case
test_utils.openAndEnterChatRoom(_converse, 'Leisure', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'Leisure', 'localhost', 'dummy').then(function () {
jid = 'Leisure@localhost'; jid = 'Leisure@localhost';
room = _converse.api.rooms.get(jid); room = _converse.api.rooms.get(jid);
expect(room instanceof Object).toBeTruthy(); expect(room instanceof Object).toBeTruthy();
@ -91,9 +101,15 @@
expect(typeof room === 'undefined').toBeTruthy(); expect(typeof room === 'undefined').toBeTruthy();
done(); done();
}); });
});
});
})); }));
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box", mock.initConverseWithAsync(function (done, _converse) { it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
// Mock 'getRoomFeatures', otherwise the room won't be // Mock 'getRoomFeatures', otherwise the room won't be
// displayed as it waits first for the features to be returned // displayed as it waits first for the features to be returned
// (when it's a new room being created). // (when it's a new room being created).
@ -106,15 +122,13 @@
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return _converse.rosterview.$el.find('dt').length; return _converse.rosterview.$el.find('dt').length;
}, 300) }, 300).then(function () {
.then(function () {
var chatroomview;
var jid = 'lounge@localhost'; var jid = 'lounge@localhost';
var room = _converse.api.rooms.open(jid); var room = _converse.api.rooms.open(jid);
// Test on chat room that doesn't exist. // Test on chat room that's not yet open
expect(room instanceof Object).toBeTruthy(); expect(room instanceof Object).toBeTruthy();
expect(room.is_chatroom).toBeTruthy(); expect(room.is_chatroom).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid); var chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.$el.is(':visible')).toBeTruthy(); expect(chatroomview.$el.is(':visible')).toBeTruthy();
// Test again, now that the room exists. // Test again, now that the room exists.
@ -231,6 +245,12 @@
' </x>'+ ' </x>'+
' </query>'+ ' </query>'+
' </iq>')[0])); ' </iq>')[0]));
test_utils.waitUntil(function () {
return sent_IQ.toLocaleString() !==
"<iq to='room@conference.example.org' type='get' xmlns='jabber:client' id='"+IQ_id+
"'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>";
}, 300).then(function () {
var $sent_stanza = $(sent_IQ.toLocaleString()); var $sent_stanza = $(sent_IQ.toLocaleString());
expect($sent_stanza.find('field[var="muc#roomconfig_roomname"] value').text()).toBe('Room'); expect($sent_stanza.find('field[var="muc#roomconfig_roomname"] value').text()).toBe('Room');
expect($sent_stanza.find('field[var="muc#roomconfig_roomdesc"] value').text()).toBe('Welcome to this room'); expect($sent_stanza.find('field[var="muc#roomconfig_roomdesc"] value').text()).toBe('Welcome to this room');
@ -242,6 +262,7 @@
expect($sent_stanza.find('field[var="muc#roomconfig_historylength"] value').text()).toBe('20'); expect($sent_stanza.find('field[var="muc#roomconfig_historylength"] value').text()).toBe('20');
done(); done();
}); });
});
})); }));
}); });
@ -287,11 +308,12 @@
* node="x-roomuser-item"/> * node="x-roomuser-item"/>
* </iq> * </iq>
*/ */
expect(sent_IQ.toLocaleString()).toBe( test_utils.waitUntil(function () {
return sent_IQ.toLocaleString() ===
"<iq to='lounge@localhost' from='dummy@localhost/resource' "+ "<iq to='lounge@localhost' from='dummy@localhost/resource' "+
"type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+ "type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/></iq>" "<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/></iq>"
); }, 300).then(function () {
/* * <iq xmlns="jabber:client" type="error" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org"> /* * <iq xmlns="jabber:client" type="error" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org">
* <error type="cancel"> * <error type="cancel">
* <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> * <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
@ -354,6 +376,7 @@
"<query xmlns='http://jabber.org/protocol/muc#owner'><x xmlns='jabber:x:data' type='submit'/>"+ "<query xmlns='http://jabber.org/protocol/muc#owner'><x xmlns='jabber:x:data' type='submit'/>"+
"</query></iq>"); "</query></iq>");
done(); done();
});
})); }));
}); });
@ -459,6 +482,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
var view = _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); var view = _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
spyOn(view, 'generateHeadingHTML').and.callThrough(); spyOn(view, 'generateHeadingHTML').and.callThrough();
var features_stanza = $iq({ var features_stanza = $iq({
from: 'coven@chat.shakespeare.lit', from: 'coven@chat.shakespeare.lit',
@ -488,6 +512,7 @@
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'}) .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
.c('value').t(0); .c('value').t(0);
_converse.connection._dataRecv(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
expect(view.generateHeadingHTML).toHaveBeenCalled(); expect(view.generateHeadingHTML).toHaveBeenCalled();
expect(view.$('.chatroom-description').text()).toBe('This is the description'); expect(view.$('.chatroom-description').text()).toBe('This is the description');
done(); done();
@ -499,7 +524,7 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); } if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var message = 'dummy: Your attention is required'; var message = 'dummy: Your attention is required';
@ -513,6 +538,7 @@
view.handleMUCMessage(msg); view.handleMUCMessage(msg);
expect(view.$el.find('.chat-message').hasClass('mentioned')).toBeTruthy(); expect(view.$el.find('.chat-message').hasClass('mentioned')).toBeTruthy();
done(); done();
});
})); }));
it("supports the /me command", it("supports the /me command",
@ -521,7 +547,7 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); } if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var message = '/me is tired'; var message = '/me is tired';
@ -547,6 +573,7 @@
expect(_.includes(view.$el.find('.chat-msg-author:last').text(), '**Max Mustermann')).toBeTruthy(); expect(_.includes(view.$el.find('.chat-msg-author:last').text(), '**Max Mustermann')).toBeTruthy();
expect(view.$el.find('.chat-msg-content:last').text()).toBe(' is as well'); expect(view.$el.find('.chat-msg-content:last').text()).toBe(' is as well');
done(); done();
});
})); }));
it("can have spaces and special characters in its name", it("can have spaces and special characters in its name",
@ -746,6 +773,9 @@
.c('value').t('cauldronburn'); .c('value').t('cauldronburn');
_converse.connection._dataRecv(test_utils.createRequest(config_stanza)); _converse.connection._dataRecv(test_utils.createRequest(config_stanza));
test_utils.waitUntil(function () {
return view.$('form.chatroom-form').length;
}, 300).then(function () {
expect(view.$('form.chatroom-form').length).toBe(1); expect(view.$('form.chatroom-form').length).toBe(1);
expect(view.$('form.chatroom-form fieldset').length).toBe(2); expect(view.$('form.chatroom-form fieldset').length).toBe(2);
var $membersonly = view.$('input[name="muc#roomconfig_membersonly"]'); var $membersonly = view.$('input[name="muc#roomconfig_membersonly"]');
@ -778,6 +808,7 @@
expect($sent_stanza.find('field[var="muc#roomconfig_allowpm"] value').text()).toBe('moderators'); expect($sent_stanza.find('field[var="muc#roomconfig_allowpm"] value').text()).toBe('moderators');
expect($sent_stanza.find('field[var="muc#roomconfig_presencebroadcast"] value').text()).toBe('moderator'); expect($sent_stanza.find('field[var="muc#roomconfig_presencebroadcast"] value').text()).toBe('moderator');
done(); done();
});
})); }));
it("shows users currently present in the room", it("shows users currently present in the room",
@ -785,7 +816,7 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function() {
var name; var name;
var view = _converse.chatboxviews.get('lounge@localhost'), var view = _converse.chatboxviews.get('lounge@localhost'),
$occupants = view.$('.occupant-list'); $occupants = view.$('.occupant-list');
@ -830,14 +861,13 @@
expect($occupants.find('li').length).toBe(i+1); expect($occupants.find('li').length).toBe(i+1);
} }
done(); done();
});
})); }));
it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks", it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
mock.initConverseWithPromises( mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {}, function (done, _converse) {
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
/* <presence xmlns="jabber:client" to="jc@chat.example.org/converse.js-17184538" /* <presence xmlns="jabber:client" to="jc@chat.example.org/converse.js-17184538"
* from="oo@conference.chat.example.org/&lt;img src=&quot;x&quot; onerror=&quot;alert(123)&quot;/&gt;"> * from="oo@conference.chat.example.org/&lt;img src=&quot;x&quot; onerror=&quot;alert(123)&quot;/&gt;">
* <x xmlns="http://jabber.org/protocol/muc#user"> * <x xmlns="http://jabber.org/protocol/muc#user">
@ -862,6 +892,7 @@
expect(occupant.length).toBe(2); expect(occupant.length).toBe(2);
expect($(occupant).last().text()).toBe("&lt;img src=&quot;x&quot; onerror=&quot;alert(123)&quot;/&gt;"); expect($(occupant).last().text()).toBe("&lt;img src=&quot;x&quot; onerror=&quot;alert(123)&quot;/&gt;");
done(); done();
});
})); }));
it("indicates moderators by means of a special css class and tooltip", it("indicates moderators by means of a special css class and tooltip",
@ -869,7 +900,7 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
var presence = $pres({ var presence = $pres({
@ -891,6 +922,7 @@
expect($(occupant).last().attr('class').indexOf('moderator')).not.toBe(-1); expect($(occupant).last().attr('class').indexOf('moderator')).not.toBe(-1);
expect($(occupant).last().attr('title')).toBe(contact_jid + ' This user is a moderator. Click to mention moderatorman in your message.'); expect($(occupant).last().attr('title')).toBe(contact_jid + ' This user is a moderator. Click to mention moderatorman in your message.');
done(); done();
});
})); }));
it("will use the user's reserved nickname, if it exists", it("will use the user's reserved nickname, if it exists",
@ -928,11 +960,13 @@
* node='x-roomuser-item'/> * node='x-roomuser-item'/>
* </iq> * </iq>
*/ */
expect(sent_IQ.toLocaleString()).toBe(
test_utils.waitUntil(function () {
return sent_IQ.toLocaleString() ===
"<iq to='lounge@localhost' from='dummy@localhost/resource' "+ "<iq to='lounge@localhost' from='dummy@localhost/resource' "+
"type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+ "type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/></iq>" "<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/></iq>";
); }, 300).then(function () {
/* <iq from='coven@chat.shakespeare.lit' /* <iq from='coven@chat.shakespeare.lit'
* id='getnick1' * id='getnick1'
* to='hag66@shakespeare.lit/pda' * to='hag66@shakespeare.lit/pda'
@ -978,6 +1012,7 @@
var info_text = view.$el.find('.chat-content .chat-info').text(); var info_text = view.$el.find('.chat-content .chat-info').text();
expect(info_text).toBe('Your nickname has been automatically set to: thirdwitch'); expect(info_text).toBe('Your nickname has been automatically set to: thirdwitch');
done(); done();
});
})); }));
it("allows the user to invite their roster contacts to enter the chat room", it("allows the user to invite their roster contacts to enter the chat room",
@ -1007,8 +1042,7 @@
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return view.$el.find('input.invited-contact').length; return view.$el.find('input.invited-contact').length;
}, 300) }, 300).then(function () {
.then(function () {
var $input = view.$el.find('input.invited-contact'); var $input = view.$el.find('input.invited-contact');
expect($input.attr('placeholder')).toBe('Invite'); expect($input.attr('placeholder')).toBe('Invite');
$input.val("Felix"); $input.val("Felix");
@ -1060,7 +1094,7 @@
spyOn(window, 'confirm').and.callFake(function () { spyOn(window, 'confirm').and.callFake(function () {
return true; return true;
}); });
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
view.close(); // Hack, otherwise we have to mock stanzas. view.close(); // Hack, otherwise we have to mock stanzas.
@ -1085,6 +1119,7 @@
expect(_converse.chatboxes.models[0].id).toBe('controlbox'); expect(_converse.chatboxes.models[0].id).toBe('controlbox');
expect(_converse.chatboxes.models[1].id).toBe(room_jid); expect(_converse.chatboxes.models[1].id).toBe(room_jid);
done(); done();
});
})); }));
it("shows received groupchat messages", it("shows received groupchat messages",
@ -1117,7 +1152,7 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); } if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
@ -1142,6 +1177,7 @@
// We don't emit an event if it's our own message // We don't emit an event if it's our own message
expect(_converse.emit.calls.count(), 1); expect(_converse.emit.calls.count(), 1);
done(); done();
});
})); }));
it("will cause the chat area to be scrolled down only if it was at the bottom already", it("will cause the chat area to be scrolled down only if it was at the bottom already",
@ -1150,7 +1186,7 @@
function (done, _converse) { function (done, _converse) {
var message = 'This message is received while the chat area is scrolled up'; var message = 'This message is received while the chat area is scrolled up';
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'scrollDown').and.callThrough(); spyOn(view, 'scrollDown').and.callThrough();
/* Create enough messages so that there's a /* Create enough messages so that there's a
@ -1183,6 +1219,7 @@
expect(view.$content.scrollTop()).toBe(0); expect(view.$content.scrollTop()).toBe(0);
done(); done();
}, 500); }, 500);
});
})); }));
it("shows received chatroom subject messages", it("shows received chatroom subject messages",
@ -1190,8 +1227,7 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc'); test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc').then(function () {
var text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org'; var text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
var stanza = Strophe.xmlHtmlNode( var stanza = Strophe.xmlHtmlNode(
'<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">'+ '<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">'+
@ -1204,6 +1240,7 @@
var $chat_content = view.$el.find('.chat-content'); var $chat_content = view.$el.find('.chat-content');
expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+text); expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+text);
done(); done();
});
})); }));
it("escapes the subject before rendering it, to avoid JS-injection attacks", it("escapes the subject before rendering it, to avoid JS-injection attacks",
@ -1211,7 +1248,7 @@
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc'); test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc').then(function () {
spyOn(window, 'alert'); spyOn(window, 'alert');
var subject = '<img src="x" onerror="alert(\'XSS\');"/>'; var subject = '<img src="x" onerror="alert(\'XSS\');"/>';
var view = _converse.chatboxviews.get('jdev@conference.jabber.org'); var view = _converse.chatboxviews.get('jdev@conference.jabber.org');
@ -1219,6 +1256,7 @@
var $chat_content = view.$el.find('.chat-content'); var $chat_content = view.$el.find('.chat-content');
expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+subject); expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+subject);
done(); done();
});
})); }));
it("informs users if their nicknames has been changed.", it("informs users if their nicknames has been changed.",
@ -1262,7 +1300,7 @@
* </presence> * </presence>
*/ */
var __ = utils.__.bind(_converse); var __ = utils.__.bind(_converse);
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'oldnick'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'oldnick').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
var $chat_content = view.$el.find('.chat-content'); var $chat_content = view.$el.find('.chat-content');
@ -1310,7 +1348,8 @@
_converse.connection._dataRecv(test_utils.createRequest(presence)); _converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(3); expect($chat_content.find('div.chat-info').length).toBe(3);
expect($chat_content.find('div.chat-info').last().html()).toBe(__(_converse.muc.new_nickname_messages["303"], "newnick")); expect($chat_content.find('div.chat-info').last().html()).toBe(
__(_converse.muc.new_nickname_messages["303"], "newnick"));
$occupants = view.$('.occupant-list'); $occupants = view.$('.occupant-list');
expect($occupants.children().length).toBe(0); expect($occupants.children().length).toBe(0);
@ -1330,12 +1369,15 @@
_converse.connection._dataRecv(test_utils.createRequest(presence)); _converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(4); expect($chat_content.find('div.chat-info').length).toBe(4);
expect($chat_content.find('div.chat-info').get(2).textContent).toBe(__(_converse.muc.new_nickname_messages["303"], "newnick")); expect($chat_content.find('div.chat-info').get(2).textContent).toBe(
expect($chat_content.find('div.chat-info').last().html()).toBe("newnick has joined the room."); __(_converse.muc.new_nickname_messages["303"], "newnick"));
expect($chat_content.find('div.chat-info').last().html()).toBe(
"newnick has joined the room.");
$occupants = view.$('.occupant-list'); $occupants = view.$('.occupant-list');
expect($occupants.children().length).toBe(1); expect($occupants.children().length).toBe(1);
expect($occupants.children().first(0).text()).toBe("newnick"); expect($occupants.children().first(0).text()).toBe("newnick");
done(); done();
});
})); }));
it("queries for the room information before attempting to join the user", it("queries for the room information before attempting to join the user",
@ -1416,7 +1458,7 @@
var sent_IQ, IQ_id; var sent_IQ, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
test_utils.openAndEnterChatRoom(_converse, 'room', 'conference.example.org', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'room', 'conference.example.org', 'dummy').then(function () {
var view = _converse.chatboxviews.get('room@conference.example.org'); var view = _converse.chatboxviews.get('room@conference.example.org');
view.model.set({ view.model.set({
'passwordprotected': false, 'passwordprotected': false,
@ -1462,6 +1504,7 @@
expect(view.model.get('open')).toBe(false); expect(view.model.get('open')).toBe(false);
expect(view.model.get('membersonly')).toBe(true); expect(view.model.get('membersonly')).toBe(true);
done(); done();
});
})); }));
it("indicates when a room is no longer anonymous", it("indicates when a room is no longer anonymous",
@ -1532,7 +1575,7 @@
* </x> * </x>
* </presence> * </presence>
*/ */
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var presence = $pres().attrs({ var presence = $pres().attrs({
from:'lounge@localhost/dummy', from:'lounge@localhost/dummy',
to:'dummy@localhost/pda', to:'dummy@localhost/pda',
@ -1561,6 +1604,7 @@
'The reason given is: "Avaunt, you cullion!".' 'The reason given is: "Avaunt, you cullion!".'
); );
done(); done();
});
})); }));
it("can be saved to, and retrieved from, browserStorage", it("can be saved to, and retrieved from, browserStorage",
@ -2063,7 +2107,7 @@
IQ_ids.push(sendIQ.bind(this)(iq, callback, errback)); IQ_ids.push(sendIQ.bind(this)(iq, callback, errback));
}); });
test_utils.openChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'dummy'); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'dummy'});
// State that the chat is members-only via the features IQ // State that the chat is members-only via the features IQ
var features_stanza = $iq({ var features_stanza = $iq({
@ -2089,25 +2133,24 @@
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var sent_stanza, var sent_stanza, sent_id;
sent_id;
spyOn(_converse.connection, 'send').and.callFake(function (stanza) { spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') { if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') {
sent_id = stanza.nodeTree.getAttribute('id'); sent_id = stanza.nodeTree.getAttribute('id');
sent_stanza = stanza; sent_stanza = stanza;
} }
}); });
var name = mock.cur_names[0]; var name = mock.cur_names[0];
var invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost'; var invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var reason = "Please join this chat room"; var reason = "Please join this chat room";
view.directInvite(invitee_jid, reason); view.directInvite(invitee_jid, reason);
// Check in reverse order that we requested all three lists
// (member, owner and admin).
var admin_iq_id = IQ_ids.pop(); var admin_iq_id = IQ_ids.pop();
var owner_iq_id = IQ_ids.pop(); var owner_iq_id = IQ_ids.pop();
var member_iq_id = IQ_ids.pop(); var member_iq_id = IQ_ids.pop();
// Check in reverse order that we requested all three lists
// (member, owner and admin).
expect(sent_IQs.pop().toLocaleString()).toBe( expect(sent_IQs.pop().toLocaleString()).toBe(
"<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+ "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
"<query xmlns='http://jabber.org/protocol/muc#admin'>"+ "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
@ -2180,16 +2223,21 @@
}); });
_converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza)); _converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
test_utils.waitUntil(function () {
return IQ_ids.length;
}, 300).then(function () {
// Check that the member list now gets updated // Check that the member list now gets updated
expect(sent_IQs.pop().toLocaleString()).toBe( var iq = "<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+IQ_ids.pop()+"'>"+
"<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+IQ_ids.pop()+"'>"+
"<query xmlns='http://jabber.org/protocol/muc#admin'>"+ "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
"<item affiliation='member' jid='"+invitee_jid+"'>"+ "<item affiliation='member' jid='"+invitee_jid+"'>"+
"<reason>Please join this chat room</reason>"+ "<reason>Please join this chat room</reason>"+
"</item>"+ "</item>"+
"</query>"+ "</query>"+
"</iq>"); "</iq>";
test_utils.waitUntil(function () {
return _.includes(_.invokeMap(sent_IQs, Object.prototype.toLocaleString), iq);
}, 300).then(function () {
// Finally check that the user gets invited. // Finally check that the user gets invited.
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec) expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
"<message from='dummy@localhost/resource' to='"+invitee_jid+"' id='"+sent_id+"' xmlns='jabber:client'>"+ "<message from='dummy@localhost/resource' to='"+invitee_jid+"' id='"+sent_id+"' xmlns='jabber:client'>"+
@ -2197,6 +2245,8 @@
"</message>" "</message>"
); );
done(); done();
});
});
})); }));
}); });
@ -2346,6 +2396,9 @@
expect(panel.$('#available-chatrooms').children('dd').length).toBe(4); expect(panel.$('#available-chatrooms').children('dd').length).toBe(4);
done(); done();
})); }));
});
describe("The \"Rooms\" Panel", function () {
it("shows the number of unread mentions received", it("shows the number of unread mentions received",
mock.initConverseWithPromises( mock.initConverseWithPromises(
@ -2354,7 +2407,8 @@
var room_jid = 'kitchen@conference.shakespeare.lit'; var room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.openAndEnterChatRoom( test_utils.openAndEnterChatRoom(
_converse, 'kitchen', 'conference.shakespeare.lit', 'fires'); _converse, 'kitchen', 'conference.shakespeare.lit', 'fires').then(function () {
test_utils.openContactsPanel(_converse); test_utils.openContactsPanel(_converse);
var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel; var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
expect(_.isNull(roomspanel.tab_el.querySelector('.msgs-indicator'))).toBeTruthy(); expect(_.isNull(roomspanel.tab_el.querySelector('.msgs-indicator'))).toBeTruthy();
@ -2371,8 +2425,12 @@
to: 'dummy@localhost', to: 'dummy@localhost',
type: 'groupchat' type: 'groupchat'
}).c('body').t(message).tree(); }).c('body').t(message).tree();
view.handleMUCMessage(msg); view.handleMUCMessage(msg);
test_utils.waitUntil(function () {
return _.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs');
}, 300).then(function () {
expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeTruthy(); expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeTruthy();
expect(roomspanel.tab_el.querySelector('.msgs-indicator').textContent).toBe('1'); expect(roomspanel.tab_el.querySelector('.msgs-indicator').textContent).toBe('1');
@ -2392,6 +2450,8 @@
expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeFalsy(); expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeFalsy();
expect(_.isNull(roomspanel.tab_el.querySelector('.msgs-indicator'))).toBeTruthy(); expect(_.isNull(roomspanel.tab_el.querySelector('.msgs-indicator'))).toBeTruthy();
done(); done();
});
});
})); }));
}); });
}); });

View File

@ -144,7 +144,7 @@
var room_jid = 'kitchen@conference.shakespeare.lit'; var room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.openAndEnterChatRoom( test_utils.openAndEnterChatRoom(
_converse, 'kitchen', 'conference.shakespeare.lit', 'fires'); _converse, 'kitchen', 'conference.shakespeare.lit', 'fires').then(function () {
var view = _converse.chatboxviews.get(room_jid); var view = _converse.chatboxviews.get(room_jid);
view.model.set({'minimized': true}); view.model.set({'minimized': true});
@ -162,6 +162,7 @@
expect(_converse.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeTruthy(); expect(_converse.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeTruthy();
expect(_converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe('1'); expect(_converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe('1');
done(); done();
});
})); }));
}); });
})); }));

View File

@ -43,7 +43,7 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); } if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var no_notification = false; var no_notification = false;
@ -73,6 +73,7 @@
delete window.Notification; delete window.Notification;
} }
done(); done();
});
})); }));
it("is shown for headline messages", it("is shown for headline messages",
@ -158,7 +159,7 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
_converse.play_sounds = true; _converse.play_sounds = true;
spyOn(_converse, 'playSoundNotification'); spyOn(_converse, 'playSoundNotification');
var view = _converse.chatboxviews.get('lounge@localhost'); var view = _converse.chatboxviews.get('lounge@localhost');
@ -195,6 +196,7 @@
expect(_converse.playSoundNotification, 1); expect(_converse.playSoundNotification, 1);
_converse.play_sounds = false; _converse.play_sounds = false;
done(); done();
});
})); }));
}); });
}); });

View File

@ -94,10 +94,10 @@
.then(function () { .then(function () {
var room_jid = 'kitchen@conference.shakespeare.lit'; var room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.openAndEnterChatRoom( test_utils.openAndEnterChatRoom(
_converse, 'kitchen', 'conference.shakespeare.lit', 'romeo'); _converse, 'kitchen', 'conference.shakespeare.lit', 'romeo').then(function () {
var view = _converse.chatboxviews.get(room_jid); var view = _converse.chatboxviews.get(room_jid);
view.model.set({'minimized': true}); view.model.set({'minimized': true});
var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
var nick = mock.chatroom_names[0]; var nick = mock.chatroom_names[0];
view.handleMUCMessage( view.handleMUCMessage(
@ -145,6 +145,7 @@
expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy(); expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy();
done(); done();
}); });
});
})); }));
}); });
})); }));

View File

@ -62,7 +62,7 @@
const ROOMS_PANEL_ID = 'chatrooms'; const ROOMS_PANEL_ID = 'chatrooms';
const CHATROOMS_TYPE = 'chatroom'; const CHATROOMS_TYPE = 'chatroom';
const { Strophe, Backbone, $iq, $build, $msg, $pres, b64_sha1, sizzle, utils, _, fp, moment } = converse.env; const { Strophe, Backbone, Promise, $iq, $build, $msg, $pres, b64_sha1, sizzle, utils, _, fp, moment } = converse.env;
// Add Strophe Namespaces // Add Strophe Namespaces
Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin"); Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
@ -448,11 +448,12 @@
this.registerHandlers(); this.registerHandlers();
if (this.model.get('connection_status') !== ROOMSTATUS.ENTERED) { if (this.model.get('connection_status') !== ROOMSTATUS.ENTERED) {
this.getRoomFeatures().always(() => { const handler = () => {
this.join(); this.join();
this.fetchMessages(); this.fetchMessages();
_converse.emit('chatRoomOpened', this); _converse.emit('chatRoomOpened', this);
}); }
this.getRoomFeatures().then(handler, handler);
} else { } else {
this.fetchMessages(); this.fetchMessages();
_converse.emit('chatRoomOpened', this); _converse.emit('chatRoomOpened', this);
@ -636,13 +637,13 @@
* A promise which resolves once the list has been * A promise which resolves once the list has been
* retrieved. * retrieved.
*/ */
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
affiliation = affiliation || 'member'; affiliation = affiliation || 'member';
const iq = $iq({to: chatroom_jid, type: "get"}) const iq = $iq({to: chatroom_jid, type: "get"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN}) .c("query", {xmlns: Strophe.NS.MUC_ADMIN})
.c("item", {'affiliation': affiliation}); .c("item", {'affiliation': affiliation});
_converse.connection.sendIQ(iq, deferred.resolve, deferred.reject); _converse.connection.sendIQ(iq, resolve, reject);
return deferred.promise(); });
}, },
parseMemberListIQ (iq) { parseMemberListIQ (iq) {
@ -725,7 +726,7 @@
* (Object) member: Map containing the member's jid and * (Object) member: Map containing the member's jid and
* optionally a reason and affiliation. * optionally a reason and affiliation.
*/ */
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
const iq = $iq({to: chatroom_jid, type: "set"}) const iq = $iq({to: chatroom_jid, type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN}) .c("query", {xmlns: Strophe.NS.MUC_ADMIN})
.c("item", { .c("item", {
@ -735,8 +736,8 @@
if (!_.isUndefined(member.reason)) { if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason); iq.c("reason", member.reason);
} }
_converse.connection.sendIQ(iq, deferred.resolve, deferred.reject); _converse.connection.sendIQ(iq, resolve, reject);
return deferred; });
}, },
setAffiliation (affiliation, members) { setAffiliation (affiliation, members) {
@ -772,10 +773,10 @@
members, members,
_.partial(this.sendAffiliationIQ, this.model.get('jid'), affiliation) _.partial(this.sendAffiliationIQ, this.model.get('jid'), affiliation)
); );
return $.when.apply($, promises); return Promise.all(promises);
}, },
setAffiliations (members, onSuccess, onError) { setAffiliations (members) {
/* Send IQ stanzas to the server to modify the /* Send IQ stanzas to the server to modify the
* affiliations in this room. * affiliations in this room.
* *
@ -786,14 +787,8 @@
* (Function) onSuccess: callback for a succesful response * (Function) onSuccess: callback for a succesful response
* (Function) onError: callback for an error response * (Function) onError: callback for an error response
*/ */
if (_.isEmpty(members)) {
// Succesfully updated with zero affilations :)
onSuccess(null);
return;
}
const affiliations = _.uniq(_.map(members, 'affiliation')); const affiliations = _.uniq(_.map(members, 'affiliation'));
const promises = _.map(affiliations, _.partial(this.setAffiliation.bind(this), _, members)); _.each(affiliations, _.partial(this.setAffiliation.bind(this), _, members));
$.when.apply($, promises).done(onSuccess).fail(onError);
}, },
marshallAffiliationIQs () { marshallAffiliationIQs () {
@ -814,12 +809,13 @@
if (_.isString(affiliations)) { if (_.isString(affiliations)) {
affiliations = [affiliations]; affiliations = [affiliations];
} }
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
const promises = _.map(affiliations, _.partial(this.requestMemberList, this.model.get('jid'))); const promises = _.map(affiliations, _.partial(this.requestMemberList, this.model.get('jid')));
$.when.apply($, promises).always( Promise.all(promises).then(
_.flow(this.marshallAffiliationIQs.bind(this), deferred.resolve) _.flow(this.marshallAffiliationIQs.bind(this), resolve),
_.flow(this.marshallAffiliationIQs.bind(this), resolve)
); );
return deferred.promise(); });
}, },
updateMemberLists (members, affiliations, deltaFunc) { updateMemberLists (members, affiliations, deltaFunc) {
@ -840,15 +836,9 @@
* updated or once it's been established there's no need * updated or once it's been established there's no need
* to update the list. * to update the list.
*/ */
const deferred = new $.Deferred();
this.getJidsWithAffiliations(affiliations).then((old_members) => { this.getJidsWithAffiliations(affiliations).then((old_members) => {
this.setAffiliations( this.setAffiliations(deltaFunc(members, old_members));
deltaFunc(members, old_members),
deferred.resolve,
deferred.reject
);
}); });
return deferred.promise();
}, },
directInvite (recipient, reason) { directInvite (recipient, reason) {
@ -1010,14 +1000,14 @@
this.setAffiliation('admin', this.setAffiliation('admin',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
}]).fail(this.onCommandError.bind(this)); }]).then(null, this.onCommandError.bind(this));
break; break;
case 'ban': case 'ban':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('outcast', this.setAffiliation('outcast',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
}]).fail(this.onCommandError.bind(this)); }]).then(null, this.onCommandError.bind(this));
break; break;
case 'clear': case 'clear':
this.clearChatRoomMessages(); this.clearChatRoomMessages();
@ -1065,7 +1055,7 @@
this.setAffiliation('member', this.setAffiliation('member',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
}]).fail(this.onCommandError.bind(this)); }]).then(null, this.onCommandError.bind(this));
break; break;
case 'nick': case 'nick':
_converse.connection.send($pres({ _converse.connection.send($pres({
@ -1079,7 +1069,7 @@
this.setAffiliation('owner', this.setAffiliation('owner',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
}]).fail(this.onCommandError.bind(this)); }]).then(null, this.onCommandError.bind(this));
break; break;
case 'op': case 'op':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.validateRoleChangeCommand(command, args)) { break; }
@ -1092,7 +1082,7 @@
this.setAffiliation('none', this.setAffiliation('none',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
}]).fail(this.onCommandError.bind(this)); }]).then(null, this.onCommandError.bind(this));
break; break;
case 'topic': case 'topic':
case 'subject': case 'subject':
@ -1330,22 +1320,18 @@
* Parameters: * Parameters:
* (HTMLElement) form: The configuration form DOM element. * (HTMLElement) form: The configuration form DOM element.
*/ */
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
const $inputs = $(form).find(':input:not([type=button]):not([type=submit])'), const $inputs = $(form).find(':input:not([type=button]):not([type=submit])'),
configArray = []; configArray = [];
$inputs.each(function () { $inputs.each(function () {
configArray.push(utils.webForm2xForm(this)); configArray.push(utils.webForm2xForm(this));
}); });
this.sendConfiguration( this.sendConfiguration(configArray, resolve, reject);
configArray,
deferred.resolve,
deferred.reject
);
this.$el.find('div.chatroom-form-container').hide((el) => { this.$el.find('div.chatroom-form-container').hide((el) => {
$(el).remove(); $(el).remove();
this.renderAfterTransition(); this.renderAfterTransition();
}); });
return deferred.promise(); });
}, },
autoConfigureChatRoom () { autoConfigureChatRoom () {
@ -1360,13 +1346,11 @@
* containing the configuration. * containing the configuration.
*/ */
const that = this; const that = this;
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
this.fetchRoomConfiguration().then(function (stanza) { this.fetchRoomConfiguration().then(function (stanza) {
const configArray = [], const configArray = [],
fields = stanza.querySelectorAll('field'), fields = stanza.querySelectorAll('field'),
config = that.model.get('roomconfig'); config = that.model.get('roomconfig');
let count = fields.length; let count = fields.length;
_.each(fields, function (field) { _.each(fields, function (field) {
@ -1389,15 +1373,11 @@
} }
configArray.push(field); configArray.push(field);
if (!--count) { if (!--count) {
that.sendConfiguration( that.sendConfiguration(configArray, resolve, reject);
configArray,
deferred.resolve,
deferred.reject
);
} }
}); });
}); });
return deferred; });
}, },
cancelConfiguration () { cancelConfiguration () {
@ -1419,7 +1399,7 @@
* Parameters: * Parameters:
* (Function) handler: The handler for the response IQ * (Function) handler: The handler for the response IQ
*/ */
const deferred = new $.Deferred(); return new Promise((resolve, reject) => {
_converse.connection.sendIQ( _converse.connection.sendIQ(
$iq({ $iq({
'to': this.model.get('jid'), 'to': this.model.get('jid'),
@ -1429,21 +1409,14 @@
if (handler) { if (handler) {
handler.apply(this, arguments); handler.apply(this, arguments);
} }
deferred.resolve(iq); resolve(iq);
}, },
deferred.reject // errback reject // errback
); );
return deferred.promise(); });
}, },
getRoomFeatures () { parseRoomFeatures (iq) {
/* Fetch the room disco info, parse it and then
* save it on the Backbone.Model of this chat rooms.
*/
const deferred = new $.Deferred();
const that = this;
_converse.connection.disco.info(this.model.get('jid'), null,
function (iq) {
/* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo /* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo
* *
* <identity * <identity
@ -1476,13 +1449,22 @@
if (!_.isNull(desc_field)) { if (!_.isNull(desc_field)) {
features.description = desc_field.textContent; features.description = desc_field.textContent;
} }
that.model.save(features); this.model.save(features);
return deferred.resolve();
}, },
deferred.reject,
getRoomFeatures () {
/* Fetch the room disco info, parse it and then
* save it on the Backbone.Model of this chat rooms.
*/
return new Promise((resolve, reject) => {
_converse.connection.disco.info(
this.model.get('jid'),
null,
_.flow(this.parseRoomFeatures.bind(this), resolve),
() => { reject(new Error("Could not parse the room features")) },
5000 5000
); );
return deferred.promise(); });
}, },
getAndRenderConfigurationForm (ev) { getAndRenderConfigurationForm (ev) {

View File

@ -86,13 +86,13 @@
this.openRoomsPanel(_converse); this.openRoomsPanel(_converse);
var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel; var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
roomspanel.$el.find('input.new-chatroom-name').val(room); roomspanel.$el.find('input.new-chatroom-name').val(room);
roomspanel.$el.find('input.new-chatroom-nick').val(nick);
roomspanel.$el.find('input.new-chatroom-server').val(server); roomspanel.$el.find('input.new-chatroom-server').val(server);
roomspanel.$el.find('form').submit(); roomspanel.$el.find('form').submit();
this.closeControlBox(_converse); this.closeControlBox(_converse);
}; };
utils.openAndEnterChatRoom = function (converse, room, server, nick) { utils.openAndEnterChatRoom = function (converse, room, server, nick) {
return new Promise(function (resolve, reject) {
sinon.spy(converse.connection, 'sendIQ'); sinon.spy(converse.connection, 'sendIQ');
utils.openChatRoom(converse, room, server); utils.openChatRoom(converse, room, server);
var view = converse.chatboxviews.get((room+'@'+server).toLowerCase()); var view = converse.chatboxviews.get((room+'@'+server).toLowerCase());
@ -100,7 +100,7 @@
// We pretend this is a new room, so no disco info is returned. // We pretend this is a new room, so no disco info is returned.
var IQ_id = converse.connection.sendIQ.firstCall.returnValue; var IQ_id = converse.connection.sendIQ.firstCall.returnValue;
var features_stanza = $iq({ var features_stanza = $iq({
from: 'lounge@localhost', 'from': 'lounge@localhost',
'id': IQ_id, 'id': IQ_id,
'to': 'dummy@localhost/desktop', 'to': 'dummy@localhost/desktop',
'type': 'error' 'type': 'error'
@ -108,6 +108,9 @@
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"}); .c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
converse.connection._dataRecv(utils.createRequest(features_stanza)); converse.connection._dataRecv(utils.createRequest(features_stanza));
utils.waitUntil(function () {
return converse.connection.sendIQ.secondCall;
}).then(function () {
// The XMPP server returns the reserved nick for this user. // The XMPP server returns the reserved nick for this user.
IQ_id = converse.connection.sendIQ.secondCall.returnValue; IQ_id = converse.connection.sendIQ.secondCall.returnValue;
var stanza = $iq({ var stanza = $iq({
@ -134,6 +137,9 @@
.c('status').attrs({code:'110'}); .c('status').attrs({code:'110'});
converse.connection._dataRecv(utils.createRequest(presence)); converse.connection._dataRecv(utils.createRequest(presence));
converse.connection.sendIQ.restore(); converse.connection.sendIQ.restore();
resolve();
});
});
}; };
utils.clearBrowserStorage = function () { utils.clearBrowserStorage = function () {