Commit 506aa331 authored by JC Brand's avatar JC Brand

Wait for promises before opening chats in API methods

parent cb118b9c
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
- New API method `_converse.api.vcard.update`. - New API method `_converse.api.vcard.update`.
- The `contactStatusChanged` event has been renamed to `contactPresenceChanged` - The `contactStatusChanged` event has been renamed to `contactPresenceChanged`
and a event `presenceChanged` is now also triggered on the contact. and a event `presenceChanged` is now also triggered on the contact.
- `_converse.api.chats.open` and `_converse.api.rooms.open` now returns a
`Presence` which resolves with the `Backbone.Model` representing the chat
object.
## UI changes ## UI changes
......
...@@ -76149,17 +76149,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -76149,17 +76149,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.occupants.on('add', this.showJoinNotification, this); this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this); this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('change:show', occupant => { this.model.occupants.on('change:show', this.showJoinOrLeaveNotification, this);
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
this.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
this.showJoinNotification(occupant);
}
});
this.createEmojiPicker(); this.createEmojiPicker();
this.createOccupantsView(); this.createOccupantsView();
this.render().insertIntoDOM(); this.render().insertIntoDOM();
...@@ -76169,8 +76159,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -76169,8 +76159,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const handler = () => { const handler = () => {
if (!u.isPersistableModel(this.model)) { if (!u.isPersistableModel(this.model)) {
// Happens during tests, nothing to do if this // Happens during tests, nothing to do if this
// is a hanging chatbox (i.e. not in the // is a hanging chatbox (i.e. not in the collection anymore).
// collection anymore).
return; return;
} }
...@@ -77047,6 +77036,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -77047,6 +77036,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
} }
}, },
showJoinOrLeaveNotification(occupant) {
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
this.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
this.showJoinNotification(occupant);
}
},
showJoinNotification(occupant) { showJoinNotification(occupant) {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) { if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
return; return;
...@@ -77094,10 +77095,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -77094,10 +77095,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
showLeaveNotification(occupant) { showLeaveNotification(occupant) {
const nick = occupant.get('nick'), const nick = occupant.get('nick'),
stat = occupant.get('status'), stat = occupant.get('status'),
last_el = this.content.lastElementChild, last_el = this.content.lastElementChild;
last_msg_date = last_el.getAttribute('data-isodate');
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && moment(last_msg_date).isSame(new Date(), "day") && _.get(last_el, 'dataset', {}).join === `"${nick}"`) { if (last_el && _.includes(_.get(last_el, 'classList', []), 'chat-info') && moment(last_el.getAttribute('data-isodate')).isSame(new Date(), "day") && _.get(last_el, 'dataset', {}).join === `"${nick}"`) {
let message; let message;
if (_.isNil(stat)) { if (_.isNil(stat)) {
...@@ -77128,7 +77128,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -77128,7 +77128,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'data': `data-leave="${nick}"` 'data': `data-leave="${nick}"`
}; };
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) { if (last_el && _.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) {
last_el.outerHTML = tpl_info(data); last_el.outerHTML = tpl_info(data);
} else { } else {
const el = u.stringToElement(tpl_info(data)); const el = u.stringToElement(tpl_info(data));
...@@ -83843,8 +83843,13 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -83843,8 +83843,13 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
xhr.onload = function () { xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) { if (xhr.status >= 200 && xhr.status < 400) {
jed_instance = new Jed(window.JSON.parse(xhr.responseText)); try {
const data = window.JSON.parse(xhr.responseText);
jed_instance = new Jed(data);
resolve(); resolve();
} catch (e) {
xhr.onerror(e);
}
} else { } else {
xhr.onerror(); xhr.onerror();
} }
...@@ -34,24 +34,24 @@ ...@@ -34,24 +34,24 @@
}); });
spyOn(_converse.connection, 'getUniqueId').and.callThrough(); spyOn(_converse.connection, 'getUniqueId').and.callThrough();
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC'); let view;
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC')
.then(() => {
var jid = 'theplay@conference.shakespeare.lit'; var jid = 'theplay@conference.shakespeare.lit';
var view = _converse.chatboxviews.get(jid); view = _converse.chatboxviews.get(jid);
spyOn(view, 'renderBookmarkForm').and.callThrough(); spyOn(view, 'renderBookmarkForm').and.callThrough();
spyOn(view, 'closeForm').and.callThrough(); spyOn(view, 'closeForm').and.callThrough();
return test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
test_utils.waitUntil(function () { }).then(() => {
return !_.isNull(view.el.querySelector('.toggle-bookmark')); var bookmark = view.el.querySelector('.toggle-bookmark');
}, 300).then(function () { bookmark.click();
var $bookmark = $(view.el).find('.toggle-bookmark');
$bookmark[0].click();
expect(view.renderBookmarkForm).toHaveBeenCalled(); expect(view.renderBookmarkForm).toHaveBeenCalled();
view.el.querySelector('.button-cancel').click(); view.el.querySelector('.button-cancel').click();
expect(view.closeForm).toHaveBeenCalled(); expect(view.closeForm).toHaveBeenCalled();
expect($bookmark.hasClass('on-button'), false); expect(u.hasClass('on-button', bookmark), false);
$bookmark[0].click(); bookmark.click();
expect(view.renderBookmarkForm).toHaveBeenCalled(); expect(view.renderBookmarkForm).toHaveBeenCalled();
/* Client uploads data: /* Client uploads data:
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
view.el.querySelector('.btn-primary').click(); view.el.querySelector('.btn-primary').click();
expect(view.model.get('bookmarked')).toBeTruthy(); expect(view.model.get('bookmarked')).toBeTruthy();
expect($bookmark.hasClass('on-button'), true); expect(u.hasClass('on-button', bookmark), true);
expect(sent_stanza.toLocaleString()).toBe( expect(sent_stanza.toLocaleString()).toBe(
"<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+ "<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+
...@@ -175,17 +175,16 @@ ...@@ -175,17 +175,16 @@
it("displays that it's bookmarked through its bookmark icon", mock.initConverseWithPromises( it("displays that it's bookmarked through its bookmark icon", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, function (done, _converse) { null, ['rosterGroupsFetched'], {}, function (done, _converse) {
let view;
test_utils.waitUntilDiscoConfirmed( test_utils.waitUntilDiscoConfirmed(
_converse, _converse.bare_jid, _converse, _converse.bare_jid,
[{'category': 'pubsub', 'type': 'pep'}], [{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options'] ['http://jabber.org/protocol/pubsub#publish-options']
).then(function () { ).then(() => test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'))
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); .then(() => {
var view = _converse.chatboxviews.get('lounge@localhost'); view = _converse.chatboxviews.get('lounge@localhost');
return test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')))
test_utils.waitUntil(function () { }).then(function () {
return !_.isNull(view.el.querySelector('.toggle-bookmark'));
}, 300).then(function () {
var bookmark_icon = view.el.querySelector('.toggle-bookmark'); var bookmark_icon = view.el.querySelector('.toggle-bookmark');
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy(); expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
view.model.set('bookmarked', true); view.model.set('bookmarked', true);
...@@ -194,27 +193,25 @@ ...@@ -194,27 +193,25 @@
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy(); expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
done(); done();
}); });
});
})); }));
it("can be unbookmarked", mock.initConverseWithPromises( it("can be unbookmarked", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, function (done, _converse) { null, ['rosterGroupsFetched'], {}, function (done, _converse) {
let sent_stanza, IQ_id, view, sendIQ;
test_utils.waitUntilDiscoConfirmed( test_utils.waitUntilDiscoConfirmed(
_converse, _converse.bare_jid, _converse, _converse.bare_jid,
[{'category': 'pubsub', 'type': 'pep'}], [{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options'] ['http://jabber.org/protocol/pubsub#publish-options']
).then(function () { ).then(() => {
var sent_stanza, IQ_id; sendIQ = _converse.connection.sendIQ;
var sendIQ = _converse.connection.sendIQ; return test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
}).then(() => {
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
var jid = 'theplay@conference.shakespeare.lit'; var jid = 'theplay@conference.shakespeare.lit';
var view = _converse.chatboxviews.get(jid); view = _converse.chatboxviews.get(jid);
return test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
test_utils.waitUntil(function () { }).then(function () {
return !_.isNull(view.el.querySelector('.toggle-bookmark'));
}, 300).then(function () {
spyOn(view, 'toggleBookmark').and.callThrough(); spyOn(view, 'toggleBookmark').and.callThrough();
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough(); spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
view.delegateEvents(); view.delegateEvents();
...@@ -227,17 +224,17 @@ ...@@ -227,17 +224,17 @@
}); });
expect(_converse.bookmarks.length).toBe(1); expect(_converse.bookmarks.length).toBe(1);
expect(view.model.get('bookmarked')).toBeTruthy(); expect(view.model.get('bookmarked')).toBeTruthy();
var $bookmark_icon = $(view.el.querySelector('.toggle-bookmark')); var bookmark_icon = view.el.querySelector('.toggle-bookmark');
expect($bookmark_icon.hasClass('button-on')).toBeTruthy(); expect(u.hasClass('button-on', bookmark_icon)).toBeTruthy();
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
spyOn(_converse.connection, 'getUniqueId').and.callThrough(); spyOn(_converse.connection, 'getUniqueId').and.callThrough();
$bookmark_icon[0].click(); bookmark_icon.click();
expect(view.toggleBookmark).toHaveBeenCalled(); expect(view.toggleBookmark).toHaveBeenCalled();
expect($bookmark_icon.hasClass('button-on')).toBeFalsy(); expect(u.hasClass('button-on', bookmark_icon)).toBeFalsy();
expect(_converse.bookmarks.length).toBe(0); expect(_converse.bookmarks.length).toBe(0);
// Check that an IQ stanza is sent out, containing no // Check that an IQ stanza is sent out, containing no
...@@ -269,7 +266,6 @@ ...@@ -269,7 +266,6 @@
); );
done(); done();
}); });
});
})); }));
}); });
...@@ -585,9 +581,8 @@ ...@@ -585,9 +581,8 @@
'name': 'The Play', 'name': 'The Play',
'nick': '' 'nick': ''
}); });
test_utils.waitUntil(function () { test_utils.waitUntil(() => $('#chatrooms .bookmarks.rooms-list .room-item:visible').length
return $('#chatrooms .bookmarks.rooms-list .room-item:visible').length; ).then(function () {
}, 300).then(function () {
expect($('#chatrooms .bookmarks.rooms-list').hasClass('collapsed')).toBeFalsy(); expect($('#chatrooms .bookmarks.rooms-list').hasClass('collapsed')).toBeFalsy();
expect($('#chatrooms .bookmarks.rooms-list .room-item:visible').length).toBe(1); expect($('#chatrooms .bookmarks.rooms-list .room-item:visible').length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED); expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
...@@ -612,6 +607,7 @@ ...@@ -612,6 +607,7 @@
{ hide_open_bookmarks: true }, { hide_open_bookmarks: true },
function (done, _converse) { function (done, _converse) {
const jid = 'room@conference.example.org';
test_utils.waitUntilDiscoConfirmed( test_utils.waitUntilDiscoConfirmed(
_converse, _converse.bare_jid, _converse, _converse.bare_jid,
[{'category': 'pubsub', 'type': 'pep'}], [{'category': 'pubsub', 'type': 'pep'}],
...@@ -625,14 +621,12 @@ ...@@ -625,14 +621,12 @@
_converse.emit('bookmarksInitialized'); _converse.emit('bookmarksInitialized');
// Check that it's there // Check that it's there
var jid = 'room@conference.example.org';
_converse.bookmarks.create({ _converse.bookmarks.create({
'jid': jid, 'jid': jid,
'autojoin': false, 'autojoin': false,
'name': 'The Play', 'name': 'The Play',
'nick': ' Othello' 'nick': ' Othello'
}); });
expect(_converse.bookmarks.length).toBe(1); expect(_converse.bookmarks.length).toBe(1);
var room_els = _converse.bookmarksview.el.querySelectorAll(".open-room"); var room_els = _converse.bookmarksview.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1); expect(room_els.length).toBe(1);
...@@ -640,9 +634,11 @@ ...@@ -640,9 +634,11 @@
// Check that it disappears once the room is opened // Check that it disappears once the room is opened
var bookmark = _converse.bookmarksview.el.querySelector(".open-room"); var bookmark = _converse.bookmarksview.el.querySelector(".open-room");
bookmark.click(); bookmark.click();
return test_utils.waitUntil(() => _converse.chatboxviews.get(jid));
}).then(() => {
expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeTruthy(); expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeTruthy();
// Check that it reappears once the room is closed // Check that it reappears once the room is closed
var view = _converse.chatboxviews.get(jid); const view = _converse.chatboxviews.get(jid);
view.close(); view.close();
expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeFalsy(); expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeFalsy();
done(); done();
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
], factory); ], factory);
} (this, function ($, jasmine, mock, test_utils) { } (this, function ($, jasmine, mock, test_utils) {
"use strict"; "use strict";
var _ = converse.env._; const _ = converse.env._;
var $iq = converse.env.$iq; const $iq = converse.env.$iq;
var $msg = converse.env.$msg; const $msg = converse.env.$msg;
var Strophe = converse.env.Strophe; const Strophe = converse.env.Strophe;
var u = converse.env.utils; const u = converse.env.utils;
const sizzle = converse.env.sizzle;
return describe("Chatboxes", function () { return describe("Chatboxes", function () {
...@@ -158,45 +159,50 @@ ...@@ -158,45 +159,50 @@
})); }));
it("can be trimmed to conserve space", it("can be trimmed to conserve space",
mock.initConverseWithPromises( mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {}, function (done, _converse) {
null, ['rosterGroupsFetched'], {},
function (done, _converse) { spyOn(_converse.chatboxviews, 'trimChats');
const trimmed_chatboxes = _converse.minimized_chats;
spyOn(trimmed_chatboxes, 'addChat').and.callThrough();
spyOn(trimmed_chatboxes, 'removeChat').and.callThrough();
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var i, $el, jid, chatbox, chatboxview, trimmedview; let online_contacts;
var i, jid, chatbox, chatboxview, trimmedview;
// openControlBox was called earlier, so the controlbox is // openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created. // visible, but no other chat boxes have been created.
var trimmed_chatboxes = _converse.minimized_chats;
expect(_converse.chatboxes.length).toEqual(1); expect(_converse.chatboxes.length).toEqual(1);
spyOn(_converse.chatboxviews, 'trimChats'); expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(1); // Controlbox is open
spyOn(trimmed_chatboxes, 'addChat').and.callThrough();
spyOn(trimmed_chatboxes, 'removeChat').and.callThrough();
expect($("#conversejs .chatbox").length).toBe(1); // Controlbox is open
_converse.rosterview.update(); // XXX: Hack to make sure $roster element is attached. _converse.rosterview.update(); // XXX: Hack to make sure $roster element is attached.
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length)
return $(_converse.rosterview.el).find('.roster-group li').length; .then(() => {
}, 700).then(function () {
// Test that they can be maximized again // Test that they can be maximized again
var online_contacts = $(_converse.rosterview.el).find('.roster-group .current-xmpp-contact a.open-chat'); online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
expect(online_contacts.length).toBe(15); expect(online_contacts.length).toBe(15);
for (i=0; i<online_contacts.length; i++) { for (i=0; i<online_contacts.length; i++) {
$el = $(online_contacts[i]); const el = online_contacts[i];
jid = _.trim($el.text().trim()).replace(/ /g,'.').toLowerCase() + '@localhost'; el.click();
$el[0].click(); }
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled(); return test_utils.waitUntil(() => _converse.chatboxes.length == 16)
}).then(() => {
expect(_converse.chatboxviews.trimChats.calls.count()).toBe(16);
for (i=0; i<online_contacts.length; i++) {
const el = online_contacts[i];
jid = _.trim(el.textContent.trim()).replace(/ /g,'.').toLowerCase() + '@localhost';
chatboxview = _converse.chatboxviews.get(jid); chatboxview = _converse.chatboxviews.get(jid);
spyOn(chatboxview, 'minimize').and.callThrough(); spyOn(chatboxview, 'minimize').and.callThrough();
chatboxview.model.set({'minimized': true}); chatboxview.model.set({'minimized': true});
expect(trimmed_chatboxes.addChat).toHaveBeenCalled(); expect(trimmed_chatboxes.addChat).toHaveBeenCalled();
expect(chatboxview.minimize).toHaveBeenCalled(); expect(chatboxview.minimize).toHaveBeenCalled();
} }
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => _converse.chatboxviews.keys().length);
return _converse.chatboxviews.keys().length > 1;
}, 500);
}).then(function () { }).then(function () {
var key = _converse.chatboxviews.keys()[1]; var key = _converse.chatboxviews.keys()[1];
trimmedview = trimmed_chatboxes.get(key); trimmedview = trimmed_chatboxes.get(key);
...@@ -208,10 +214,9 @@ ...@@ -208,10 +214,9 @@
expect(trimmedview.restore).toHaveBeenCalled(); expect(trimmedview.restore).toHaveBeenCalled();
expect(chatbox.maximize).toHaveBeenCalled(); expect(chatbox.maximize).toHaveBeenCalled();
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled(); expect(_converse.chatboxviews.trimChats.calls.count()).toBe(17);
done(); done();
}); });
done();
})); }));
it("can be opened in minimized mode initially", it("can be opened in minimized mode initially",
...@@ -237,29 +242,26 @@ ...@@ -237,29 +242,26 @@
it("is focused if its already open and you click on its corresponding roster item", it("is focused if its already open and you click on its corresponding roster item",
mock.initConverseWithPromises( mock.initConverseWithPromises(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.rosterview.update(); // XXX: Hack to make sure $roster element is attaced. _converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
var $el, jid, chatbox; let el, jid;
// openControlBox was called earlier, so the controlbox is // openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created. // visible, but no other chat boxes have been created.
expect(_converse.chatboxes.length).toEqual(1); expect(_converse.chatboxes.length).toEqual(1);
chatbox = test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
$el = $(_converse.rosterview.el).find('a.open-chat:contains("'+chatbox.getDisplayName()+'")'); .then((view) => {
jid = $el.text().replace(/ /g,'.').toLowerCase() + '@localhost'; el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', _converse.rosterview.el).pop();
jid = el.textContent.replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
$el[0].click(); el.click();
test_utils.waitUntil(function () { return test_utils.waitUntil(() => _converse.emit.calls.count(), 500);
return _converse.emit.calls.count(); }).then(() => {
}, 300).then(function () {
expect(_converse.chatboxes.length).toEqual(2); expect(_converse.chatboxes.length).toEqual(2);
expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
done(); done();
...@@ -268,10 +270,11 @@ ...@@ -268,10 +270,11 @@
it("can be saved to, and retrieved from, browserStorage", it("can be saved to, and retrieved from, browserStorage",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched',], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
...@@ -279,10 +282,11 @@ ...@@ -279,10 +282,11 @@
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.openChatBoxes(_converse, 6); test_utils.openChatBoxes(_converse, 6);
return test_utils.waitUntil(() => _converse.chatboxes.length == 7).then(() => {
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled(); expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// We instantiate a new ChatBoxes collection, which by default // We instantiate a new ChatBoxes collection, which by default
// will be empty. // will be empty.
var newchatboxes = new _converse.ChatBoxes(); const newchatboxes = new _converse.ChatBoxes();
expect(newchatboxes.length).toEqual(0); expect(newchatboxes.length).toEqual(0);
// The chatboxes will then be fetched from browserStorage inside the // The chatboxes will then be fetched from browserStorage inside the
// onConnected method // onConnected method
...@@ -290,8 +294,8 @@ ...@@ -290,8 +294,8 @@
expect(newchatboxes.length).toEqual(7); expect(newchatboxes.length).toEqual(7);
// Check that the chatboxes items retrieved from browserStorage // Check that the chatboxes items retrieved from browserStorage
// have the same attributes values as the original ones. // have the same attributes values as the original ones.
var attrs = ['id', 'box_id', 'visible']; const attrs = ['id', 'box_id', 'visible'];
var new_attrs, old_attrs; let new_attrs, old_attrs;
for (var i=0; i<attrs.length; i++) { for (var i=0; i<attrs.length; i++) {
new_attrs = _.map(_.map(newchatboxes.models, 'attributes'), attrs[i]); new_attrs = _.map(_.map(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.map(_.map(_converse.chatboxes.models, 'attributes'), attrs[i]); old_attrs = _.map(_.map(_converse.chatboxes.models, 'attributes'), attrs[i]);
...@@ -299,21 +303,25 @@ ...@@ -299,21 +303,25 @@
} }
_converse.rosterview.render(); _converse.rosterview.render();
done(); done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
it("can be closed by clicking a DOM element with class 'close-chatbox-button'", it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group').length; const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 300).then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
var chatbox = test_utils.openChatBoxes(_converse, 1)[0], .then(() => test_utils.openChatBoxFor(_converse, contact_jid))
controlview = _converse.chatboxviews.get('controlbox'), // The controlbox is currently open .then(() => {
chatview = _converse.chatboxviews.get(chatbox.get('jid')); var controlview = _converse.chatboxviews.get('controlbox'), // The controlbox is currently open
chatview = _converse.chatboxviews.get(contact_jid);
spyOn(chatview, 'close').and.callThrough(); spyOn(chatview, 'close').and.callThrough();
spyOn(controlview, 'close').and.callThrough(); spyOn(controlview, 'close').and.callThrough();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
...@@ -338,20 +346,22 @@ ...@@ -338,20 +346,22 @@
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var chatview; let chatview;
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group').length; const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 300) test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
.then(function () { .then(() => test_utils.openChatBoxFor(_converse, contact_jid))
var chatbox = test_utils.openChatBoxes(_converse, 1)[0], .then(() => {
trimmed_chatboxes = _converse.minimized_chats, var trimmed_chatboxes = _converse.minimized_chats,
trimmedview; trimmedview;
chatview = _converse.chatboxviews.get(chatbox.get('jid')); chatview = _converse.chatboxviews.get(contact_jid);
spyOn(chatview, 'minimize').and.callThrough(); spyOn(chatview, 'minimize').and.callThrough();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
// We need to rebind all events otherwise our spy won't be called // We need to rebind all events otherwise our spy won't be called
...@@ -372,9 +382,7 @@ ...@@ -372,9 +382,7 @@
expect(trimmedview.restore).toHaveBeenCalled(); expect(trimmedview.restore).toHaveBeenCalled();
expect(_converse.emit).toHaveBeenCalledWith('chatBoxMaximized', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('chatBoxMaximized', jasmine.any(Object));
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => u.isVisible(chatview.el.querySelector('.chat-body')), 500);
return $(chatview.el).find('.chat-body').is(':visible');
}, 500);
}).then(function () { }).then(function () {
expect($(chatview.el).find('.toggle-chatbox-button').hasClass('fa-minus')).toBeTruthy(); expect($(chatview.el).find('.toggle-chatbox-button').hasClass('fa-minus')).toBeTruthy();
expect($(chatview.el).find('.toggle-chatbox-button').hasClass('fa-plus')).toBeFalsy(); expect($(chatview.el).find('.toggle-chatbox-button').hasClass('fa-plus')).toBeFalsy();
...@@ -385,14 +393,14 @@ ...@@ -385,14 +393,14 @@
it("will be removed from browserStorage when closed", it("will be removed from browserStorage when closed",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
return $(_converse.rosterview.el).find('.roster-group').length; .then(() => {
}, 300).then(function () {
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
spyOn(_converse.chatboxviews, 'trimChats'); spyOn(_converse.chatboxviews, 'trimChats');
_converse.chatboxes.browserStorage._clear(); _converse.chatboxes.browserStorage._clear();
...@@ -403,6 +411,8 @@ ...@@ -403,6 +411,8 @@
expect(_converse.chatboxes.length).toEqual(1); expect(_converse.chatboxes.length).toEqual(1);
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']); expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
test_utils.openChatBoxes(_converse, 6); test_utils.openChatBoxes(_converse, 6);
return test_utils.waitUntil(() => _converse.chatboxes.length == 7)
}).then(() => {
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled(); expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
expect(_converse.chatboxes.length).toEqual(7); expect(_converse.chatboxes.length).toEqual(7);
expect(_converse.emit).toHaveBeenCalledWith('chatBoxOpened', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('chatBoxOpened', jasmine.any(Object));
...@@ -428,14 +438,16 @@ ...@@ -428,14 +438,16 @@
it("can be found on each chat box", it("can be found on each chat box",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
var chatbox = _converse.chatboxes.get(contact_jid); var chatbox = _converse.chatboxes.get(contact_jid);
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
expect(chatbox).toBeDefined(); expect(chatbox).toBeDefined();
...@@ -444,20 +456,24 @@ ...@@ -444,20 +456,24 @@
expect(_.isElement(toolbar)).toBe(true); expect(_.isElement(toolbar)).toBe(true);
expect(toolbar.querySelectorAll(':scope > li').length).toBe(1); expect(toolbar.querySelectorAll(':scope > li').length).toBe(1);
done(); done();
});
})); }));
it("contains a button for inserting emojis", it("contains a button for inserting emojis",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; let timeout = false, view, toolbar;
test_utils.openChatBoxFor(_converse, contact_jid); const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
var view = _converse.chatboxviews.get(contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
var toolbar = view.el.querySelector('ul.chat-toolbar'); .then(() => {
view = _converse.chatboxviews.get(contact_jid);
toolbar = view.el.querySelector('ul.chat-toolbar');
expect(toolbar.querySelectorAll('li.toggle-smiley').length).toBe(1); expect(toolbar.querySelectorAll('li.toggle-smiley').length).toBe(1);
// Register spies // Register spies
spyOn(view, 'toggleEmojiMenu').and.callThrough(); spyOn(view, 'toggleEmojiMenu').and.callThrough();
...@@ -466,39 +482,26 @@ ...@@ -466,39 +482,26 @@
view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
toolbar.querySelector('li.toggle-smiley').click(); toolbar.querySelector('li.toggle-smiley').click();
var timeout = false; return test_utils.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'), 500));
}).then(() => {
test_utils.waitUntil(function () {
return u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'));
}, 500).then(function () {
var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container'); var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container');
var items = picker.querySelectorAll('.emoji-picker li'); var items = picker.querySelectorAll('.emoji-picker li');
items[0].click() items[0].click()
expect(view.insertEmoji).toHaveBeenCalled(); expect(view.insertEmoji).toHaveBeenCalled();
setTimeout(function () { timeout = true; }, 100); setTimeout(function () { timeout = true; }, 100);
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => timeout, 500);
return timeout; }).then(() => {
}, 500);
}).then(function () {
timeout = false; timeout = false;
toolbar.querySelector('li.toggle-smiley').click(); // Close the panel again toolbar.querySelector('li.toggle-smiley').click(); // Close the panel again
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => !view.el.querySelector('.toggle-smiley .toolbar-menu').offsetHeight, 500);
return !view.el.querySelector('.toggle-smiley .toolbar-menu').offsetHeight; }).then(() => {
}, 500);
}).then(function () {
setTimeout(function () { timeout = true; }, 100); setTimeout(function () { timeout = true; }, 100);
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => timeout, 500);
return timeout; }).then(() => {
}, 500);
}).then(function () {
toolbar.querySelector('li.toggle-smiley').click(); toolbar.querySelector('li.toggle-smiley').click();
expect(view.toggleEmojiMenu).toHaveBeenCalled(); expect(view.toggleEmojiMenu).toHaveBeenCalled();
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container')), 500);
var $picker = $(view.el).find('.toggle-smiley .emoji-picker-container'); }).then(() => {
return u.isVisible($picker[0]);
}, 500);
}).then(function () {
var nodes = view.el.querySelectorAll('.toggle-smiley ul li'); var nodes = view.el.querySelectorAll('.toggle-smiley ul li');
nodes[nodes.length-1].click(); nodes[nodes.length-1].click();
expect(view.el.querySelector('textarea.chat-textarea').value).toBe(':grinning: '); expect(view.el.querySelector('textarea.chat-textarea').value).toBe(':grinning: ');
...@@ -509,34 +512,38 @@ ...@@ -509,34 +512,38 @@
it("can contain a button for starting a call", it("can contain a button for starting a call",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var view; let view, toolbar, call_button;
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
// First check that the button doesn't show if it's not enabled // First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons" // via "visible_toolbar_buttons"
_converse.visible_toolbar_buttons.call = false; _converse.visible_toolbar_buttons.call = false;
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid); view = _converse.chatboxviews.get(contact_jid);
var toolbar = view.el.querySelector('ul.chat-toolbar'); toolbar = view.el.querySelector('ul.chat-toolbar');
var call_button = toolbar.querySelector('.toggle-call'); call_button = toolbar.querySelector('.toggle-call');
expect(_.isNull(call_button)).toBeTruthy(); expect(_.isNull(call_button)).toBeTruthy();
view.close(); view.close();
// Now check that it's shown if enabled and that it emits // Now check that it's shown if enabled and that it emits
// callButtonClicked // callButtonClicked
_converse.visible_toolbar_buttons.call = true; // enable the button _converse.visible_toolbar_buttons.call = true; // enable the button
test_utils.openChatBoxFor(_converse, contact_jid); return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
view = _converse.chatboxviews.get(contact_jid); view = _converse.chatboxviews.get(contact_jid);
toolbar = view.el.querySelector('ul.chat-toolbar'); toolbar = view.el.querySelector('ul.chat-toolbar');
call_button = toolbar.querySelector('.toggle-call'); call_button = toolbar.querySelector('.toggle-call');
call_button.click(); call_button.click();
expect(_converse.emit).toHaveBeenCalledWith('callButtonClicked', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('callButtonClicked', jasmine.any(Object));
done(); done();
});
})); }));
}); });
...@@ -568,17 +575,19 @@ ...@@ -568,17 +575,19 @@
it("is sent when the user opens a chat box", it("is sent when the user opens a chat box",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group').length; return $(_converse.rosterview.el).find('.roster-group').length;
}, 300).then(function () { }, 300).then(function () {
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; return test_utils.openChatBoxFor(_converse, contact_jid);
test_utils.openChatBoxFor(_converse, contact_jid); }).then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active'); expect(view.model.get('chat_state')).toBe('active');
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
...@@ -593,26 +602,24 @@ ...@@ -593,26 +602,24 @@
})); }));
it("is sent when the user maximizes a minimized a chat box", mock.initConverseWithPromises( it("is sent when the user maximizes a minimized a chat box", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
return $(_converse.rosterview.el).find('.roster-group').length; .then(() => test_utils.openChatBoxFor(_converse, contact_jid))
}, 500).then(function () { .then(() => {
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
view.model.minimize(); view.model.minimize();
expect(view.model.get('chat_state')).toBe('inactive'); expect(view.model.get('chat_state')).toBe('inactive');
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
view.model.maximize(); view.model.maximize();
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => view.model.get('chat_state') === 'active', 700);
return view.model.get('chat_state') === 'active'; }).then(() => {
}, 700);
}).then(function () {
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var calls = _.filter(_converse.connection.send.calls.all(), function (call) { var calls = _.filter(_converse.connection.send.calls.all(), function (call) {
return call.args[0] instanceof Strophe.Builder; return call.args[0] instanceof Strophe.Builder;
...@@ -633,16 +640,17 @@ ...@@ -633,16 +640,17 @@
it("is sent as soon as the user starts typing a message which is not a command", it("is sent as soon as the user starts typing a message which is not a command",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () { const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
return $(_converse.rosterview.el).find('.roster-group').length;
}, 300).then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, contact_jid))
test_utils.openChatBoxFor(_converse, contact_jid); .then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active'); expect(view.model.get('chat_state')).toBe('active');
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
...@@ -720,21 +728,20 @@ ...@@ -720,21 +728,20 @@
it("can be a composing carbon message that this user sent from a different client", it("can be a composing carbon message that this user sent from a different client",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var contact, sent_stanza, IQ_id, stanza; let contact, sent_stanza, IQ_id, stanza, recipient_jid;
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']) test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
.then(() => test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname')))
.then(function () { .then(function () {
return test_utils.waitUntil(function () {
return _converse.xmppstatus.vcard.get('fullname');
}, 300);
}).then(function () {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
// Send a message from a different resource // Send a message from a different resource
spyOn(_converse, 'log'); spyOn(_converse, 'log');
var recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost'; recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, recipient_jid); return test_utils.openChatBoxFor(_converse, recipient_jid);
}).then(() => {
var msg = $msg({ var msg = $msg({
'from': _converse.bare_jid, 'from': _converse.bare_jid,
'id': (new Date()).getTime(), 'id': (new Date()).getTime(),
...@@ -771,19 +778,19 @@ ...@@ -771,19 +778,19 @@
it("is sent if the user has stopped typing since 30 seconds", it("is sent if the user has stopped typing since 30 seconds",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var view, contact_jid; let view;
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700)
return $(_converse.rosterview.el).find('.roster-group li').length; .then(() => {
}, 700).then(function () {
_converse.TIMEOUTS.PAUSED = 200; // Make the timeout shorter so that we can test _converse.TIMEOUTS.PAUSED = 200; // Make the timeout shorter so that we can test
return test_utils.openChatBoxFor(_converse, contact_jid);
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; }).then(() => {
test_utils.openChatBoxFor(_converse, contact_jid);
view = _converse.chatboxviews.get(contact_jid); view = _converse.chatboxviews.get(contact_jid);
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
spyOn(view, 'setChatState').and.callThrough(); spyOn(view, 'setChatState').and.callThrough();
...@@ -796,10 +803,8 @@ ...@@ -796,10 +803,8 @@
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree()); var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
expect($stanza.children().get(0).tagName).toBe('composing'); expect($stanza.children().get(0).tagName).toBe('composing');
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => view.model.get('chat_state') === 'paused', 500);
return view.model.get('chat_state') === 'paused'; }).then(() => {
}, 500);
}).then(function () {
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var calls = _.filter(_converse.connection.send.calls.all(), function (call) { var calls = _.filter(_converse.connection.send.calls.all(), function (call) {
return call.args[0] instanceof Strophe.Builder; return call.args[0] instanceof Strophe.Builder;
...@@ -828,7 +833,7 @@ ...@@ -828,7 +833,7 @@
}); });
expect(view.model.get('chat_state')).toBe('composing'); expect(view.model.get('chat_state')).toBe('composing');
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
})); }));
it("will be shown if received", it("will be shown if received",
...@@ -868,21 +873,20 @@ ...@@ -868,21 +873,20 @@
it("can be a paused carbon message that this user sent from a different client", it("can be a paused carbon message that this user sent from a different client",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var contact, sent_stanza, IQ_id, stanza; let contact, sent_stanza, IQ_id, stanza, recipient_jid;
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']) test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
.then(function () { .then(() => test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname')))
return test_utils.waitUntil(function () { .then(() => {
return _converse.xmppstatus.vcard.get('fullname');
}, 300);
}).then(function () {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
// Send a message from a different resource // Send a message from a different resource
spyOn(_converse, 'log'); spyOn(_converse, 'log');
var recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost'; recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, recipient_jid); return test_utils.openChatBoxFor(_converse, recipient_jid);
}).then(() => {
var msg = $msg({ var msg = $msg({
'from': _converse.bare_jid, 'from': _converse.bare_jid,
'id': (new Date()).getTime(), 'id': (new Date()).getTime(),
...@@ -979,14 +983,16 @@ ...@@ -979,14 +983,16 @@
it("is sent when the user a minimizes a chat box", it("is sent when the user a minimizes a chat box",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
view.minimize(); view.minimize();
...@@ -996,21 +1002,21 @@ ...@@ -996,21 +1002,21 @@
expect($stanza.attr('to')).toBe(contact_jid); expect($stanza.attr('to')).toBe(contact_jid);
expect($stanza.children().get(0).tagName).toBe('inactive'); expect($stanza.children().get(0).tagName).toBe('inactive');
done(); done();
});
})); }));
it("is sent if the user closes a chat box", it("is sent if the user closes a chat box",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
return $(_converse.rosterview.el).find('.roster-group').length; .then(() => test_utils.openChatBoxFor(_converse, contact_jid))
}, 300).then(function () { .then((view) => {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active'); expect(view.model.get('chat_state')).toBe('active');
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
view.close(); view.close();
...@@ -1028,16 +1034,18 @@ ...@@ -1028,16 +1034,18 @@
it("will clear any other chat status notifications", it("will clear any other chat status notifications",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var view = _converse.chatboxviews.get(sender_jid); var view = _converse.chatboxviews.get(sender_jid);
expect(view.el.querySelectorAll('.chat-event').length).toBe(0); expect(view.el.querySelectorAll('.chat-event').length).toBe(0);
// Insert <composing> message, to also check that // Insert <composing> message, to also check that
...@@ -1062,6 +1070,7 @@ ...@@ -1062,6 +1070,7 @@
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
expect($(view.el).find('.chat-state-notification').length).toBe(0); expect($(view.el).find('.chat-state-notification').length).toBe(0);
done(); done();
});
})); }));
}); });
...@@ -1103,15 +1112,17 @@ ...@@ -1103,15 +1112,17 @@
it("'/clear' can be used to clear messages in a conversation", it("'/clear' can be used to clear messages in a conversation",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; test_utils.openChatBoxFor(_converse, contact_jid)
test_utils.openChatBoxFor(_converse, contact_jid); .then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
var message = 'This message is another sent from this chatbox'; var message = 'This message is another sent from this chatbox';
// Lets make sure there is at least one message already // Lets make sure there is at least one message already
...@@ -1136,6 +1147,7 @@ ...@@ -1136,6 +1147,7 @@
expect(_converse.emit.calls.count(), 1); expect(_converse.emit.calls.count(), 1);
expect(_converse.emit.calls.mostRecent().args, ['messageSend', message]); expect(_converse.emit.calls.mostRecent().args, ['messageSend', message]);
done(); done();
});
})); }));
}); });
...@@ -1267,133 +1279,133 @@ ...@@ -1267,133 +1279,133 @@
it("is incremented when the message is received and ChatBoxView is scrolled up", it("is incremented when the message is received and ChatBoxView is scrolled up",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost', const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
test_utils.openChatBoxFor(_converse, sender_jid); test_utils.openChatBoxFor(_converse, sender_jid)
var chatbox = _converse.chatboxes.get(sender_jid); .then((view) => {
chatbox.save('scrolled', true); view.model.save('scrolled', true);
_converse.chatboxes.onMessage(msg); _converse.chatboxes.onMessage(msg);
expect(chatbox.get('num_unread')).toBe(1); expect(view.model.get('num_unread')).toBe(1);
done(); done();
});
})); }));
it("is not incremented when the message is received and ChatBoxView is scrolled down", it("is not incremented when the message is received and ChatBoxView is scrolled down",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost', const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be read'); msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be read');
test_utils.openChatBoxFor(_converse, sender_jid); test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
_converse.chatboxes.onMessage(msg); _converse.chatboxes.onMessage(msg);
expect(chatbox.get('num_unread')).toBe(0); expect(chatbox.get('num_unread')).toBe(0);
done(); done();
});
})); }));
it("is incremeted when message is received, chatbox is scrolled down and the window is not focused", it("is incremeted when message is received, chatbox is scrolled down and the window is not focused",
mock.initConverseWithPromises( mock.initConverseWithPromises(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () { var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
}; };
test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden'; _converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
expect(chatbox.get('num_unread')).toBe(1); expect(chatbox.get('num_unread')).toBe(1);
done(); done();
});
})); }));
it("is incremeted when message is received, chatbox is scrolled up and the window is not focused", it("is incremeted when message is received, chatbox is scrolled up and the window is not focused",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () { var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
}; };
test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true); chatbox.save('scrolled', true);
_converse.windowState = 'hidden'; _converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
expect(chatbox.get('num_unread')).toBe(1); expect(chatbox.get('num_unread')).toBe(1);
done(); done();
});
})); }));
it("is cleared when ChatBoxView was scrolled down and the window become focused", it("is cleared when ChatBoxView was scrolled down and the window become focused",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () { var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
}; };
test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); const chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden'; _converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
expect(chatbox.get('num_unread')).toBe(1); expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus'); _converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(0); expect(chatbox.get('num_unread')).toBe(0);
done(); done();
});
})); }));
it("is not cleared when ChatBoxView was scrolled up and the windows become focused", it("is not cleared when ChatBoxView was scrolled up and the windows become focused",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () { var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
}; };
test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true); chatbox.save('scrolled', true);
_converse.windowState = 'hidden'; _converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
expect(chatbox.get('num_unread')).toBe(1); expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus'); _converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(1); expect(chatbox.get('num_unread')).toBe(1);
done(); done();
});
})); }));
}); });
...@@ -1401,16 +1413,16 @@ ...@@ -1401,16 +1413,16 @@
it("is updated when message is received and chatbox is scrolled up", it("is updated when message is received and chatbox is scrolled up",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return $(_converse.rosterview.el).find('.roster-group').length;
}, 500) const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
.then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, sender_jid))
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true); chatbox.save('scrolled', true);
...@@ -1433,16 +1445,16 @@ ...@@ -1433,16 +1445,16 @@
it("is updated when message is received and chatbox is minimized", it("is updated when message is received and chatbox is minimized",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return $(_converse.rosterview.el).find('.roster-group').length; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 500)
.then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, sender_jid))
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid); var chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize(); chatboxview.minimize();
...@@ -1466,16 +1478,16 @@ ...@@ -1466,16 +1478,16 @@
it("is cleared when chatbox is maximzied after receiving messages in minimized mode", it("is cleared when chatbox is maximzied after receiving messages in minimized mode",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return $(_converse.rosterview.el).find('.roster-group').length; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 500)
.then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, sender_jid))
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid); var chatboxview = _converse.chatboxviews.get(sender_jid);
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator'; var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
...@@ -1483,7 +1495,6 @@ ...@@ -1483,7 +1495,6 @@
var msgFactory = function () { var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
}; };
chatboxview.minimize(); chatboxview.minimize();
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
...@@ -1500,16 +1511,16 @@ ...@@ -1500,16 +1511,16 @@
it("is cleared when unread messages are viewed which were received in scrolled-up chatbox", it("is cleared when unread messages are viewed which were received in scrolled-up chatbox",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return $(_converse.rosterview.el).find('.roster-group').length; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 500)
.then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, sender_jid))
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid); var chatboxview = _converse.chatboxviews.get(sender_jid);
var msgFactory = function () { var msgFactory = function () {
...@@ -1532,16 +1543,16 @@ ...@@ -1532,16 +1543,16 @@
it("is not cleared after user clicks on roster view when chatbox is already opened and scrolled up", it("is not cleared after user clicks on roster view when chatbox is already opened and scrolled up",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return $(_converse.rosterview.el).find('.roster-group').length; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
}, 500)
.then(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.openChatBoxFor(_converse, sender_jid))
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var chatbox = _converse.chatboxes.get(sender_jid); var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid); var chatboxview = _converse.chatboxviews.get(sender_jid);
var msgFactory = function () { var msgFactory = function () {
...@@ -1566,79 +1577,90 @@ ...@@ -1566,79 +1577,90 @@
it("is displayed when scrolled up chatbox is minimized after receiving unread messages", it("is displayed when scrolled up chatbox is minimized after receiving unread messages",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var msgFactory = function () { const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
}; };
var selectUnreadMsgCount = function () { const selectUnreadMsgCount = function () {
var minimizedChatBoxView = _converse.minimized_chats.get(sender_jid); const minimizedChatBoxView = _converse.minimized_chats.get(sender_jid);
return $(minimizedChatBoxView.el).find('.message-count'); return $(minimizedChatBoxView.el).find('.message-count');
}; };
var chatbox = _converse.chatboxes.get(sender_jid); const chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true); chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
var chatboxview = _converse.chatboxviews.get(sender_jid); const chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize(); chatboxview.minimize();
var $unreadMsgCount = selectUnreadMsgCount(); const $unreadMsgCount = selectUnreadMsgCount();
expect(u.isVisible($unreadMsgCount[0])).toBeTruthy(); expect(u.isVisible($unreadMsgCount[0])).toBeTruthy();
expect($unreadMsgCount.html()).toBe('1'); expect($unreadMsgCount.html()).toBe('1');
done(); done();
});
})); }));
it("is incremented when message is received and windows is not focused", it("is incremented when message is received and windows is not focused",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; test_utils.openChatBoxFor(_converse, sender_jid)
test_utils.openChatBoxFor(_converse, sender_jid); .then(() => {
var msgFactory = function () { const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); return test_utils.createChatMessage(_converse, sender_jid,
'This message will be received as unread, but eventually will be read');
}; };
var selectUnreadMsgCount = function () { const selectUnreadMsgCount = function () {
var minimizedChatBoxView = _converse.minimized_chats.get(sender_jid); const minimizedChatBoxView = _converse.minimized_chats.get(sender_jid);
return $(minimizedChatBoxView.el).find('.message-count'); return $(minimizedChatBoxView.el).find('.message-count');
}; };
var chatboxview = _converse.chatboxviews.get(sender_jid); const chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize(); chatboxview.minimize();
_converse.chatboxes.onMessage(msgFactory()); _converse.chatboxes.onMessage(msgFactory());
var $unreadMsgCount = selectUnreadMsgCount(); const $unreadMsgCount = selectUnreadMsgCount();
expect(u.isVisible($unreadMsgCount[0])).toBeTruthy(); expect(u.isVisible($unreadMsgCount[0])).toBeTruthy();
expect($unreadMsgCount.html()).toBe('1'); expect($unreadMsgCount.html()).toBe('1');
done(); done();
});
})); }));
it("will render Openstreetmap-URL from geo-URI", it("will render Openstreetmap-URL from geo-URI",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var base_url = document.URL.split(window.location.pathname)[0]; _converse.emit('rosterContactsFetched');
var message = "geo:37.786971,-122.399677";
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; let view;
test_utils.openChatBoxFor(_converse, contact_jid); const base_url = document.URL.split(window.location.pathname)[0],
var view = _converse.chatboxviews.get(contact_jid); message = "geo:37.786971,-122.399677",
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
test_utils.waitUntil(function () { return test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg').length, 1000);
return $(view.el).find('.chat-content').find('.chat-msg').length; }).then(() => {
}, 1000).then(function () {
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text'); var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text');
expect(msg.html()).toEqual( expect(msg.html()).toEqual(
......
(function (root, factory) { (function (root, factory) {
define(["jquery", "jasmine", "mock", "test-utils" ], factory); define(["jquery", "jasmine", "mock", "test-utils" ], factory);
} (this, function ($, jasmine, mock, test_utils) { } (this, function ($, jasmine, mock, test_utils) {
var _ = converse.env._; const _ = converse.env._,
var $pres = converse.env.$pres; $pres = converse.env.$pres,
var $iq = converse.env.$iq; $iq = converse.env.$iq,
var $msg = converse.env.$msg; $msg = converse.env.$msg,
var Strophe = converse.env.Strophe; Strophe = converse.env.Strophe,
var Promise = converse.env.Promise; Promise = converse.env.Promise,
var moment = converse.env.moment; moment = converse.env.moment,
var sizzle = converse.env.sizzle; sizzle = converse.env.sizzle,
var u = converse.env.utils; Backbone = converse.env.Backbone,
u = converse.env.utils;
return describe("ChatRooms", function () { return describe("ChatRooms", function () {
describe("The \"rooms\" API", function () { describe("The \"rooms\" API", function () {
...@@ -107,7 +108,7 @@ ...@@ -107,7 +108,7 @@
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box", it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
// Mock 'getRoomFeatures', otherwise the room won't be // Mock 'getRoomFeatures', otherwise the room won't be
...@@ -119,22 +120,24 @@ ...@@ -119,22 +120,24 @@
return deferred.promise(); return deferred.promise();
}); });
const sent_IQ_els = [];
let jid = 'lounge@localhost';
let chatroomview, sent_IQ, IQ_id;
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
test_utils.waitUntil(function () { test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length)
return $(_converse.rosterview.el).find('.roster-group .group-toggle').length; .then(() => _converse.api.rooms.open(jid))
}, 300).then(function () { .then((room) => {
var jid = 'lounge@localhost';
var room = _converse.api.rooms.open(jid);
// Test on groupchat that's not yet open // Test on groupchat that's not yet open
expect(room instanceof Object).toBeTruthy(); expect(room instanceof Backbone.Model).toBeTruthy();
var chatroomview = _converse.chatboxviews.get(jid); chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.is_chatroom).toBeTruthy(); expect(chatroomview.is_chatroom).toBeTruthy();
expect(u.isVisible(chatroomview.el)).toBeTruthy(); expect(u.isVisible(chatroomview.el)).toBeTruthy();
// Test again, now that the room exists. // Test again, now that the room exists.
room = _converse.api.rooms.open(jid); return _converse.api.rooms.open(jid);
expect(room instanceof Object).toBeTruthy(); }).then((room) => {
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid); chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.is_chatroom).toBeTruthy(); expect(chatroomview.is_chatroom).toBeTruthy();
expect(u.isVisible(chatroomview.el)).toBeTruthy(); expect(u.isVisible(chatroomview.el)).toBeTruthy();
...@@ -142,26 +145,28 @@ ...@@ -142,26 +145,28 @@
// Test with mixed case in JID // Test with mixed case in JID
jid = 'Leisure@localhost'; jid = 'Leisure@localhost';
room = _converse.api.rooms.open(jid); return _converse.api.rooms.open(jid);
expect(room instanceof Object).toBeTruthy(); }).then((room) => {
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase()); chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
expect(u.isVisible(chatroomview.el)).toBeTruthy(); expect(u.isVisible(chatroomview.el)).toBeTruthy();
jid = 'leisure@localhost'; jid = 'leisure@localhost';
room = _converse.api.rooms.open(jid); return _converse.api.rooms.open(jid);
expect(room instanceof Object).toBeTruthy(); }).then((room) => {
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase()); chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
expect(u.isVisible(chatroomview.el)).toBeTruthy(); expect(u.isVisible(chatroomview.el)).toBeTruthy();
jid = 'leiSure@localhost'; jid = 'leiSure@localhost';
room = _converse.api.rooms.open(jid); return _converse.api.rooms.open(jid);
expect(room instanceof Object).toBeTruthy(); }).then((room) => {
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase()); chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
expect(u.isVisible(chatroomview.el)).toBeTruthy(); expect(u.isVisible(chatroomview.el)).toBeTruthy();
chatroomview.close(); chatroomview.close();
_converse.muc_instant_rooms = false; _converse.muc_instant_rooms = false;
var sent_IQ, IQ_id, sent_IQ_els = [];
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQ = iq; sent_IQ = iq;
...@@ -169,7 +174,7 @@ ...@@ -169,7 +174,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
// Test with configuration // Test with configuration
_converse.api.rooms.open('room@conference.example.org', { return _converse.api.rooms.open('room@conference.example.org', {
'nick': 'some1', 'nick': 'some1',
'auto_configure': true, 'auto_configure': true,
'roomconfig': { 'roomconfig': {
...@@ -181,6 +186,7 @@ ...@@ -181,6 +186,7 @@
'whois': 'anyone' 'whois': 'anyone'
} }
}); });
}).then((room) => {
chatroomview = _converse.chatboxviews.get('room@conference.example.org'); chatroomview = _converse.chatboxviews.get('room@conference.example.org');
// 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.
...@@ -252,11 +258,8 @@ ...@@ -252,11 +258,8 @@
spyOn(chatroomview.model, 'sendConfiguration').and.callThrough(); spyOn(chatroomview.model, 'sendConfiguration').and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(node.firstElementChild)); _converse.connection._dataRecv(test_utils.createRequest(node.firstElementChild));
return test_utils.waitUntil(() => chatroomview.model.sendConfiguration.calls.count() === 1);
}).then(() => {
return test_utils.waitUntil(function () {
return chatroomview.model.sendConfiguration.calls.count() === 1;
}, 300).then(function () {
var sent_stanza = sent_IQ_els.pop(); var sent_stanza = sent_IQ_els.pop();
while (sent_stanza.getAttribute('type') !== 'set') { while (sent_stanza.getAttribute('type') !== 'set') {
sent_stanza = sent_IQ_els.pop(); sent_stanza = sent_IQ_els.pop();
...@@ -271,7 +274,6 @@ ...@@ -271,7 +274,6 @@
expect(sizzle('field[var="muc#roomconfig_historylength"] value', sent_stanza).pop().textContent).toBe('20'); expect(sizzle('field[var="muc#roomconfig_historylength"] value', sent_stanza).pop().textContent).toBe('20');
done(); done();
}); });
});
})); }));
}); });
...@@ -279,12 +281,12 @@ ...@@ -279,12 +281,12 @@
it("will be created when muc_instant_rooms is set to true", it("will be created when muc_instant_rooms is set to true",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var IQ_stanzas = _converse.connection.IQ_stanzas; const IQ_stanzas = _converse.connection.IQ_stanzas;
var sent_IQ, IQ_id; const sendIQ = _converse.connection.sendIQ;
var sendIQ = _converse.connection.sendIQ; let sent_IQ, IQ_id, view;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
if (iq.nodeTree.getAttribute('to') === 'lounge@localhost') { if (iq.nodeTree.getAttribute('to') === 'lounge@localhost') {
sent_IQ = iq; sent_IQ = iq;
...@@ -293,8 +295,8 @@ ...@@ -293,8 +295,8 @@
sendIQ.bind(this)(iq, callback, errback); sendIQ.bind(this)(iq, callback, errback);
} }
}); });
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
.then(() => {
// 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.
// //
/* <iq from="jordie.langen@chat.example.org/converse.js-11659299" to="myroom@conference.chat.example.org" type="get"> /* <iq from="jordie.langen@chat.example.org/converse.js-11659299" to="myroom@conference.chat.example.org" type="get">
...@@ -315,7 +317,7 @@ ...@@ -315,7 +317,7 @@
.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(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
var view = _converse.chatboxviews.get('lounge@localhost'); view = _converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'join').and.callThrough(); spyOn(view, 'join').and.callThrough();
spyOn(view, 'submitNickname').and.callThrough(); spyOn(view, 'submitNickname').and.callThrough();
...@@ -326,11 +328,8 @@ ...@@ -326,11 +328,8 @@
* node="x-roomuser-item"/> * node="x-roomuser-item"/>
* </iq> * </iq>
*/ */
test_utils.waitUntil(function () { return test_utils.waitUntil(() => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('query[node="x-roomuser-item"]')).length);
return _.filter(IQ_stanzas, function (iq) { }).then(() => {
return iq.nodeTree.querySelector('query[node="x-roomuser-item"]');
}).length > 0;
}, 300).then(function () {
const iq = _.filter(IQ_stanzas, function (iq) { const iq = _.filter(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector(`query[node="x-roomuser-item"]`); return iq.nodeTree.querySelector(`query[node="x-roomuser-item"]`);
}).pop(); }).pop();
...@@ -411,10 +410,11 @@ ...@@ -411,10 +410,11 @@
it("shows join/leave messages when users enter or exit a groupchat", it("shows join/leave messages when users enter or exit a groupchat",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1'); test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1')
.then(() => {
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var $chat_content = $(view.el).find('.chat-content'); var $chat_content = $(view.el).find('.chat-content');
...@@ -604,6 +604,7 @@ ...@@ -604,6 +604,7 @@
expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(5); expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(5);
expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat"); expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat");
done(); done();
});
})); }));
it("shows a new day indicator if a join/leave message is received on a new day", it("shows a new day indicator if a join/leave message is received on a new day",
...@@ -774,19 +775,19 @@ ...@@ -774,19 +775,19 @@
it("shows its description in the chat heading", it("shows its description in the chat heading",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var sent_IQ, IQ_id; let sent_IQ, IQ_id, view;
var sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQ = iq; sent_IQ = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'})
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); .then(() => {
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var features_stanza = $iq({ const features_stanza = $iq({
from: 'coven@chat.shakespeare.lit', from: 'coven@chat.shakespeare.lit',
'id': IQ_id, 'id': IQ_id,
'to': 'dummy@localhost/desktop', 'to': 'dummy@localhost/desktop',
...@@ -814,9 +815,9 @@ ...@@ -814,9 +815,9 @@
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of participants'}) .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of participants'})
.c('value').t(0); .c('value').t(0);
_converse.connection._dataRecv(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
test_utils.waitUntil(() => _.get(view.el.querySelector('.chatroom-description'), 'textContent')) return test_utils.waitUntil(() => _.get(view.el.querySelector('.chatroom-description'), 'textContent'))
.then(function () { }).then(function () {
expect($(view.el.querySelector('.chatroom-description')).text()).toBe('This is the description'); expect(view.el.querySelector('.chatroom-description').textContent).toBe('This is the description');
done(); done();
}); });
})); }));
...@@ -886,7 +887,7 @@ ...@@ -886,7 +887,7 @@
it("can be configured if you're its owner", it("can be configured if you're its owner",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var view; var view;
...@@ -897,7 +898,8 @@ ...@@ -897,7 +898,8 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'})
.then(() => {
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
spyOn(view.model, 'saveAffiliationAndRole').and.callThrough(); spyOn(view.model, 'saveAffiliationAndRole').and.callThrough();
...@@ -933,12 +935,9 @@ ...@@ -933,12 +935,9 @@
_converse.connection._dataRecv(test_utils.createRequest(presence)); _converse.connection._dataRecv(test_utils.createRequest(presence));
expect(view.model.saveAffiliationAndRole).toHaveBeenCalled(); expect(view.model.saveAffiliationAndRole).toHaveBeenCalled();
expect($(view.el.querySelector('.toggle-chatbox-button')).is(':visible')).toBeTruthy(); expect($(view.el.querySelector('.toggle-chatbox-button')).is(':visible')).toBeTruthy();
return test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.configure-chatroom-button')))
test_utils.waitUntil(function () { }).then(() => {
return !_.isNull(view.el.querySelector('.configure-chatroom-button'));
}, 300).then(function () {
expect($(view.el.querySelector('.configure-chatroom-button')).is(':visible')).toBeTruthy(); expect($(view.el.querySelector('.configure-chatroom-button')).is(':visible')).toBeTruthy();
view.el.querySelector('.configure-chatroom-button').click(); view.el.querySelector('.configure-chatroom-button').click();
/* Check that an IQ is sent out, asking for the /* Check that an IQ is sent out, asking for the
...@@ -1074,9 +1073,8 @@ ...@@ -1074,9 +1073,8 @@
.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 test_utils.waitUntil(() => view.el.querySelectorAll('form.chatroom-form').length)
return $(view.el.querySelector('form.chatroom-form')).length; }).then(() => {
}, 300).then(function () {
expect($(view.el.querySelector('form.chatroom-form')).length).toBe(1); expect($(view.el.querySelector('form.chatroom-form')).length).toBe(1);
expect(view.el.querySelectorAll('form.chatroom-form fieldset').length).toBe(2); expect(view.el.querySelectorAll('form.chatroom-form fieldset').length).toBe(2);
var $membersonly = $(view.el.querySelector('input[name="muc#roomconfig_membersonly"]')); var $membersonly = $(view.el.querySelector('input[name="muc#roomconfig_membersonly"]'));
...@@ -1109,7 +1107,6 @@ ...@@ -1109,7 +1107,6 @@
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();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
...@@ -1318,12 +1315,12 @@ ...@@ -1318,12 +1315,12 @@
it("will use the user's reserved nickname, if it exists", it("will use the user's reserved nickname, if it exists",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var IQ_stanzas = _converse.connection.IQ_stanzas; let sent_IQ, IQ_id, view;
var sent_IQ, IQ_id; const IQ_stanzas = _converse.connection.IQ_stanzas;
var sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
if (iq.nodeTree.getAttribute('to') === 'lounge@localhost') { if (iq.nodeTree.getAttribute('to') === 'lounge@localhost') {
sent_IQ = iq; sent_IQ = iq;
...@@ -1333,8 +1330,8 @@ ...@@ -1333,8 +1330,8 @@
} }
}); });
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
.then(() => {
// 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 features_stanza = $iq({ var features_stanza = $iq({
from: 'lounge@localhost', from: 'lounge@localhost',
...@@ -1345,7 +1342,7 @@ ...@@ -1345,7 +1342,7 @@
.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(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
var view = _converse.chatboxviews.get('lounge@localhost'); view = _converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'join').and.callThrough(); spyOn(view, 'join').and.callThrough();
/* <iq from='hag66@shakespeare.lit/pda' /* <iq from='hag66@shakespeare.lit/pda'
...@@ -1356,12 +1353,8 @@ ...@@ -1356,12 +1353,8 @@
* node='x-roomuser-item'/> * node='x-roomuser-item'/>
* </iq> * </iq>
*/ */
return test_utils.waitUntil(() => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('query[node="x-roomuser-item"]')).length)
test_utils.waitUntil(function () { }).then(() => {
return _.filter(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector('query[node="x-roomuser-item"]');
}).length > 0;
}, 300).then(function () {
const iq = _.filter(IQ_stanzas, function (iq) { const iq = _.filter(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector(`query[node="x-roomuser-item"]`); return iq.nodeTree.querySelector(`query[node="x-roomuser-item"]`);
}).pop(); }).pop();
...@@ -1421,20 +1414,23 @@ ...@@ -1421,20 +1414,23 @@
it("allows the user to invite their roster contacts to enter the groupchat", it("allows the user to invite their roster contacts to enter the groupchat",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
test_utils.createContacts(_converse, 'current'); // We need roster contacts, so that we have someone to invite test_utils.createContacts(_converse, 'current'); // We need roster contacts, so that we have someone to invite
// Since we don't actually fetch roster contacts, we need to // Since we don't actually fetch roster contacts, we need to
// cheat here and emit the event. // cheat here and emit the event.
_converse.emit('rosterContactsFetched'); _converse.emit('rosterContactsFetched');
let view;
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
.then(() => {
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
spyOn(window, 'prompt').and.callFake(function () { spyOn(window, 'prompt').and.callFake(function () {
return "Please join!"; return "Please join!";
}); });
var view = _converse.chatboxviews.get('lounge@localhost'); view = _converse.chatboxviews.get('lounge@localhost');
// XXX: cheating a lttle bit, normally this'll be set after // XXX: cheating a lttle bit, normally this'll be set after
// receiving the features for the groupchat. // receiving the features for the groupchat.
...@@ -1444,9 +1440,8 @@ ...@@ -1444,9 +1440,8 @@
var $input; var $input;
$(view.el).find('.chat-area').remove(); $(view.el).find('.chat-area').remove();
test_utils.waitUntil(function () { return test_utils.waitUntil(() => view.el.querySelectorAll('input.invited-contact').length)
return $(view.el).find('input.invited-contact').length; }).then(function () {
}, 300).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");
...@@ -1782,7 +1777,7 @@ ...@@ -1782,7 +1777,7 @@
it("queries for the groupchat information before attempting to join the user", it("queries for the groupchat information before attempting to join the user",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var sent_IQ, IQ_id; var sent_IQ, IQ_id;
...@@ -1792,15 +1787,16 @@ ...@@ -1792,15 +1787,16 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); let view;
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'})
.then(() => {
// Check that the groupchat queried for the feautures. // Check that the groupchat queried for the feautures.
expect(sent_IQ.toLocaleString()).toBe( expect(sent_IQ.toLocaleString()).toBe(
"<iq from='dummy@localhost/resource' to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+ "<iq from='dummy@localhost/resource' to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/disco#info'/>"+ "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
"</iq>"); "</iq>");
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
spyOn(view.model, 'parseRoomFeatures').and.callThrough(); spyOn(view.model, 'parseRoomFeatures').and.callThrough();
/* <iq from='coven@chat.shakespeare.lit' /* <iq from='coven@chat.shakespeare.lit'
* id='ik3vs715' * id='ik3vs715'
...@@ -1821,7 +1817,7 @@ ...@@ -1821,7 +1817,7 @@
* </query> * </query>
* </iq> * </iq>
*/ */
var features_stanza = $iq({ const features_stanza = $iq({
from: 'coven@chat.shakespeare.lit', from: 'coven@chat.shakespeare.lit',
'id': IQ_id, 'id': IQ_id,
'to': 'dummy@localhost/desktop', 'to': 'dummy@localhost/desktop',
...@@ -1841,8 +1837,8 @@ ...@@ -1841,8 +1837,8 @@
.c('feature', {'var': 'muc_unmoderated'}).up() .c('feature', {'var': 'muc_unmoderated'}).up()
.c('feature', {'var': 'muc_nonanonymous'}); .c('feature', {'var': 'muc_nonanonymous'});
_converse.connection._dataRecv(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300) return test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300)
.then(() => { }).then(() => {
expect(view.model.get('features_fetched')).toBeTruthy(); expect(view.model.get('features_fetched')).toBeTruthy();
expect(view.model.get('passwordprotected')).toBe(true); expect(view.model.get('passwordprotected')).toBe(true);
expect(view.model.get('hidden')).toBe(true); expect(view.model.get('hidden')).toBe(true);
...@@ -2014,10 +2010,11 @@ ...@@ -2014,10 +2010,11 @@
it("can be saved to, and retrieved from, browserStorage", it("can be saved to, and retrieved from, browserStorage",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
.then(() => {
// We instantiate a new ChatBoxes collection, which by default // We instantiate a new ChatBoxes collection, which by default
// will be empty. // will be empty.
test_utils.openControlBox(); test_utils.openControlBox();
...@@ -2042,15 +2039,17 @@ ...@@ -2042,15 +2039,17 @@
} }
_converse.rosterview.render(); _converse.rosterview.render();
done(); done();
});
})); }));
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
var view = _converse.chatboxviews.get('lounge@localhost'), .then(() => {
const view = _converse.chatboxviews.get('lounge@localhost'),
trimmed_chatboxes = _converse.minimized_chats; trimmed_chatboxes = _converse.minimized_chats;
spyOn(view, 'minimize').and.callThrough(); spyOn(view, 'minimize').and.callThrough();
...@@ -2071,15 +2070,18 @@ ...@@ -2071,15 +2070,18 @@
expect(view.model.get('minimized')).toBeFalsy(); expect(view.model.get('minimized')).toBeFalsy();
expect(_converse.emit.calls.count(), 3); expect(_converse.emit.calls.count(), 3);
done(); done();
});
})); }));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy')
var view = _converse.chatboxviews.get('lounge@localhost'); .then(() => {
const view = _converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'close').and.callThrough(); spyOn(view, 'close').and.callThrough();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
spyOn(view.model, 'leave'); spyOn(view.model, 'leave');
...@@ -2089,6 +2091,7 @@ ...@@ -2089,6 +2091,7 @@
expect(view.model.leave).toHaveBeenCalled(); expect(view.model.leave).toHaveBeenCalled();
expect(_converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
done(); done();
});
})); }));
}); });
...@@ -2953,20 +2956,20 @@ ...@@ -2953,20 +2956,20 @@
it("will first be added to the member list if the groupchat is members only", it("will first be added to the member list if the groupchat is members only",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var sent_IQs = [], IQ_ids = []; var sent_IQs = [], IQ_ids = [];
var invitee_jid, sent_stanza, sent_id; let invitee_jid, sent_stanza, sent_id, view;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQs.push(iq); sent_IQs.push(iq);
IQ_ids.push(sendIQ.bind(this)(iq, callback, errback)); IQ_ids.push(sendIQ.bind(this)(iq, callback, errback));
}); });
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'dummy'}); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'dummy'})
.then(() => {
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
spyOn(view.model, 'parseRoomFeatures').and.callThrough(); spyOn(view.model, 'parseRoomFeatures').and.callThrough();
// State that the chat is members-only via the features IQ // State that the chat is members-only via the features IQ
...@@ -2988,8 +2991,8 @@ ...@@ -2988,8 +2991,8 @@
.c('feature', {'var': 'muc_membersonly'}).up(); .c('feature', {'var': 'muc_membersonly'}).up();
_converse.connection._dataRecv(test_utils.createRequest(features_stanza)); _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300) return test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300);
.then(() => { }).then(() => {
expect(view.model.get('membersonly')).toBeTruthy(); expect(view.model.get('membersonly')).toBeTruthy();
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
...@@ -3174,10 +3177,12 @@ ...@@ -3174,10 +3177,12 @@
it("contains a link to a modal through which a new chatroom can be created", it("contains a link to a modal through which a new chatroom can be created",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openControlBox(); test_utils.openControlBox();
_converse.emit('rosterContactsFetched');
var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel; var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
roomspanel.el.querySelector('.show-add-muc-modal').click(); roomspanel.el.querySelector('.show-add-muc-modal').click();
test_utils.closeControlBox(_converse); test_utils.closeControlBox(_converse);
...@@ -3193,6 +3198,8 @@ ...@@ -3193,6 +3198,8 @@
modal.el.querySelector('input[name="chatroom"]').value = 'lounce@muc.localhost'; modal.el.querySelector('input[name="chatroom"]').value = 'lounce@muc.localhost';
modal.el.querySelector('form input[type="submit"]').click(); modal.el.querySelector('form input[type="submit"]').click();
return test_utils.waitUntil(() => _converse.chatboxes.length);
}).then(() => {
expect($('.chatroom:visible').length).toBe(1); // There should now be an open chatroom expect($('.chatroom:visible').length).toBe(1); // There should now be an open chatroom
done(); done();
}).catch(_.partial(console.error, _)); }).catch(_.partial(console.error, _));
...@@ -3200,10 +3207,9 @@ ...@@ -3200,10 +3207,9 @@
it("contains a link to a modal which can list groupchats publically available on the server", it("contains a link to a modal which can list groupchats publically available on the server",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
...@@ -3216,9 +3222,8 @@ ...@@ -3216,9 +3222,8 @@
roomspanel.el.querySelector('.show-list-muc-modal').click(); roomspanel.el.querySelector('.show-list-muc-modal').click();
test_utils.closeControlBox(_converse); test_utils.closeControlBox(_converse);
const modal = roomspanel.list_rooms_modal; const modal = roomspanel.list_rooms_modal;
test_utils.waitUntil(function () { test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
return u.isVisible(modal.el); .then(() => {
}, 1000).then(function () {
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(function () { spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(function () {
var deferred = new $.Deferred(); var deferred = new $.Deferred();
deferred.resolve(); deferred.resolve();
...@@ -3231,7 +3236,8 @@ ...@@ -3231,7 +3236,8 @@
const input = modal.el.querySelector('input[name="server"]').value = 'chat.shakespear.lit'; const input = modal.el.querySelector('input[name="server"]').value = 'chat.shakespear.lit';
modal.el.querySelector('input[type="submit"]').click(); modal.el.querySelector('input[type="submit"]').click();
return test_utils.waitUntil(() => _converse.chatboxes.length);
}).then(() => {
expect(sent_stanza.toLocaleString()).toBe( expect(sent_stanza.toLocaleString()).toBe(
"<iq to='chat.shakespear.lit' from='dummy@localhost/resource' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+ "<iq to='chat.shakespear.lit' from='dummy@localhost/resource' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/disco#items'/>"+ "<query xmlns='http://jabber.org/protocol/disco#items'/>"+
...@@ -3260,6 +3266,8 @@ ...@@ -3260,6 +3266,8 @@
expect(rooms[4].textContent.trim()).toBe("Macbeth's Castle"); expect(rooms[4].textContent.trim()).toBe("Macbeth's Castle");
rooms[4].querySelector('.open-room').click(); rooms[4].querySelector('.open-room').click();
return test_utils.waitUntil(() => _converse.chatboxes.length > 1);
}).then(() => {
expect($('.chatroom:visible').length).toBe(1); // There should now be an open chatroom expect($('.chatroom:visible').length).toBe(1); // There should now be an open chatroom
var view = _converse.chatboxviews.get('inverness@chat.shakespeare.lit'); var view = _converse.chatboxviews.get('inverness@chat.shakespeare.lit');
expect(view.el.querySelector('.chat-head-chatroom').textContent.trim()).toBe("Macbeth's Castle"); expect(view.el.querySelector('.chat-head-chatroom').textContent.trim()).toBe("Macbeth's Castle");
...@@ -3509,10 +3517,11 @@ ...@@ -3509,10 +3517,11 @@
describe("A paused notification", function () { describe("A paused notification", function () {
it("will be shown if received", it("will be shown if received",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1'); test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1')
.then(() => {
var room_jid = 'coven@chat.shakespeare.lit'; var room_jid = 'coven@chat.shakespeare.lit';
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var $chat_content = $(view.el).find('.chat-content'); var $chat_content = $(view.el).find('.chat-content');
...@@ -3645,6 +3654,7 @@ ...@@ -3645,6 +3654,7 @@
expect(notifications[0].textContent).toEqual('nomorenicks is typing'); expect(notifications[0].textContent).toEqual('nomorenicks is typing');
expect(notifications[1].textContent).toEqual('newguy has stopped typing'); expect(notifications[1].textContent).toEqual('newguy has stopped typing');
done(); done();
});
})); }));
}); });
}); });
......
...@@ -225,25 +225,28 @@ ...@@ -225,25 +225,28 @@
[{'category': 'server', 'type':'IM'}], [{'category': 'server', 'type':'IM'}],
['http://jabber.org/protocol/disco#items'], [], 'info').then(function () { ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items').then(function () { let contact_jid, view;
test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []).then(function () {
test_utils.createContacts(_converse, 'current'); test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items')
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []))
test_utils.openChatBoxFor(_converse, contact_jid); .then(() => {
var view = _converse.chatboxviews.get(contact_jid); test_utils.createContacts(_converse, 'current', 3);
test_utils.waitUntil(function () { _converse.emit('rosterContactsFetched');
return view.el.querySelector('.upload-file');
}, 150).then(function () { contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
view = _converse.chatboxviews.get(contact_jid);
test_utils.waitUntil(() => view.el.querySelector('.upload-file'));
}).then(() => {
expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null); expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
done(); done();
}); });
}); });
});
});
})); }));
it("appears in MUC chats", mock.initConverseWithPromises( it("appears in MUC chats", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.waitUntilDiscoConfirmed( test_utils.waitUntilDiscoConfirmed(
...@@ -251,19 +254,15 @@ ...@@ -251,19 +254,15 @@
[{'category': 'server', 'type':'IM'}], [{'category': 'server', 'type':'IM'}],
['http://jabber.org/protocol/disco#items'], [], 'info').then(function () { ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items').then(function () { test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items')
test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []).then(function () { .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []))
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () { .then(() => test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'))
var view = _converse.chatboxviews.get('lounge@localhost'); .then(() => test_utils.waitUntil(() => _converse.chatboxviews.get('lounge@localhost').el.querySelector('.upload-file')))
test_utils.waitUntil(function () { .then(() => {
return view.el.querySelector('.upload-file'); const view = _converse.chatboxviews.get('lounge@localhost');
}).then(function () {
expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null); expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
});
});
});
}); });
})); }));
...@@ -277,12 +276,16 @@ ...@@ -277,12 +276,16 @@
var send_backup = XMLHttpRequest.prototype.send; var send_backup = XMLHttpRequest.prototype.send;
var IQ_stanzas = _converse.connection.IQ_stanzas; var IQ_stanzas = _converse.connection.IQ_stanzas;
let contact_jid;
test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items').then(function () { test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items')
test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []).then(function () { .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []))
.then(() => {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; _converse.emit('rosterContactsFetched');
test_utils.openChatBoxFor(_converse, contact_jid); contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
var file = { var file = {
'type': 'image/jpeg', 'type': 'image/jpeg',
...@@ -375,7 +378,6 @@ ...@@ -375,7 +378,6 @@
}); });
}); });
}); });
});
})); }));
it("is uploaded and sent out from a groupchat", mock.initConverseWithAsync(function (done, _converse) { it("is uploaded and sent out from a groupchat", mock.initConverseWithAsync(function (done, _converse) {
...@@ -487,18 +489,16 @@ ...@@ -487,18 +489,16 @@
}); });
})); }));
it("shows and error message if the file is too large", mock.initConverseWithAsync(function (done, _converse) { it("shows an error message if the file is too large", mock.initConverseWithAsync(function (done, _converse) {
var IQ_stanzas = _converse.connection.IQ_stanzas; const IQ_stanzas = _converse.connection.IQ_stanzas;
var IQ_ids = _converse.connection.IQ_ids; const IQ_ids = _converse.connection.IQ_ids;
var send_backup = XMLHttpRequest.prototype.send; const send_backup = XMLHttpRequest.prototype.send;
let view, contact_jid;
test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []).then(function () { test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [])
test_utils.waitUntil(function () { .then(() => test_utils.waitUntil(() => _.filter(
return _.filter(IQ_stanzas, function (iq) { IQ_stanzas, (iq) => iq.nodeTree.querySelector('iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]')).length
return iq.nodeTree.querySelector( )).then(() => {
'iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]');
}).length > 0;
}, 300).then(function () {
var stanza = _.find(IQ_stanzas, function (iq) { var stanza = _.find(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector( return iq.nodeTree.querySelector(
'iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]'); 'iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]');
...@@ -519,8 +519,8 @@ ...@@ -519,8 +519,8 @@
.c('feature', { .c('feature', {
'var': 'http://jabber.org/protocol/disco#items'}); 'var': 'http://jabber.org/protocol/disco#items'});
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
return _converse.api.disco.entities.get();
_converse.api.disco.entities.get().then(function(entities) { }).then(function (entities) {
expect(entities.length).toBe(2); expect(entities.length).toBe(2);
expect(_.includes(entities.pluck('jid'), 'localhost')).toBe(true); expect(_.includes(entities.pluck('jid'), 'localhost')).toBe(true);
expect(_.includes(entities.pluck('jid'), 'dummy@localhost')).toBe(true); expect(_.includes(entities.pluck('jid'), 'dummy@localhost')).toBe(true);
...@@ -535,7 +535,6 @@ ...@@ -535,7 +535,6 @@
return iq.nodeTree.querySelector('iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]'); return iq.nodeTree.querySelector('iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]');
}).length > 0; }).length > 0;
}, 300); }, 300);
});
}).then(function () { }).then(function () {
var stanza = _.find(IQ_stanzas, function (iq) { var stanza = _.find(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector('iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]'); return iq.nodeTree.querySelector('iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]');
...@@ -550,6 +549,7 @@ ...@@ -550,6 +549,7 @@
.c('item', { .c('item', {
'jid': 'upload.localhost', 'jid': 'upload.localhost',
'name': 'HTTP File Upload'}); 'name': 'HTTP File Upload'});
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.api.disco.entities.get().then(function (entities) { _converse.api.disco.entities.get().then(function (entities) {
...@@ -584,15 +584,18 @@ ...@@ -584,15 +584,18 @@
.c('field', {'var':'max-file-size'}) .c('field', {'var':'max-file-size'})
.c('value').t('5242880'); .c('value').t('5242880');
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
return _converse.api.disco.entities.get();
_converse.api.disco.entities.get().then(function (entities) { }).then(function (entities) {
expect(entities.get('localhost').items.get('upload.localhost').identities.where({'category': 'store'}).length).toBe(1); expect(entities.get('localhost').items.get('upload.localhost').identities.where({'category': 'store'}).length).toBe(1);
_converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, _converse.domain).then( return _converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, _converse.domain);
function (result) { }).then(function (result) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; _converse.emit('rosterContactsFetched');
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid); contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
view = _converse.chatboxviews.get(contact_jid);
var file = { var file = {
'type': 'image/jpeg', 'type': 'image/jpeg',
'size': '5242881', 'size': '5242881',
...@@ -600,27 +603,23 @@ ...@@ -600,27 +603,23 @@
'name': "my-juliet.jpg" 'name': "my-juliet.jpg"
}; };
view.model.sendFiles([file]); view.model.sendFiles([file]);
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => view.el.querySelectorAll('.message').length)
return view.el.querySelectorAll('.message').length;
}).then(function () { }).then(function () {
const messages = view.el.querySelectorAll('.message.chat-error'); const messages = view.el.querySelectorAll('.message.chat-error');
expect(messages.length).toBe(1); expect(messages.length).toBe(1);
expect(messages[0].textContent).toBe( expect(messages[0].textContent).toBe(
'The size of your file, my-juliet.jpg, exceeds the maximum allowed by your server, which is 5 MB.'); 'The size of your file, my-juliet.jpg, exceeds the maximum allowed by your server, which is 5 MB.');
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}
);
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})
});
})); }));
}); });
}); });
describe("While a file is being uploaded", function () { describe("While a file is being uploaded", function () {
it("shows a progress bar", mock.initConverseWithAsync(function (done, _converse) { it("shows a progress bar", mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
test_utils.waitUntilDiscoConfirmed( test_utils.waitUntilDiscoConfirmed(
_converse, _converse.domain, _converse, _converse.domain,
[{'category': 'server', 'type':'IM'}], [{'category': 'server', 'type':'IM'}],
...@@ -628,26 +627,28 @@ ...@@ -628,26 +627,28 @@
var send_backup = XMLHttpRequest.prototype.send; var send_backup = XMLHttpRequest.prototype.send;
var IQ_stanzas = _converse.connection.IQ_stanzas; var IQ_stanzas = _converse.connection.IQ_stanzas;
let view, contact_jid;
test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items').then(function () { test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items')
test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []).then(function () { .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []))
.then(() => {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; _converse.emit('rosterContactsFetched');
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid); contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
var file = { return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
view = _converse.chatboxviews.get(contact_jid);
const file = {
'type': 'image/jpeg', 'type': 'image/jpeg',
'size': '23456' , 'size': '23456' ,
'lastModifiedDate': "", 'lastModifiedDate': "",
'name': "my-juliet.jpg" 'name': "my-juliet.jpg"
}; };
view.model.sendFiles([file]); view.model.sendFiles([file]);
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request')).length)
return _.filter(IQ_stanzas, function (iq) {
return iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request');
}).length > 0;
}).then(function () { }).then(function () {
var iq = IQ_stanzas.pop(); const iq = IQ_stanzas.pop();
expect(iq.toLocaleString()).toBe( expect(iq.toLocaleString()).toBe(
"<iq from='dummy@localhost/resource' "+ "<iq from='dummy@localhost/resource' "+
"to='upload.montague.tld' "+ "to='upload.montague.tld' "+
...@@ -660,10 +661,9 @@ ...@@ -660,10 +661,9 @@
"content-type='image/jpeg'/>"+ "content-type='image/jpeg'/>"+
"</iq>"); "</iq>");
var base_url = document.URL.split(window.location.pathname)[0]; const base_url = document.URL.split(window.location.pathname)[0];
var message = base_url+"/logo/conversejs-filled.svg"; const message = base_url+"/logo/conversejs-filled.svg";
const stanza = Strophe.xmlHtmlNode(
var stanza = Strophe.xmlHtmlNode(
"<iq from='upload.montague.tld'"+ "<iq from='upload.montague.tld'"+
" id='"+iq.nodeTree.getAttribute('id')+"'"+ " id='"+iq.nodeTree.getAttribute('id')+"'"+
" to='dummy@localhost/resource'"+ " to='dummy@localhost/resource'"+
...@@ -676,7 +676,6 @@ ...@@ -676,7 +676,6 @@
" <get url='"+message+"' />"+ " <get url='"+message+"' />"+
"</slot>"+ "</slot>"+
"</iq>").firstElementChild; "</iq>").firstElementChild;
spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () { spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
const message = view.model.messages.at(0); const message = view.model.messages.at(0);
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0'); expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');
...@@ -694,11 +693,8 @@ ...@@ -694,11 +693,8 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
}); });
}); });
});
});
})); }));
}); });
}); });
}); });
})); }));
...@@ -21,14 +21,15 @@ ...@@ -21,14 +21,15 @@
it("can be sent as a correction by clicking the pencil icon", it("can be sent as a correction by clicking the pencil icon",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
const view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
const textarea = view.el.querySelector('textarea.chat-textarea'); const textarea = view.el.querySelector('textarea.chat-textarea');
...@@ -115,19 +116,21 @@ ...@@ -115,19 +116,21 @@
); );
expect(view.el.querySelectorAll('.chat-msg .chat-msg__action').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg .chat-msg__action').length).toBe(1);
done(); done();
});
})); }));
it("can be sent as a correction by using the up arrow", it("can be sent as a correction by using the up arrow",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
const view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
const textarea = view.el.querySelector('textarea.chat-textarea'); const textarea = view.el.querySelector('textarea.chat-textarea');
expect(textarea.value).toBe(''); expect(textarea.value).toBe('');
...@@ -262,6 +265,7 @@ ...@@ -262,6 +265,7 @@
expect(view.model.messages.at(1).get('correcting')).toBeFalsy(); expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
expect(view.model.messages.at(2).get('correcting')).toBeFalsy(); expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
done(); done();
});
})); }));
...@@ -321,15 +325,16 @@ ...@@ -321,15 +325,16 @@
it("can be replaced with a correction", it("can be replaced with a correction",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
const message = 'This is a received message'; const message = 'This is a received message';
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, sender_jid); test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
const msg_id = u.getUniqueId(); const msg_id = u.getUniqueId();
_converse.chatboxes.onMessage($msg({ _converse.chatboxes.onMessage($msg({
'from': sender_jid, 'from': sender_jid,
...@@ -381,6 +386,7 @@ ...@@ -381,6 +386,7 @@
expect(older_msgs[1].textContent).toBe('But soft, what light through yonder chimney breaks?'); expect(older_msgs[1].textContent).toBe('But soft, what light through yonder chimney breaks?');
done(); done();
}); });
});
})); }));
describe("when a chatbox is opened for someone who is not in the roster", function () { describe("when a chatbox is opened for someone who is not in the roster", function () {
...@@ -500,10 +506,11 @@ ...@@ -500,10 +506,11 @@
it("will have the error message displayed after itself", it("will have the error message displayed after itself",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
// TODO: what could still be done for error // TODO: what could still be done for error
...@@ -524,7 +531,8 @@ ...@@ -524,7 +531,8 @@
var sender_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost'; var sender_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
var fullname = _converse.xmppstatus.get('fullname'); var fullname = _converse.xmppstatus.get('fullname');
fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname; fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname;
_converse.api.chats.open(sender_jid); _converse.api.chats.open(sender_jid)
.then(() => {
var msg_text = 'This message will not be sent, due to an error'; var msg_text = 'This message will not be sent, due to an error';
var view = _converse.chatboxviews.get(sender_jid); var view = _converse.chatboxviews.get(sender_jid);
var message = view.model.messages.create({ var message = view.model.messages.create({
...@@ -621,25 +629,28 @@ ...@@ -621,25 +629,28 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').length).toEqual(3); expect($chat_content.find('.chat-error').length).toEqual(3);
done(); done();
});
})); }));
}); });
it("will cause the chat area to be scrolled down only if it was at the bottom originally", it("will cause the chat area to be scrolled down only if it was at the bottom originally",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; let chatboxview;
test_utils.openChatBoxFor(_converse, sender_jid); const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const message = 'This message is received while the chat area is scrolled up';
var chatboxview = _converse.chatboxviews.get(sender_jid); test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
chatboxview = _converse.chatboxviews.get(sender_jid);
spyOn(chatboxview, 'onScrolledDown').and.callThrough(); spyOn(chatboxview, 'onScrolledDown').and.callThrough();
// Create enough messages so that there's a scrollbar. // Create enough messages so that there's a scrollbar.
var message = 'This message is received while the chat area is scrolled up';
for (var i=0; i<20; i++) { for (var i=0; i<20; i++) {
_converse.chatboxes.onMessage($msg({ _converse.chatboxes.onMessage($msg({
from: sender_jid, from: sender_jid,
...@@ -649,18 +660,12 @@ ...@@ -649,18 +660,12 @@
}).c('body').t('Message: '+i).up() }).c('body').t('Message: '+i).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()); .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
} }
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => chatboxview.content.scrollTop, 1000)
return chatboxview.content.scrollTop; .then(() => test_utils.waitUntil(() => !chatboxview.model.get('auto_scrolled'), 500))
}, 1000).then(function () { }).then(() => {
return test_utils.waitUntil(function () {
return !chatboxview.model.get('auto_scrolled');
}, 500);
}).then(function () {
chatboxview.content.scrollTop = 0; chatboxview.content.scrollTop = 0;
return test_utils.waitUntil(function () { return test_utils.waitUntil(() => chatboxview.model.get('scrolled'), 900);
return chatboxview.model.get('scrolled'); }).then(() => {
}, 900);
}).then(function () {
_converse.chatboxes.onMessage($msg({ _converse.chatboxes.onMessage($msg({
from: sender_jid, from: sender_jid,
to: _converse.connection.jid, to: _converse.connection.jid,
...@@ -1109,23 +1114,22 @@ ...@@ -1109,23 +1114,22 @@
it("received for a minimized chat box will increment a counter on its header", it("received for a minimized chat box will increment a counter on its header",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
if (_converse.view_mode === 'fullscreen') { if (_converse.view_mode === 'fullscreen') {
return done(); return done();
} }
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_name = mock.cur_names[0];
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group').length;
}, 300)
.then(function () {
var contact_name = mock.cur_names[0];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(_converse, 'emit').and.callThrough(); spyOn(_converse, 'emit').and.callThrough();
test_utils.openChatBoxFor(_converse, contact_jid);
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
.then(() => test_utils.openChatBoxFor(_converse, contact_jid))
.then(() => {
var chatview = _converse.chatboxviews.get(contact_jid); var chatview = _converse.chatboxviews.get(contact_jid);
expect(u.isVisible(chatview.el)).toBeTruthy(); expect(u.isVisible(chatview.el)).toBeTruthy();
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
...@@ -1171,19 +1175,18 @@ ...@@ -1171,19 +1175,18 @@
it("will indicate when it has a time difference of more than a day between it and its predecessor", it("will indicate when it has a time difference of more than a day between it and its predecessor",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group').length;
}, 300)
.then(function () {
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
var contact_name = mock.cur_names[1]; const contact_name = mock.cur_names[1];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
.then(() => test_utils.openChatBoxFor(_converse, contact_jid))
.then(() => {
test_utils.clearChatBoxMessages(_converse, contact_jid); test_utils.clearChatBoxMessages(_converse, contact_jid);
var one_day_ago = moment(); var one_day_ago = moment();
one_day_ago.subtract('days', 1); one_day_ago.subtract('days', 1);
...@@ -1270,18 +1273,20 @@ ...@@ -1270,18 +1273,20 @@
it("can be sent from a chatbox, and will appear inside it", it("can be sent from a chatbox, and will appear inside it",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object)); expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
var view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
var message = 'This message is sent from this chatbox'; const message = 'This message is sent from this chatbox';
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
...@@ -1289,61 +1294,70 @@ ...@@ -1289,61 +1294,70 @@
expect(_converse.emit.calls.mostRecent().args, ['messageSend', message]); expect(_converse.emit.calls.mostRecent().args, ['messageSend', message]);
expect($(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text').text()).toEqual(message); expect($(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text').text()).toEqual(message);
done(); done();
});
})); }));
it("is sanitized to prevent Javascript injection attacks", it("is sanitized to prevent Javascript injection attacks",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
var view = _converse.chatboxviews.get(contact_jid); .then(() => {
var message = '<p>This message contains <em>some</em> <b>markup</b></p>'; const view = _converse.chatboxviews.get(contact_jid);
const message = '<p>This message contains <em>some</em> <b>markup</b></p>';
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text'); const msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('&lt;p&gt;This message contains &lt;em&gt;some&lt;/em&gt; &lt;b&gt;markup&lt;/b&gt;&lt;/p&gt;'); expect(msg.html()).toEqual('&lt;p&gt;This message contains &lt;em&gt;some&lt;/em&gt; &lt;b&gt;markup&lt;/b&gt;&lt;/p&gt;');
done(); done();
});
})); }));
it("can contain hyperlinks, which will be clickable", it("can contain hyperlinks, which will be clickable",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
var view = _converse.chatboxviews.get(contact_jid); .then(() => {
var message = 'This message contains a hyperlink: www.opkode.com'; const view = _converse.chatboxviews.get(contact_jid);
const message = 'This message contains a hyperlink: www.opkode.com';
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text'); const msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text');
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('This message contains a hyperlink: <a target="_blank" rel="noopener" href="http://www.opkode.com">www.opkode.com</a>'); expect(msg.html()).toEqual('This message contains a hyperlink: <a target="_blank" rel="noopener" href="http://www.opkode.com">www.opkode.com</a>');
done(); done();
});
})); }));
it("will have properly escaped URLs", it("will have properly escaped URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var message, msg; let message, msg;
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
message = "http://www.opkode.com/'onmouseover='alert(1)'whatever"; message = "http://www.opkode.com/'onmouseover='alert(1)'whatever";
...@@ -1376,10 +1390,14 @@ ...@@ -1376,10 +1390,14 @@
expect(msg.text()).toEqual(message); expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>'); expect(msg.html()).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>');
done(); done();
});
})); }));
it("will render newlines", mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {}, function (done, _converse) { it("will render newlines",
mock.initConverseWithPromises(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid);
...@@ -1417,19 +1435,22 @@ ...@@ -1417,19 +1435,22 @@
it("will render images from their URLs", it("will render images from their URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
const base_url = document.URL.split(window.location.pathname)[0]; const base_url = document.URL.split(window.location.pathname)[0];
let message = base_url+"/logo/conversejs-filled.svg"; let message = base_url+"/logo/conversejs-filled.svg";
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); let view;
const view = _converse.chatboxviews.get(contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
return test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length, 1000)
test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length, 1000).then(() => { }).then(() => {
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
const msg = $(view.el).find('.chat-content .chat-msg').last().find('.chat-msg__text'); const msg = $(view.el).find('.chat-content .chat-msg').last().find('.chat-msg__text');
expect(msg.html().trim()).toEqual( expect(msg.html().trim()).toEqual(
...@@ -1462,29 +1483,32 @@ ...@@ -1462,29 +1483,32 @@
it("will render the message time as configured", it("will render the message time as configured",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'],
function (done, _converse) { {}, function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
_converse.time_format = 'hh:mm'; _converse.time_format = 'hh:mm';
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
var view = _converse.chatboxviews.get(contact_jid); .then(() => {
var message = 'This message is sent from this chatbox'; const view = _converse.chatboxviews.get(contact_jid);
const message = 'This message is sent from this chatbox';
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
var chatbox = _converse.chatboxes.get(contact_jid); const chatbox = _converse.chatboxes.get(contact_jid);
expect(chatbox.messages.models.length, 1); expect(chatbox.messages.models.length, 1);
var msg_object = chatbox.messages.models[0]; const msg_object = chatbox.messages.models[0];
var msg_author = view.el.querySelector('.chat-content .chat-msg:last-child .chat-msg__author'); const msg_author = view.el.querySelector('.chat-content .chat-msg:last-child .chat-msg__author');
expect(msg_author.textContent.trim()).toBe('Max Mustermann'); expect(msg_author.textContent.trim()).toBe('Max Mustermann');
var msg_time = view.el.querySelector('.chat-content .chat-msg:last-child .chat-msg__time'); const msg_time = view.el.querySelector('.chat-content .chat-msg:last-child .chat-msg__time');
var time = moment(msg_object.get('time')).format(_converse.time_format); const time = moment(msg_object.get('time')).format(_converse.time_format);
expect(msg_time.textContent).toBe(time); expect(msg_time.textContent).toBe(time);
done(); done();
});
})); }));
it("will be correctly identified and rendered as a followup message", it("will be correctly identified and rendered as a followup message",
...@@ -1655,17 +1679,20 @@ ...@@ -1655,17 +1679,20 @@
})); }));
describe("which contains a OOB URL", function () { describe("which contains an OOB URL", function () {
it("will render audio from oob mp3 URLs", it("will render audio from oob mp3 URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); let view;
const view = _converse.chatboxviews.get(contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
const stanza = Strophe.xmlHtmlNode( const stanza = Strophe.xmlHtmlNode(
...@@ -1674,10 +1701,11 @@ ...@@ -1674,10 +1701,11 @@
" to='dummy@localhost/resource'>"+ " to='dummy@localhost/resource'>"+
" <body>Have you heard this funny audio?</body>"+ " <body>Have you heard this funny audio?</body>"+
" <x xmlns='jabber:x:oob'><url>http://localhost/audio.mp3</url></x>"+ " <x xmlns='jabber:x:oob'><url>http://localhost/audio.mp3</url></x>"+
"</message>").firstChild; "</message>").firstChild
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000).then(function () { return test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
}).then(() => {
let msg = view.el.querySelector('.chat-msg .chat-msg__text'); let msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you heard this funny audio?</div>'); expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you heard this funny audio?</div>');
let media = view.el.querySelector('.chat-msg .chat-msg__media'); let media = view.el.querySelector('.chat-msg .chat-msg__media');
...@@ -1709,12 +1737,14 @@ ...@@ -1709,12 +1737,14 @@
it("will render video from oob mp4 URLs", it("will render video from oob mp4 URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
const view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
...@@ -1755,17 +1785,21 @@ ...@@ -1755,17 +1785,21 @@
'<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>'); '<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>');
done(); done();
}); });
});
})); }));
it("will render download links for files from oob URLs", it("will render download links for files from oob URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current', 1); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); let view;
const view = _converse.chatboxviews.get(contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
const stanza = Strophe.xmlHtmlNode( const stanza = Strophe.xmlHtmlNode(
...@@ -1777,7 +1811,8 @@ ...@@ -1777,7 +1811,8 @@
"</message>").firstChild; "</message>").firstChild;
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000).then(function () { test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
}).then(function () {
const msg = view.el.querySelector('.chat-msg .chat-msg__text'); const msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you downloaded this funny file?</div>'); expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you downloaded this funny file?</div>');
const media = view.el.querySelector('.chat-msg .chat-msg__media'); const media = view.el.querySelector('.chat-msg .chat-msg__media');
...@@ -1790,13 +1825,16 @@ ...@@ -1790,13 +1825,16 @@
it("will render images from oob URLs", it("will render images from oob URLs",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); let view;
const view = _converse.chatboxviews.get(contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough(); spyOn(view.model, 'sendMessage').and.callThrough();
const base_url = document.URL.split(window.location.pathname)[0]; const base_url = document.URL.split(window.location.pathname)[0];
const url = base_url+"/logo/conversejs-filled.svg"; const url = base_url+"/logo/conversejs-filled.svg";
...@@ -1809,8 +1847,8 @@ ...@@ -1809,8 +1847,8 @@
" <x xmlns='jabber:x:oob'><url>"+url+"</url></x>"+ " <x xmlns='jabber:x:oob'><url>"+url+"</url></x>"+
"</message>").firstChild; "</message>").firstChild;
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
return test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000);
test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000).then(function () { }).then(function () {
const msg = view.el.querySelector('.chat-msg .chat-msg__text'); const msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you seen this funny image?</div>'); expect(msg.outerHTML).toEqual('<div class="chat-msg__text">Have you seen this funny image?</div>');
const media = view.el.querySelector('.chat-msg .chat-msg__media'); const media = view.el.querySelector('.chat-msg .chat-msg__media');
......
...@@ -13,13 +13,16 @@ ...@@ -13,13 +13,16 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
_converse.minimized_chats.toggleview.model.browserStorage._clear(); _converse.minimized_chats.toggleview.model.browserStorage._clear();
_converse.minimized_chats.initToggle(); _converse.minimized_chats.initToggle();
var contact_jid, chatview; let contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; let chatview;
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
chatview = _converse.chatboxviews.get(contact_jid); chatview = _converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
expect($(_converse.minimized_chats.el).is(':visible')).toBeFalsy(); expect($(_converse.minimized_chats.el).is(':visible')).toBeFalsy();
...@@ -30,7 +33,8 @@ ...@@ -30,7 +33,8 @@
expect(_converse.minimized_chats.keys()[0]).toBe(contact_jid); expect(_converse.minimized_chats.keys()[0]).toBe(contact_jid);
contact_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; contact_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); return test_utils.openChatBoxFor(_converse, contact_jid);
}).then(() => {
chatview = _converse.chatboxviews.get(contact_jid); chatview = _converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy(); expect(chatview.model.get('minimized')).toBeFalsy();
chatview.el.querySelector('.toggle-chatbox-button').click(); chatview.el.querySelector('.toggle-chatbox-button').click();
...@@ -39,6 +43,7 @@ ...@@ -39,6 +43,7 @@
expect(_converse.minimized_chats.keys().length).toBe(2); expect(_converse.minimized_chats.keys().length).toBe(2);
expect(_.includes(_converse.minimized_chats.keys(), contact_jid)).toBeTruthy(); expect(_.includes(_converse.minimized_chats.keys(), contact_jid)).toBeTruthy();
done(); done();
});
})); }));
it("can be toggled to hide or show minimized chats", it("can be toggled to hide or show minimized chats",
...@@ -47,24 +52,26 @@ ...@@ -47,24 +52,26 @@
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
_converse.minimized_chats.toggleview.model.browserStorage._clear(); _converse.minimized_chats.toggleview.model.browserStorage._clear();
_converse.minimized_chats.initToggle(); _converse.minimized_chats.initToggle();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
var chatview = _converse.chatboxviews.get(contact_jid); .then(() => {
expect($(_converse.minimized_chats.el).is(':visible')).toBeFalsy(); const chatview = _converse.chatboxviews.get(contact_jid);
expect(u.isVisible(_converse.minimized_chats.el)).toBeFalsy();
chatview.model.set({'minimized': true}); chatview.model.set({'minimized': true});
expect($(_converse.minimized_chats.el).is(':visible')).toBeTruthy(); expect(u.isVisible(_converse.minimized_chats.el)).toBeTruthy();
expect(_converse.minimized_chats.keys().length).toBe(1); expect(_converse.minimized_chats.keys().length).toBe(1);
expect(_converse.minimized_chats.keys()[0]).toBe(contact_jid); expect(_converse.minimized_chats.keys()[0]).toBe(contact_jid);
expect($(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')).is(':visible')).toBeTruthy(); expect(u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy(); expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
_converse.minimized_chats.el.querySelector('#toggle-minimized-chats').click(); _converse.minimized_chats.el.querySelector('#toggle-minimized-chats').click();
return test_utils.waitUntil(() => u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')));
return test_utils.waitUntil(() => u.isVisible(u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')))) }).then(() => {
.then(function () {
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy(); expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
done(); done();
}); });
......
...@@ -12,25 +12,26 @@ ...@@ -12,25 +12,26 @@
describe("A list of open rooms", function () { describe("A list of open rooms", function () {
it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises( it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], null, ['rosterGroupsFetched', 'chatBoxesFetched'],
{ allow_bookmarks: false // Makes testing easier, otherwise we { allow_bookmarks: false // Makes testing easier, otherwise we
// have to mock stanza traffic. // have to mock stanza traffic.
}, },
function (done, _converse) { function (done, _converse) {
test_utils.openControlBox(); test_utils.openControlBox();
var controlbox = _converse.chatboxviews.get('controlbox'); const controlbox = _converse.chatboxviews.get('controlbox');
let list = controlbox.el.querySelector('div.rooms-list-container');
var list = controlbox.el.querySelector('div.rooms-list-container');
expect(_.includes(list.classList, 'hidden')).toBeTruthy(); expect(_.includes(list.classList, 'hidden')).toBeTruthy();
test_utils.openChatRoom(_converse, 'room', 'conference.shakespeare.lit', 'JC'); let room_els;
test_utils.openChatRoom(_converse, 'room', 'conference.shakespeare.lit', 'JC')
.then(() => {
expect(_.isUndefined(_converse.rooms_list_view)).toBeFalsy(); expect(_.isUndefined(_converse.rooms_list_view)).toBeFalsy();
var room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room"); room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1); expect(room_els.length).toBe(1);
expect(room_els[0].innerText).toBe('room@conference.shakespeare.lit'); expect(room_els[0].innerText).toBe('room@conference.shakespeare.lit');
return test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); }).then(() => {
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room"); room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(2); expect(room_els.length).toBe(2);
...@@ -50,6 +51,7 @@ ...@@ -50,6 +51,7 @@
list = controlbox.el.querySelector('div.rooms-list-container'); list = controlbox.el.querySelector('div.rooms-list-container');
expect(_.includes(list.classList, 'hidden')).toBeTruthy(); expect(_.includes(list.classList, 'hidden')).toBeTruthy();
done(); done();
});
} }
)); ));
}); });
...@@ -57,26 +59,26 @@ ...@@ -57,26 +59,26 @@
describe("A groupchat shown in the groupchats list", function () { describe("A groupchat shown in the groupchats list", function () {
it("is highlighted if its currently open", mock.initConverseWithPromises( it("is highlighted if its currently open", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], null, ['rosterGroupsFetched', 'chatBoxesFetched'],
{ whitelisted_plugins: ['converse-roomslist'], { whitelisted_plugins: ['converse-roomslist'],
allow_bookmarks: false // Makes testing easier, otherwise we allow_bookmarks: false // Makes testing easier, otherwise we
// have to mock stanza traffic. // have to mock stanza traffic.
}, function (done, _converse) { }, function (done, _converse) {
spyOn(_converse, 'isSingleton').and.callFake(function () { spyOn(_converse, 'isSingleton').and.callFake(() => true);
return true;
});
let room_els, item;
test_utils.openControlBox(); test_utils.openControlBox();
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'})
let room_els = _converse.rooms_list_view.el.querySelectorAll(".available-chatroom"); .then(() => {
room_els = _converse.rooms_list_view.el.querySelectorAll(".available-chatroom");
expect(room_els.length).toBe(1); expect(room_els.length).toBe(1);
let item = room_els[0]; item = room_els[0];
expect(u.hasClass('open', item)).toBe(true); expect(u.hasClass('open', item)).toBe(true);
expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit'); expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
return _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'});
_converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'}); }).then(() => {
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room"); room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(2); expect(room_els.length).toBe(2);
...@@ -85,18 +87,21 @@ ...@@ -85,18 +87,21 @@
item = room_els[0]; item = room_els[0];
expect(item.textContent.trim()).toBe('balcony@chat.shakespeare.lit'); expect(item.textContent.trim()).toBe('balcony@chat.shakespeare.lit');
done(); done();
});
})); }));
it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises( it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], null, ['rosterGroupsFetched', 'chatBoxesFetched'],
{ whitelisted_plugins: ['converse-roomslist'], { whitelisted_plugins: ['converse-roomslist'],
allow_bookmarks: false // Makes testing easier, otherwise we allow_bookmarks: false // Makes testing easier, otherwise we
// have to mock stanza traffic. // have to mock stanza traffic.
}, function (done, _converse) { }, function (done, _converse) {
let view;
test_utils.openControlBox(); test_utils.openControlBox();
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'}); _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'})
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); .then(() => {
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
const last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree; const last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
const IQ_id = last_stanza.getAttribute('id'); const IQ_id = last_stanza.getAttribute('id');
const features_stanza = $iq({ const features_stanza = $iq({
...@@ -127,9 +132,8 @@ ...@@ -127,9 +132,8 @@
.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));
return test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING) }).then(function () {
.then(function () {
var presence = $pres({ var presence = $pres({
to: _converse.connection.jid, to: _converse.connection.jid,
from: 'coven@chat.shakespeare.lit/some1', from: 'coven@chat.shakespeare.lit/some1',
...@@ -201,12 +205,10 @@ ...@@ -201,12 +205,10 @@
}, },
function (done, _converse) { function (done, _converse) {
spyOn(window, 'confirm').and.callFake(function () { spyOn(window, 'confirm').and.callFake(() => true);
return true;
});
expect(_converse.chatboxes.length).toBe(1); expect(_converse.chatboxes.length).toBe(1);
test_utils.openChatRoom( test_utils.openChatRoom(_converse, 'lounge', 'conference.shakespeare.lit', 'JC')
_converse, 'lounge', 'conference.shakespeare.lit', 'JC'); .then(() => {
expect(_converse.chatboxes.length).toBe(2); expect(_converse.chatboxes.length).toBe(2);
var room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room"); var room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1); expect(room_els.length).toBe(1);
...@@ -218,6 +220,7 @@ ...@@ -218,6 +220,7 @@
expect(room_els.length).toBe(0); expect(room_els.length).toBe(0);
expect(_converse.chatboxes.length).toBe(1); expect(_converse.chatboxes.length).toBe(1);
done(); done();
});
})); }));
it("shows unread messages directed at the user", mock.initConverseWithAsync( it("shows unread messages directed at the user", mock.initConverseWithAsync(
......
...@@ -92,12 +92,14 @@ ...@@ -92,12 +92,14 @@
it("can be sent without a hint", it("can be sent without a hint",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
// XXX: We need to send a presence from the contact, so that we // XXX: We need to send a presence from the contact, so that we
// have a resource, that resource is then queried to see // have a resource, that resource is then queried to see
...@@ -108,9 +110,9 @@ ...@@ -108,9 +110,9 @@
'to': 'dummy@localhost' 'to': 'dummy@localhost'
}); });
_converse.connection._dataRecv(test_utils.createRequest(presence)); _converse.connection._dataRecv(test_utils.createRequest(presence));
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]))
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () { .then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
spyOn(view, 'onMessageSubmitted').and.callThrough(); spyOn(view, 'onMessageSubmitted').and.callThrough();
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
...@@ -167,10 +169,12 @@ ...@@ -167,10 +169,12 @@
it("can be sent with a hint", it("can be sent with a hint",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox(); test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
...@@ -183,9 +187,9 @@ ...@@ -183,9 +187,9 @@
'to': 'dummy@localhost' 'to': 'dummy@localhost'
}); });
_converse.connection._dataRecv(test_utils.createRequest(presence)); _converse.connection._dataRecv(test_utils.createRequest(presence));
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]))
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () { .then(() => {
var view = _converse.chatboxviews.get(contact_jid); var view = _converse.chatboxviews.get(contact_jid);
var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler'); var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
spoiler_toggle.click(); spoiler_toggle.click();
......
...@@ -58,16 +58,17 @@ ...@@ -58,16 +58,17 @@
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched'); _converse.emit('rosterContactsFetched');
let view, modal;
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
const view = _converse.chatboxviews.get(contact_jid); view = _converse.chatboxviews.get(contact_jid);
const show_modal_button = view.el.querySelector('.show-user-details-modal'); const show_modal_button = view.el.querySelector('.show-user-details-modal');
expect(u.isVisible(show_modal_button)).toBeTruthy(); expect(u.isVisible(show_modal_button)).toBeTruthy();
show_modal_button.click(); show_modal_button.click();
const modal = view.user_details_modal; modal = view.user_details_modal;
test_utils.waitUntil(() => u.isVisible(modal.el), 2000) return test_utils.waitUntil(() => u.isVisible(modal.el), 2000);
.then(function () { }).then(function () {
spyOn(window, 'confirm').and.returnValue(true); spyOn(window, 'confirm').and.returnValue(true);
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback, errback) { spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback, errback) {
errback(); errback();
......
...@@ -561,8 +561,7 @@ ...@@ -561,8 +561,7 @@
const handler = () => { const handler = () => {
if (!u.isPersistableModel(this.model)) { if (!u.isPersistableModel(this.model)) {
// Happens during tests, nothing to do if this // Happens during tests, nothing to do if this
// is a hanging chatbox (i.e. not in the // is a hanging chatbox (i.e. not in the collection anymore).
// collection anymore).
return; return;
} }
this.populateAndJoin(); this.populateAndJoin();
......
...@@ -148,8 +148,13 @@ ...@@ -148,8 +148,13 @@
); );
xhr.onload = function () { xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) { if (xhr.status >= 200 && xhr.status < 400) {
jed_instance = new Jed(window.JSON.parse(xhr.responseText)); try {
const data = window.JSON.parse(xhr.responseText);
jed_instance = new Jed(data);
resolve(); resolve();
} catch (e) {
xhr.onerror(e);
}
} else { } else {
xhr.onerror(); xhr.onerror();
} }
......
...@@ -98,8 +98,9 @@ ...@@ -98,8 +98,9 @@
return views; return views;
}; };
utils.openChatBoxFor = function (converse, jid) { utils.openChatBoxFor = function (_converse, jid) {
return converse.roster.get(jid).trigger("open"); _converse.roster.get(jid).trigger("open");
return utils.waitUntil(() => _converse.chatboxviews.get(jid));
}; };
utils.openChatRoomViaModal = function (_converse, jid, nick) { utils.openChatRoomViaModal = function (_converse, jid, nick) {
...@@ -121,14 +122,14 @@ ...@@ -121,14 +122,14 @@
}; };
utils.openChatRoom = function (_converse, room, server, nick) { utils.openChatRoom = function (_converse, room, server, nick) {
_converse.api.rooms.open(`${room}@${server}`); return _converse.api.rooms.open(`${room}@${server}`);
}; };
utils.openAndEnterChatRoom = function (_converse, room, server, nick) { utils.openAndEnterChatRoom = function (_converse, room, server, nick) {
let last_stanza; let last_stanza;
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
_converse.api.rooms.open(`${room}@${server}`); return _converse.api.rooms.open(`${room}@${server}`).then(() => {
const view = _converse.chatboxviews.get((room+'@'+server).toLowerCase()); const view = _converse.chatboxviews.get((room+'@'+server).toLowerCase());
// 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.
let last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree; let last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
...@@ -178,7 +179,7 @@ ...@@ -178,7 +179,7 @@
.c('status').attrs({code:'110'}); .c('status').attrs({code:'110'});
_converse.connection._dataRecv(utils.createRequest(presence)); _converse.connection._dataRecv(utils.createRequest(presence));
resolve(); resolve();
}).catch(_.partial(console.error, _));
}).catch(_.partial(console.error, _)); }).catch(_.partial(console.error, _));
}).catch(_.partial(console.error, _)); }).catch(_.partial(console.error, _));
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment