Commit a2f4acdc authored by JC Brand's avatar JC Brand

All tests suites now updated and isolated.

parent 3e409573
/*global converse */
(function (root, factory) {
define([
"jquery",
......@@ -14,7 +13,12 @@
describe("A chat room", function () {
it("can be bookmarked", function () {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("can be bookmarked", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -23,7 +27,7 @@
});
spyOn(converse.connection, 'getUniqueId').andCallThrough();
test_utils.openChatRoom('theplay', 'conference.shakespeare.lit', 'JC');
test_utils.openChatRoom(converse, 'theplay', 'conference.shakespeare.lit', 'JC');
var jid = 'theplay@conference.shakespeare.lit';
var view = converse.chatboxviews.get(jid);
spyOn(view, 'renderBookmarkForm').andCallThrough();
......@@ -121,9 +125,9 @@
converse.connection._dataRecv(test_utils.createRequest(stanza));
// We ignore this IQ stanza... (unless it's an error stanza), so
// nothing to test for here.
});
}));
it("will be automatically opened if 'autojoin' is set on the bookmark", function () {
it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverse(function (converse) {
var jid = 'lounge@localhost';
converse.bookmarks.create({
'jid': jid,
......@@ -141,17 +145,18 @@
'nick': ' Othello'
});
expect(_.isUndefined(converse.chatboxviews.get(jid))).toBeFalsy();
});
}));
describe("when bookmarked", function () {
beforeEach(function () {
test_utils.closeAllChatBoxes();
converse.bookmarks.reset();
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("displays that it's bookmarked through its bookmark icon", function () {
it("displays that it's bookmarked through its bookmark icon", mock.initConverse(function (converse) {
runs(function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
});
waits(100);
runs(function () {
......@@ -163,9 +168,9 @@
view.model.set('bookmarked', false);
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
});
});
}));
it("can be unbookmarked", function () {
it("can be unbookmarked", mock.initConverse(function (converse) {
var view, sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -175,7 +180,7 @@
spyOn(converse.connection, 'getUniqueId').andCallThrough();
runs(function () {
test_utils.openChatRoom('theplay', 'conference.shakespeare.lit', 'JC');
test_utils.openChatRoom(converse, 'theplay', 'conference.shakespeare.lit', 'JC');
});
waits(100);
runs(function () {
......@@ -229,15 +234,16 @@
"</iq>"
);
});
});
}));
});
describe("and when autojoin is set", function () {
beforeEach(function () {
converse.bookmarks.reset();
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("will be be opened and joined automatically upon login", function () {
it("will be be opened and joined automatically upon login", mock.initConverse(function (converse) {
spyOn(converse_api.rooms, 'open');
var jid = 'theplay@conference.shakespeare.lit';
var model = converse.bookmarks.create({
......@@ -256,17 +262,18 @@
'nick': ''
});
expect(converse_api.rooms.open).toHaveBeenCalled();
});
}));
});
});
describe("Bookmarks", function () {
beforeEach(function () {
window.sessionStorage.clear();
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("can be pushed from the XMPP server", function () {
it("can be pushed from the XMPP server", mock.initConverse(function (converse) {
// TODO
/* The stored data is automatically pushed to all of the user's
* connected resources.
......@@ -311,9 +318,9 @@
* </event>
* </message>
*/
});
}));
it("can be retrieved from the XMPP server", function () {
it("can be retrieved from the XMPP server", mock.initConverse(function (converse) {
var sent_stanza, IQ_id,
sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -380,21 +387,21 @@
expect(converse.bookmarks.models.length).toBe(2);
expect(converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
expect(converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
});
}));
describe("The rooms panel", function () {
beforeEach(function () {
test_utils.openRoomsPanel();
converse.bookmarks.reset();
converse.chatboxviews.get('controlbox').$('#chatrooms dl.bookmarks').html('');
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("shows a list of bookmarks", function () {
it("shows a list of bookmarks", mock.initConverse(function (converse) {
var IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
converse.chatboxviews.get('controlbox').$('#chatrooms dl.bookmarks').html('');
converse.emit('chatBoxesFetched');
var stanza = $iq({'to': converse.connection.jid, 'type':'result', 'id':IQ_id})
.c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
......@@ -418,7 +425,7 @@
}).c('nick').t('JC').up().up();
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($('#chatrooms dl.bookmarks dd').length).toBe(3);
});
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"utils",
"mock",
"test_utils"
], factory);
} (this, function ($, _, utils, mock, test_utils) {
} (this, function (utils, mock, test_utils) {
"use strict";
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var $msg = converse_api.env.$msg;
var Strophe = converse_api.env.Strophe;
var moment = converse_api.env.moment;
return describe("Chatboxes", $.proxy(function(mock, test_utils) {
return describe("Chatboxes", function() {
describe("A Chatbox", function () {
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.removeControlBox();
test_utils.clearBrowserStorage();
test_utils.initConverse();
test_utils.createContacts('current');
test_utils.openControlBox();
test_utils.openContactsPanel();
});
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is created when you click on a roster item", function () {
it("is created when you click on a roster item", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
var i, $el, jid, chatboxview;
// openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created.
expect(this.chatboxes.length).toEqual(1);
spyOn(this.chatboxviews, 'trimChats');
expect(converse.chatboxes.length).toEqual(1);
spyOn(converse.chatboxviews, 'trimChats');
expect($("#conversejs .chatbox").length).toBe(1); // Controlbox is open
var online_contacts = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact').find('a.open-chat');
var online_contacts = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact').find('a.open-chat');
for (i=0; i<online_contacts.length; i++) {
$el = $(online_contacts[i]);
jid = $el.text().replace(/ /g,'.').toLowerCase() + '@localhost';
$el.click();
chatboxview = this.chatboxviews.get(jid);
expect(this.chatboxes.length).toEqual(i+2);
expect(this.chatboxviews.trimChats).toHaveBeenCalled();
chatboxview = converse.chatboxviews.get(jid);
expect(converse.chatboxes.length).toEqual(i+2);
expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
// Check that new chat boxes are created to the left of the
// controlbox (but to the right of all existing chat boxes)
expect($("#conversejs .chatbox").length).toBe(i+2);
expect($("#conversejs .chatbox")[1].id).toBe(chatboxview.model.get('box_id'));
}
}.bind(converse));
}));
it("can be trimmed to conserve space", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be trimmed to conserve space", function () {
var i, $el, jid, chatbox, chatboxview, trimmedview;
// openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created.
var trimmed_chatboxes = converse.minimized_chats;
expect(this.chatboxes.length).toEqual(1);
spyOn(this.chatboxviews, 'trimChats');
expect(converse.chatboxes.length).toEqual(1);
spyOn(converse.chatboxviews, 'trimChats');
spyOn(trimmed_chatboxes, 'addChat').andCallThrough();
spyOn(trimmed_chatboxes, 'removeChat').andCallThrough();
expect($("#conversejs .chatbox").length).toBe(1); // Controlbox is open
......@@ -64,47 +65,51 @@
// Test that they can be trimmed
runs(function () {
converse.rosterview.update(); // XXX: Hack to make sure $roster element is attaced.
}.bind(this));
});
waits(50);
runs(function () {
// Test that they can be maximized again
var online_contacts = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact').find('a.open-chat');
var online_contacts = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact').find('a.open-chat');
for (i=0; i<online_contacts.length; i++) {
$el = $(online_contacts[i]);
jid = $el.text().replace(/ /g,'.').toLowerCase() + '@localhost';
$el.click();
expect(this.chatboxviews.trimChats).toHaveBeenCalled();
expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
chatboxview = this.chatboxviews.get(jid);
chatboxview = converse.chatboxviews.get(jid);
spyOn(chatboxview, 'minimize').andCallThrough();
chatboxview.model.set({'minimized': true});
expect(trimmed_chatboxes.addChat).toHaveBeenCalled();
expect(chatboxview.minimize).toHaveBeenCalled();
trimmedview = trimmed_chatboxes.get(jid);
}
var key = this.chatboxviews.keys()[1];
var key = converse.chatboxviews.keys()[1];
trimmedview = trimmed_chatboxes.get(key);
chatbox = trimmedview.model;
spyOn(chatbox, 'maximize').andCallThrough();
spyOn(trimmedview, 'restore').andCallThrough();
trimmedview.delegateEvents();
trimmedview.$("a.restore-chat").click();
}.bind(this));
});
waits(250);
runs(function () {
expect(trimmedview.restore).toHaveBeenCalled();
expect(chatbox.maximize).toHaveBeenCalled();
expect(this.chatboxviews.trimChats).toHaveBeenCalled();
}.bind(this));
}.bind(converse));
expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
});
}));
it("is focused if its already open and you click on its corresponding roster item", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is focused if its already open and you click on its corresponding roster item", function () {
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
var $el, jid, chatboxview, chatbox;
// openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created.
expect(converse.chatboxes.length).toEqual(1);
chatbox = test_utils.openChatBoxFor(contact_jid);
chatbox = test_utils.openChatBoxFor(converse, contact_jid);
chatboxview = converse.chatboxviews.get(contact_jid);
spyOn(chatboxview, 'focus');
// Test that they can be trimmed
......@@ -119,21 +124,25 @@
expect(converse.chatboxes.length).toEqual(2);
expect(chatboxview.focus).toHaveBeenCalled();
});
});
}));
it("can be saved to, and retrieved from, browserStorage", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be saved to, and retrieved from, browserStorage", function () {
spyOn(converse, 'emit');
spyOn(this.chatboxviews, 'trimChats');
spyOn(converse.chatboxviews, 'trimChats');
runs(function () {
test_utils.openControlBox();
});
waits(250);
runs(function () {
test_utils.openChatBoxes(6);
expect(this.chatboxviews.trimChats).toHaveBeenCalled();
test_utils.openChatBoxes(converse, 6);
expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
// We instantiate a new ChatBoxes collection, which by default
// will be empty.
var newchatboxes = new this.ChatBoxes();
var newchatboxes = new converse.ChatBoxes();
expect(newchatboxes.length).toEqual(0);
// The chatboxes will then be fetched from browserStorage inside the
// onConnected method
......@@ -145,17 +154,21 @@
var new_attrs, old_attrs;
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(this.chatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.chatboxes.models, 'attributes'), attrs[i]);
expect(_.isEqual(new_attrs, old_attrs)).toEqual(true);
}
this.rosterview.render();
}.bind(converse));
}.bind(converse));
it("can be closed by clicking a DOM element with class 'close-chatbox-button'", function () {
var chatbox = test_utils.openChatBoxes(1)[0],
controlview = this.chatboxviews.get('controlbox'), // The controlbox is currently open
chatview = this.chatboxviews.get(chatbox.get('jid'));
converse.rosterview.render();
});
}));
it("can be closed by clicking a DOM element with class 'close-chatbox-button'", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
var chatbox = test_utils.openChatBoxes(converse, 1)[0],
controlview = converse.chatboxviews.get('controlbox'), // The controlbox is currently open
chatview = converse.chatboxviews.get(chatbox.get('jid'));
spyOn(chatview, 'close').andCallThrough();
spyOn(controlview, 'close').andCallThrough();
spyOn(converse, 'emit');
......@@ -180,12 +193,16 @@
expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
expect(converse.emit.callCount, 2);
});
}.bind(converse));
}));
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", function () {
var chatbox = test_utils.openChatBoxes(1)[0],
chatview = this.chatboxviews.get(chatbox.get('jid')),
trimmed_chatboxes = this.minimized_chats,
var chatbox = test_utils.openChatBoxes(converse, 1)[0],
chatview = converse.chatboxviews.get(chatbox.get('jid')),
trimmed_chatboxes = converse.minimized_chats,
trimmedview;
spyOn(chatview, 'minimize').andCallThrough();
spyOn(converse, 'emit');
......@@ -217,12 +234,16 @@
expect(chatview.$el.find('.toggle-chatbox-button').hasClass('icon-plus')).toBeFalsy();
expect(chatview.model.get('minimized')).toBeFalsy();
});
}.bind(converse));
}));
it("will be removed from browserStorage when closed", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will be removed from browserStorage when closed", function () {
spyOn(converse, 'emit');
spyOn(converse.chatboxviews, 'trimChats');
this.chatboxes.browserStorage._clear();
converse.chatboxes.browserStorage._clear();
runs(function () {
test_utils.closeControlBox();
});
......@@ -231,18 +252,18 @@
expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
expect(converse.chatboxes.length).toEqual(1);
expect(converse.chatboxes.pluck('id')).toEqual(['controlbox']);
test_utils.openChatBoxes(6);
test_utils.openChatBoxes(converse, 6);
expect(converse.chatboxviews.trimChats).toHaveBeenCalled();
expect(converse.chatboxes.length).toEqual(7);
expect(converse.emit).toHaveBeenCalledWith('chatBoxOpened', jasmine.any(Object));
test_utils.closeAllChatBoxes();
test_utils.closeAllChatBoxes(converse);
});
waits(50);
runs(function () {
expect(converse.chatboxes.length).toEqual(1);
expect(converse.chatboxes.pluck('id')).toEqual(['controlbox']);
expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
var newchatboxes = new this.ChatBoxes();
var newchatboxes = new converse.ChatBoxes();
expect(newchatboxes.length).toEqual(0);
expect(converse.chatboxes.pluck('id')).toEqual(['controlbox']);
// onConnected will fetch chatboxes in browserStorage, but
......@@ -251,28 +272,42 @@
newchatboxes.onConnected();
expect(newchatboxes.length).toEqual(1);
expect(newchatboxes.models[0].id).toBe("controlbox");
}.bind(converse));
}.bind(converse));
});
}));
describe("A chat toolbar", function () {
it("can be found on each chat box", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be found on each chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var chatbox = this.chatboxes.get(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var chatbox = converse.chatboxes.get(contact_jid);
var view = converse.chatboxviews.get(contact_jid);
expect(chatbox).toBeDefined();
expect(view).toBeDefined();
var $toolbar = view.$el.find('ul.chat-toolbar');
expect($toolbar.length).toBe(1);
expect($toolbar.children('li').length).toBe(3);
}.bind(converse));
}));
it("contains a button for inserting emoticons", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("contains a button for inserting emoticons", function () {
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost',
view, $toolbar, $textarea;
waits(300); // ChatBox.show() is debounced for 250ms
runs(function () {
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar');
$textarea = view.$el.find('textarea.chat-textarea');
......@@ -324,13 +359,17 @@
expect(view.$el.find('.toggle-smiley ul').is(':visible')).toBeFalsy();
expect($textarea.val()).toBe(':) <3 ');
});
});
}));
it("contains a button for starting an encrypted chat session", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("contains a button for starting an encrypted chat session", function () {
// TODO: More tests can be added here...
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var $toolbar = view.$el.find('ul.chat-toolbar');
expect($toolbar.children('li.toggle-otr').length).toBe(1);
// Register spies
......@@ -348,17 +387,21 @@
expect($menu.children('li').length).toBe(2);
});
}.bind(converse));
}));
it("can contain a button for starting a call", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can contain a button for starting a call", function () {
var view, callButton, $toolbar;
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(converse, 'emit');
// First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons"
converse.visible_toolbar_buttons.call = false;
test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar');
callButton = $toolbar.find('.toggle-call');
expect(callButton.length).toBe(0);
......@@ -366,24 +409,28 @@
// Now check that it's shown if enabled and that it emits
// callButtonClicked
converse.visible_toolbar_buttons.call = true; // enable the button
test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar');
callButton = $toolbar.find('.toggle-call');
expect(callButton.length).toBe(1);
callButton.click();
expect(converse.emit).toHaveBeenCalledWith('callButtonClicked', jasmine.any(Object));
}.bind(converse));
}));
it("can contain a button for clearing messages", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can contain a button for clearing messages", function () {
var view, clearButton, $toolbar;
var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
// First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons"
converse.visible_toolbar_buttons.clear = false;
test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid);
view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
view = converse.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar');
clearButton = $toolbar.find('.toggle-clear');
expect(clearButton.length).toBe(0);
......@@ -391,8 +438,8 @@
// Now check that it's shown if enabled and that it calls
// clearMessages
converse.visible_toolbar_buttons.clear = true; // enable the button
test_utils.openChatBoxFor(contact_jid);
view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
$toolbar = view.$el.find('ul.chat-toolbar');
clearButton = $toolbar.find('.toggle-clear');
expect(clearButton.length).toBe(1);
......@@ -400,48 +447,46 @@
view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
clearButton.click();
expect(view.clearMessages).toHaveBeenCalled();
}.bind(converse));
}.bind(converse));
}));
});
describe("A Chat Message", function () {
beforeEach(function () {
test_utils.closeAllChatBoxes();
test_utils.removeControlBox();
converse.roster.browserStorage._clear();
test_utils.initConverse();
test_utils.createContacts('current');
test_utils.openControlBox();
test_utils.openContactsPanel();
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
describe("when received from someone else", function () {
it("can be received which will open a chatbox and be displayed inside it", function () {
it("can be received which will open a chatbox and be displayed inside it", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
spyOn(converse, 'emit');
var message = 'This is a received message';
var message = 'converse is a received message';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
// We don't already have an open chatbox for this user
expect(this.chatboxes.get(sender_jid)).not.toBeDefined();
expect(converse.chatboxes.get(sender_jid)).not.toBeDefined();
runs(function () {
// onMessage is a handler for received XMPP messages
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
}.bind(converse));
});
waits(50);
runs(function () {
// Check that the chatbox and its view now exist
var chatbox = this.chatboxes.get(sender_jid);
var chatboxview = this.chatboxviews.get(sender_jid);
var chatbox = converse.chatboxes.get(sender_jid);
var chatboxview = converse.chatboxviews.get(sender_jid);
expect(chatbox).toBeDefined();
expect(chatboxview).toBeDefined();
// Check that the message was received and check the message parameters
......@@ -457,11 +502,21 @@
expect(msg_txt).toEqual(message);
var sender_txt = $chat_content.find('span.chat-msg-them').text();
expect(sender_txt.match(/^[0-9][0-9]:[0-9][0-9] /)).toBeTruthy();
}.bind(converse));
}.bind(converse));
});
}));
describe("and for which then an error message is received from the server", function () {
it("will have the error message displayed after itself", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("will have the error message displayed after itself", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
// TODO: what could still be done for error
// messages... if the <error> element has type
// "cancel", then we know the messages wasn't sent,
......@@ -553,13 +608,17 @@
.t('Server-to-server connection failed: Connecting failed: connection timeout');
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').length).toEqual(1);
});
}));
});
it("will cause the chat area to be scrolled down only if it was at the bottom already", function () {
it("will cause the chat area to be scrolled down only if it was at the bottom already", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
var message = 'This message is received while the chat area is scrolled up';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(sender_jid);
test_utils.openChatBoxFor(converse, sender_jid);
var chatboxview = converse.chatboxviews.get(sender_jid);
spyOn(chatboxview, 'scrollDown').andCallThrough();
runs(function () {
......@@ -606,9 +665,13 @@
runs(function () {
expect(chatboxview.$('.new-msgs-indicator').is(':visible')).toBeFalsy();
});
});
}));
it("is ignored if it's intended for a different resource and filter_by_resource is set to true", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is ignored if it's intended for a different resource and filter_by_resource is set to true", function () {
// Send a message from a different resource
var message, sender_jid, msg;
spyOn(converse, 'log');
......@@ -652,16 +715,20 @@
var msg_txt = $chat_content.find('.chat-message').find('.chat-msg-content').text();
expect(msg_txt).toEqual(message);
});
});
}));
});
describe("when sent by the current user", function () {
it("will always cause the chat area to be scrolled down", function () {
it("will always cause the chat area to be scrolled down", mock.initConverse(function (converse) {
// TODO
});
}));
});
it("is ignored if it's a malformed headline message", function () {
it("is ignored if it's a malformed headline message", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
/* Ideally we wouldn't have to filter out headline
* messages, but Prosody gives them the wrong 'type' :(
*/
......@@ -686,9 +753,13 @@
converse.log.restore();
converse.chatboxes.getChatBox.restore();
utils.isHeadlineMessage.restore();
});
}));
it("can be a carbon message, as defined in XEP-0280", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be a carbon message, as defined in XEP-0280", function () {
// Send a message from a different resource
spyOn(converse, 'log');
var msgtext = 'This is a carbon message';
......@@ -727,9 +798,13 @@
expect(msg_txt).toEqual(msgtext);
var sender_txt = $chat_content.find('span.chat-msg-them').text();
expect(sender_txt.match(/^[0-9][0-9]:[0-9][0-9] /)).toBeTruthy();
});
}));
it("can be a carbon message that this user sent from a different client, as defined in XEP-0280", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be a carbon message that this user sent from a different client, as defined in XEP-0280", function () {
// Send a message from a different resource
spyOn(converse, 'log');
var msgtext = 'This is a sent carbon message';
......@@ -766,14 +841,18 @@
var $chat_content = chatboxview.$el.find('.chat-content');
var msg_txt = $chat_content.find('.chat-message').find('.chat-msg-content').text();
expect(msg_txt).toEqual(msgtext);
});
}));
it("received for a minimized chat box will increment a counter on its header", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("received for a minimized chat box will increment a counter on its header", function () {
var contact_name = mock.cur_names[0];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
spyOn(this, 'emit').andCallThrough();
test_utils.openChatBoxFor(contact_jid);
var chatview = this.chatboxviews.get(contact_jid);
spyOn(converse, 'emit').andCallThrough();
test_utils.openChatBoxFor(converse, contact_jid);
var chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.$el.is(':visible')).toBeTruthy();
expect(chatview.model.get('minimized')).toBeFalsy();
chatview.$el.find('.toggle-chatbox-button').click();
......@@ -782,24 +861,24 @@
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
this.chatboxes.onMessage(msg);
expect(this.emit).toHaveBeenCalledWith('message', msg);
var trimmed_chatboxes = this.minimized_chats;
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
var trimmed_chatboxes = converse.minimized_chats;
var trimmedview = trimmed_chatboxes.get(contact_jid);
var $count = trimmedview.$el.find('.chat-head-message-count');
expect(chatview.$el.is(':visible')).toBeFalsy();
expect(trimmedview.model.get('minimized')).toBeTruthy();
expect($count.is(':visible')).toBeTruthy();
expect($count.html()).toBe('1');
this.chatboxes.onMessage(
converse.chatboxes.onMessage(
$msg({
from: mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('This message is also sent to a minimized chatbox').up()
......@@ -812,19 +891,23 @@
expect($count.html()).toBe('2');
trimmedview.$el.find('.restore-chat').click();
expect(trimmed_chatboxes.keys().length).toBe(0);
}.bind(converse));
}));
it("will indicate when it has a time difference of more than a day between it and its predecessor", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will indicate when it has a time difference of more than a day between it and its predecessor", function () {
spyOn(converse, 'emit');
var contact_name = mock.cur_names[1];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.clearChatBoxMessages(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
test_utils.clearChatBoxMessages(converse, contact_jid);
var one_day_ago = moment();
one_day_ago.subtract('days', 1);
var message = 'This is a day old message';
var chatbox = this.chatboxes.get(contact_jid);
var chatboxview = this.chatboxviews.get(contact_jid);
var chatbox = converse.chatboxes.get(contact_jid);
var chatboxview = converse.chatboxviews.get(contact_jid);
var $chat_content = chatboxview.$el.find('.chat-content');
var msg_obj;
var msg_txt;
......@@ -832,13 +915,13 @@
var msg = $msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: one_day_ago.unix()
}).c('body').t(message).up()
.c('delay', { xmlns:'urn:xmpp:delay', from: 'localhost', stamp: one_day_ago.format() })
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
expect(chatbox.messages.length).toEqual(1);
msg_obj = chatbox.messages.models[0];
......@@ -860,12 +943,12 @@
message = 'This is a current message';
msg = $msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: new Date().getTime()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
// Check that there is a <time> element, with the required
// props.
......@@ -888,14 +971,18 @@
expect(msg_txt).toEqual(message);
sender_txt = $chat_content.find('span.chat-msg-them').last().text();
expect(sender_txt.match(/^[0-9][0-9]:[0-9][0-9] /)).toBeTruthy();
}.bind(converse));
}));
it("can be sent from a chatbox, and will appear inside it", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can be sent from a chatbox, and will appear inside it", function () {
spyOn(converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
expect(converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
var view = this.chatboxviews.get(contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var message = 'This message is sent from this chatbox';
spyOn(view, 'sendMessage').andCallThrough();
test_utils.sendMessage(view, message);
......@@ -903,12 +990,16 @@
expect(view.model.messages.length, 2);
expect(converse.emit.mostRecentCall.args, ['messageSend', message]);
expect(view.$el.find('.chat-content').find('.chat-message').last().find('.chat-msg-content').text()).toEqual(message);
}.bind(converse));
}));
it("is sanitized to prevent Javascript injection attacks", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is sanitized to prevent Javascript injection attacks", function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var message = '<p>This message contains <em>some</em> <b>markup</b></p>';
spyOn(view, 'sendMessage').andCallThrough();
test_utils.sendMessage(view, message);
......@@ -916,12 +1007,16 @@
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-msg-content');
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;');
}.bind(converse));
}));
it("should display emoticons correctly", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("should display emoticons correctly", function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var messages = [':)', ';)', ':D', ':P', '8)', '>:)', ':S', ':\\', '>:(', ':(', ':O', '(^.^)b', '<3'];
var emoticons = [
'<span class="emoticon icon-smiley"></span>', '<span class="emoticon icon-wink"></span>',
......@@ -940,11 +1035,15 @@
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-msg-content');
expect(msg.html()).toEqual(emoticons[i]);
}
}.bind(converse));
}));
it("can contain hyperlinks, which will be clickable", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("can contain hyperlinks, which will be clickable", function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var message = 'This message contains a hyperlink: www.opkode.com';
spyOn(view, 'sendMessage').andCallThrough();
......@@ -958,12 +1057,16 @@
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>');
});
});
}));
it("will have properly escaped URLs", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will have properly escaped URLs", function () {
var message, msg;
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
spyOn(view, 'sendMessage').andCallThrough();
runs(function () {
......@@ -1007,9 +1110,13 @@
expect(msg.text()).toEqual(message);
expect(msg.html()).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">https://en.wikipedia.org/wiki/Ender%27s_Game</a>');
});
});
}));
it("will render images from their URLs", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will render images from their URLs", function () {
if (/PhantomJS/.test(window.navigator.userAgent)) {
// Doesn't work when running tests in PhantomJS, since
// the page is loaded via file:///
......@@ -1017,7 +1124,7 @@
}
var message = document.URL.split(window.location.pathname)[0] + "/logo/conversejs.svg";
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
spyOn(view, 'sendMessage').andCallThrough();
runs(function () {
......@@ -1029,13 +1136,22 @@
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-msg-content');
expect(msg.html()).toEqual('<img src="'+message+'" class="chat-image">');
});
});
}));
}.bind(converse));
});
describe("A Chat Status Notification", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("does not open automatically if a chat state notification is received", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("does not open automatically if a chat state notification is received", function () {
spyOn(converse, 'emit');
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// <composing> state
......@@ -1047,15 +1163,25 @@
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
});
}));
describe("An active notification", function () {
it("is sent when the user opens a chat box", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is sent when the user opens a chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
waits(300); // ChatBox.show() is debounced for 250ms
runs(function () {
spyOn(converse.connection, 'send');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active');
expect(converse.connection.send).toHaveBeenCalled();
......@@ -1066,12 +1192,16 @@
expect($stanza.children().get(1).tagName).toBe('no-store');
expect($stanza.children().get(2).tagName).toBe('no-permanent-store');
});
});
}));
it("is sent when the user maximizes a minimized a chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is sent when the user maximizes a minimized a chat box", function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
view.minimize();
expect(view.model.get('chat_state')).toBe('inactive');
spyOn(converse.connection, 'send');
......@@ -1084,15 +1214,25 @@
expect($stanza.children().get(0).tagName).toBe('active');
expect($stanza.children().get(1).tagName).toBe('no-store');
expect($stanza.children().get(2).tagName).toBe('no-permanent-store');
}.bind(converse));
}.bind(converse));
}));
});
describe("A composing notification", function () {
it("is sent as soon as the user starts typing a message which is not a command", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is sent as soon as the user starts typing a message which is not a command", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
waits(300); // ChatBox.show() is debounced for 250ms
runs(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active');
spyOn(converse.connection, 'send');
......@@ -1116,9 +1256,13 @@
expect(view.model.get('chat_state')).toBe('composing');
expect(converse.emit.callCount, 1);
});
});
}));
it("will be shown if received", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will be shown if received", function () {
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
spyOn(converse, 'emit');
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
......@@ -1126,28 +1270,38 @@
// <composing> state
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
var chatboxview = this.chatboxviews.get(sender_jid);
var chatboxview = converse.chatboxviews.get(sender_jid);
expect(chatboxview).toBeDefined();
// Check that the notification appears inside the chatbox in the DOM
var $events = chatboxview.$el.find('.chat-event');
expect($events.text()).toEqual(mock.cur_names[1] + ' is typing');
}.bind(converse));
}.bind(converse));
}));
});
describe("A paused notification", function () {
it("is sent if the user has stopped typing since 30 seconds", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is sent if the user has stopped typing since 30 seconds", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
var view, contact_jid;
converse.TIMEOUTS.PAUSED = 200; // Make the timeout shorter so that we can test
waits(300); // ChatBox.show() is debounced for 250ms
runs(function () {
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
view = converse.chatboxviews.get(contact_jid);
spyOn(converse.connection, 'send');
spyOn(view, 'setChatState').andCallThrough();
......@@ -1193,9 +1347,13 @@
runs(function () {
expect(view.model.get('chat_state')).toBe('composing');
});
});
}));
it("will be shown if received", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will be shown if received", function () {
// TODO: only show paused state if the previous state was composing
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
spyOn(converse, 'emit');
......@@ -1203,26 +1361,36 @@
// <paused> state
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
var chatboxview = this.chatboxviews.get(sender_jid);
var chatboxview = converse.chatboxviews.get(sender_jid);
var $events = chatboxview.$el.find('.chat-event');
expect($events.text()).toEqual(mock.cur_names[1] + ' has stopped typing');
}.bind(converse));
}.bind(converse));
}));
});
describe("An inactive notifciation", function () {
it("is sent if the user has stopped typing since 2 minutes", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is sent if the user has stopped typing since 2 minutes", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
// Make the timeouts shorter so that we can test
this.TIMEOUTS.PAUSED = 200;
this.TIMEOUTS.INACTIVE = 200;
converse.TIMEOUTS.PAUSED = 200;
converse.TIMEOUTS.INACTIVE = 200;
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
runs(function () {
expect(view.model.get('chat_state')).toBe('active');
view.keyPressed({
......@@ -1248,12 +1416,16 @@
expect($stanza.children().get(2).tagName).toBe('no-permanent-store');
});
}.bind(converse));
}));
it("is sent when the user a minimizes a chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is sent when the user a minimizes a chat box", function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
spyOn(converse.connection, 'send');
view.minimize();
expect(view.model.get('chat_state')).toBe('inactive');
......@@ -1261,13 +1433,17 @@
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.attr('to')).toBe(contact_jid);
expect($stanza.children().get(0).tagName).toBe('inactive');
}.bind(converse));
}));
it("is sent if the user closes a chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is sent if the user closes a chat box", function () {
waits(300); // ChatBox.show() is debounced for 250ms
runs(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active');
spyOn(converse.connection, 'send');
......@@ -1281,67 +1457,81 @@
expect($stanza.children().get(1).tagName).toBe('no-store');
expect($stanza.children().get(2).tagName).toBe('no-permanent-store');
});
});
}));
it("will clear any other chat status notifications if its received", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("will clear any other chat status notifications if its received", function () {
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
spyOn(converse, 'emit');
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(sender_jid);
var view = this.chatboxviews.get(sender_jid);
test_utils.openChatBoxFor(converse, sender_jid);
var view = converse.chatboxviews.get(sender_jid);
expect(view.$el.find('.chat-event').length).toBe(0);
view.showStatusNotification(sender_jid+' '+'is typing');
expect(view.$el.find('.chat-event').length).toBe(1);
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('inactive', {'xmlns': Strophe.NS.CHATSTATES}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
expect(view.$el.find('.chat-event').length).toBe(0);
}.bind(converse));
}));
}.bind(converse));
});
describe("A gone notifciation", function () {
it("will be shown if received", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("will be shown if received", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
spyOn(converse, 'emit');
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// <paused> state
var msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('gone', {'xmlns': Strophe.NS.CHATSTATES}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
var chatboxview = this.chatboxviews.get(sender_jid);
var chatboxview = converse.chatboxviews.get(sender_jid);
var $events = chatboxview.$el.find('.chat-event');
expect($events.text()).toEqual(mock.cur_names[1] + ' has gone away');
}.bind(converse));
}.bind(converse));
}.bind(converse));
}.bind(converse));
}));
});
});
});
describe("Special Messages", function () {
beforeEach(function () {
test_utils.closeAllChatBoxes();
test_utils.removeControlBox();
converse.roster.browserStorage._clear();
test_utils.initConverse();
test_utils.createContacts('current');
test_utils.openControlBox();
test_utils.openContactsPanel();
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("'/clear' can be used to clear messages in a conversation", function () {
it("'/clear' can be used to clear messages in a conversation", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
spyOn(converse, 'emit');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
var view = this.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var view = converse.chatboxviews.get(contact_jid);
var message = 'This message is another sent from this chatbox';
// Lets make sure there is at least one message already
// (e.g for when this test is run on its own).
......@@ -1364,44 +1554,47 @@
expect(view.model.messages.browserStorage.records.length, 0); // And also from browserStorage
expect(converse.emit.callCount, 1);
expect(converse.emit.mostRecentCall.args, ['messageSend', message]);
}.bind(converse));
}.bind(converse));
}));
});
describe("A Message Counter", function () {
beforeEach(function () {
converse.clearMsgCounter();
test_utils.closeAllChatBoxes();
test_utils.removeControlBox();
converse.roster.browserStorage._clear();
test_utils.initConverse();
test_utils.createContacts('current');
test_utils.openControlBox();
test_utils.openContactsPanel();
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is incremented when the message is received and the window is not focused", function () {
it("is incremented when the message is received and the window is not focused", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
spyOn(converse, 'emit');
expect(this.msg_counter).toBe(0);
expect(converse.msg_counter).toBe(0);
spyOn(converse, 'incrementMsgCounter').andCallThrough();
var previous_state = converse.windowState;
var message = 'This message will increment the message counter';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
converse.windowState = 'hidden';
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.incrementMsgCounter).toHaveBeenCalled();
expect(this.msg_counter).toBe(1);
expect(converse.msg_counter).toBe(1);
expect(converse.emit).toHaveBeenCalledWith('message', msg);
converse.windowSate = previous_state;
}.bind(converse));
}));
it("is cleared when the window is focused", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is cleared when the window is focused", function () {
converse.windowState = 'hidden';
spyOn(converse, 'clearMsgCounter').andCallThrough();
runs(function () {
......@@ -1412,25 +1605,29 @@
runs(function () {
expect(converse.clearMsgCounter).toHaveBeenCalled();
});
}.bind(converse));
}));
it("is not incremented when the message is received and the window is focused", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
it("is not incremented when the message is received and the window is focused", function () {
expect(this.msg_counter).toBe(0);
expect(converse.msg_counter).toBe(0);
spyOn(converse, 'incrementMsgCounter').andCallThrough();
converse.saveWindowState(null, 'focus');
var message = 'This message will not increment the message counter';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msg = $msg({
from: sender_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
this.chatboxes.onMessage(msg);
converse.chatboxes.onMessage(msg);
expect(converse.incrementMsgCounter).not.toHaveBeenCalled();
expect(this.msg_counter).toBe(0);
}.bind(converse));
}.bind(converse));
}, converse, mock, test_utils));
expect(converse.msg_counter).toBe(0);
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils",
"utils"
], function ($, _, mock, test_utils, utils) {
return factory($, _, mock, test_utils, utils);
}
);
} (this, function ($, _, mock, test_utils, utils) {
define(["mock", "test_utils", "utils" ], factory);
} (this, function (mock, test_utils, utils) {
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var $pres = converse_api.env.$pres;
var $iq = converse_api.env.$iq;
var $msg = converse_api.env.$msg;
var Strophe = converse_api.env.Strophe;
return describe("ChatRooms", function (mock, test_utils) {
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.clearBrowserStorage();
});
});
return describe("ChatRooms", function () {
describe("The \"rooms\" API", function () {
beforeEach(function () {
test_utils.closeAllChatBoxes();
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
converse.rosterview.model.reset();
test_utils.createContacts('current');
});
it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", function () {
it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
runs(function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
test_utils.openChatRoom('leisure', 'localhost', 'dummy');
test_utils.openChatRoom('news', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'leisure', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'news', 'localhost', 'dummy');
expect(converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
expect(converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
expect(converse.chatboxviews.get('news@localhost').$el.is(':visible')).toBeTruthy();
......@@ -52,8 +37,8 @@
expect(converse.chatboxviews.get('leisure@localhost')).toBeUndefined();
expect(converse.chatboxviews.get('news@localhost')).toBeUndefined();
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
test_utils.openChatRoom('leisure', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'leisure', 'localhost', 'dummy');
expect(converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
expect(converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
});
......@@ -63,12 +48,13 @@
expect(converse.chatboxviews.get('lounge@localhost')).toBeUndefined();
expect(converse.chatboxviews.get('leisure@localhost')).toBeUndefined();
});
});
}));
it("has a method 'get' which returns a wrapped chat room (if it exists)", function () {
it("has a method 'get' which returns a wrapped chat room (if it exists)", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
waits('300'); // ChatBox.show() is debounced for 250ms
runs(function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var jid = 'lounge@localhost';
var room = converse_api.rooms.get(jid);
expect(room instanceof Object).toBeTruthy();
......@@ -80,7 +66,7 @@
waits('300'); // ChatBox.show() is debounced for 250ms
runs(function () {
// Test with mixed case
test_utils.openChatRoom('Leisure', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'Leisure', 'localhost', 'dummy');
var jid = 'Leisure@localhost';
var room = converse_api.rooms.get(jid);
expect(room instanceof Object).toBeTruthy();
......@@ -107,9 +93,10 @@
room = converse_api.rooms.get(jid);
expect(typeof room === 'undefined').toBeTruthy();
});
});
}));
it("has a method 'open' which opens and returns a wrapped chat box", function () {
it("has a method 'open' which opens and returns a wrapped chat box", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
var chatroomview;
var jid = 'lounge@localhost';
var room = converse_api.rooms.open(jid);
......@@ -151,27 +138,25 @@
expect(chatroomview.$el.is(':visible')).toBeTruthy();
chatroomview.close();
});
});
}));
});
describe("A Chat Room", function () {
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.clearBrowserStorage();
});
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can have spaces and special characters in its name", function () {
test_utils.openChatRoom('lounge & leisure', 'localhost', 'dummy');
it("can have spaces and special characters in its name", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge & leisure', 'localhost', 'dummy');
var view = converse.chatboxviews.get(
Strophe.escapeNode('lounge & leisure')+'@localhost');
expect(view instanceof converse.ChatRoomView).toBe(true);
});
}));
it("shows users currently present in the room", function () {
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
it("shows users currently present in the room", mock.initConverse(function (converse) {
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var name;
var view = converse.chatboxviews.get('lounge@localhost'),
$occupants = view.$('.occupant-list');
......@@ -215,10 +200,10 @@
converse.connection._dataRecv(test_utils.createRequest(presence));
expect($occupants.find('li').length).toBe(i+1);
}
});
}));
it("indicates moderators by means of a special css class and tooltip", function () {
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
it("indicates moderators by means of a special css class and tooltip", mock.initConverse(function (converse) {
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
var presence = $pres({
......@@ -239,9 +224,9 @@
expect($(occupant).last().text()).toBe("moderatorman");
expect($(occupant).last().attr('class').indexOf('moderator')).not.toBe(-1);
expect($(occupant).last().attr('title')).toBe('This user is a moderator. Click to mention this user in your message.');
});
}));
it("will use the user's reserved nickname, if it exists", function () {
it("will use the user's reserved nickname, if it exists", mock.initConverse(function (converse) {
var sent_IQ, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -249,7 +234,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'join').andCallThrough();
......@@ -310,19 +295,19 @@
converse.connection._dataRecv(test_utils.createRequest(presence));
var info_text = view.$el.find('.chat-content .chat-info').text();
expect(info_text).toBe('Your nickname has been automatically set to: thirdwitch');
});
}));
it("allows the user to invite their roster contacts to enter the chat room", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("allows the user to invite their roster contacts to enter the chat room", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
spyOn(converse, 'emit');
spyOn(window, 'prompt').andCallFake(function () {
return null;
});
var $input;
var view = this.chatboxviews.get('lounge@localhost');
var view = converse.chatboxviews.get('lounge@localhost');
view.$el.find('.chat-area').remove();
view.renderChatArea(); // Will init the widget
test_utils.createContacts('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
$input = view.$el.find('input.invited-contact.tt-input');
var $hint = view.$el.find('input.invited-contact.tt-hint');
runs (function () {
......@@ -340,15 +325,15 @@
$sugg.trigger('click');
expect(window.prompt).toHaveBeenCalled();
});
}.bind(converse));
}));
it("can be joined automatically, based upon a received invite", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("can be joined automatically, based upon a received invite", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
spyOn(window, 'confirm').andCallFake(function () {
return true;
});
test_utils.createContacts('current'); // We need roster contacts, who can invite us
var view = this.chatboxviews.get('lounge@localhost');
test_utils.createContacts(converse, 'current'); // We need roster contacts, who can invite us
var view = converse.chatboxviews.get('lounge@localhost');
view.close();
var name = mock.cur_names[0];
var from_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
......@@ -370,12 +355,12 @@
expect(converse.chatboxes.models.length).toBe(2);
expect(converse.chatboxes.models[0].id).toBe('controlbox');
expect(converse.chatboxes.models[1].id).toBe(room_jid);
}.bind(converse));
}));
it("shows received groupchat messages", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("shows received groupchat messages", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
spyOn(converse, 'emit');
var view = this.chatboxviews.get('lounge@localhost');
var view = converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var nick = mock.chatroom_names[0];
var text = 'This is a received message';
......@@ -390,10 +375,10 @@
expect($chat_content.find('.chat-message').length).toBe(1);
expect($chat_content.find('.chat-msg-content').text()).toBe(text);
expect(converse.emit).toHaveBeenCalledWith('message', message.nodeTree);
}.bind(converse));
}));
it("shows sent groupchat messages", function () {
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
it("shows sent groupchat messages", mock.initConverse(function (converse) {
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
spyOn(converse, 'emit');
var view = converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
......@@ -417,11 +402,11 @@
expect($chat_content.find('.chat-msg-content').last().text()).toBe(text);
// We don't emit an event if it's our own message
expect(converse.emit.callCount, 1);
});
}));
it("will cause the chat area to be scrolled down only if it was at the bottom already", function () {
it("will cause the chat area to be scrolled down only if it was at the bottom already", mock.initConverse(function (converse) {
var message = 'This message is received while the chat area is scrolled up';
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'scrollDown').andCallThrough();
runs(function () {
......@@ -461,10 +446,10 @@
expect(msg_txt).toEqual(message);
expect(view.$content.scrollTop()).toBe(0);
});
});
}));
it("shows received chatroom subject messages", function () {
test_utils.openAndEnterChatRoom('jdev', 'conference.jabber.org', 'jc');
it("shows received chatroom subject messages", mock.initConverse(function (converse) {
test_utils.openAndEnterChatRoom(converse, 'jdev', 'conference.jabber.org', 'jc');
var text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
var stanza = Strophe.xmlHtmlNode(
......@@ -478,9 +463,9 @@
var $chat_content = view.$el.find('.chat-content');
expect($chat_content.find('.chat-info').length).toBe(1);
expect($chat_content.find('.chat-info').text()).toBe('Topic set by ralphm to: '+text);
});
}));
it("informs users if their nicknames has been changed.", function () {
it("informs users if their nicknames has been changed.", mock.initConverse(function (converse) {
/* The service then sends two presence stanzas to the full JID
* of each occupant (including the occupant who is changing his
* or her room nickname), one of type "unavailable" for the old
......@@ -517,7 +502,7 @@
* </presence>
*/
var __ = utils.__.bind(converse);
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'oldnick');
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'oldnick');
var view = converse.chatboxviews.get('lounge@localhost');
var $chat_content = view.$el.find('.chat-content');
......@@ -588,9 +573,9 @@
$occupants = view.$('.occupant-list');
expect($occupants.children().length).toBe(1);
expect($occupants.children().first(0).text()).toBe("newnick");
});
}));
it("informs users if they have been kicked out of the chat room", function () {
it("informs users if they have been kicked out of the chat room", mock.initConverse(function (converse) {
/* <presence
* from='harfleur@chat.shakespeare.lit/pistol'
* to='pistol@shakespeare.lit/harfleur'
......@@ -604,7 +589,7 @@
* </x>
* </presence>
*/
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var presence = $pres().attrs({
from:'lounge@localhost/dummy',
to:'dummy@localhost/pda',
......@@ -621,20 +606,20 @@
.up()
.c('status').attrs({code:'307'}).nodeTree;
var view = this.chatboxviews.get('lounge@localhost');
var view = converse.chatboxviews.get('lounge@localhost');
view.onChatRoomPresence(presence);
expect(view.$('.chat-area').is(':visible')).toBeFalsy();
expect(view.$('.occupants').is(':visible')).toBeFalsy();
var $chat_body = view.$('.chatroom-body');
expect($chat_body.html().trim().indexOf('<p>You have been kicked from this room</p><p>The reason given is: "Avaunt, you cullion!"</p>')).not.toBe(-1);
}.bind(converse));
}));
it("can be saved to, and retrieved from, browserStorage", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("can be saved to, and retrieved from, browserStorage", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
// We instantiate a new ChatBoxes collection, which by default
// will be empty.
test_utils.openControlBox();
var newchatboxes = new this.ChatBoxes();
var newchatboxes = new converse.ChatBoxes();
expect(newchatboxes.length).toEqual(0);
// The chatboxes will then be fetched from browserStorage inside the
// onConnected method
......@@ -646,20 +631,20 @@
var new_attrs, old_attrs;
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(this.chatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.chatboxes.models, 'attributes'), attrs[i]);
// FIXME: should have have to sort here? Order must
// probably be the same...
// This should be fixed once the controlbox always opens
// only on the right.
expect(_.isEqual(new_attrs.sort(), old_attrs.sort())).toEqual(true);
}
this.rosterview.render();
}.bind(converse));
converse.rosterview.render();
}));
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
var view = this.chatboxviews.get('lounge@localhost'),
trimmed_chatboxes = this.minimized_chats;
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost'),
trimmed_chatboxes = converse.minimized_chats;
spyOn(view, 'minimize').andCallThrough();
spyOn(view, 'maximize').andCallThrough();
spyOn(converse, 'emit');
......@@ -686,11 +671,10 @@
expect(view.model.get('minimized')).toBeFalsy();
expect(converse.emit.callCount, 3);
});
}.bind(converse));
}));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'close').andCallThrough();
spyOn(converse, 'emit');
......@@ -705,20 +689,19 @@
expect(view.leave).toHaveBeenCalled();
expect(converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
});
});
}.bind(converse));
}));
});
describe("Each chat room can take special commands", function () {
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.clearBrowserStorage();
});
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("to clear messages", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("to clear messages", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'onMessageSubmitted').andCallThrough();
spyOn(view, 'clearChatRoomMessages');
......@@ -727,10 +710,10 @@
expect(view.onMessageSubmitted).toHaveBeenCalled();
expect(view.clearChatRoomMessages).toHaveBeenCalled();
});
}));
it("to ban a user", function () {
test_utils.openChatRoom('lounge', 'localhost', 'dummy');
it("to ban a user", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'onMessageSubmitted').andCallThrough();
spyOn(view, 'setAffiliation').andCallThrough();
......@@ -754,13 +737,18 @@
expect(view.validateRoleChangeCommand.callCount).toBe(2);
expect(view.showStatusNotification.callCount).toBe(1);
expect(view.setAffiliation).toHaveBeenCalled();
});
}.bind(converse));
}));
});
describe("When attempting to enter a chatroom", function () {
beforeEach(function () {
var roomspanel = this.chatboxviews.get('controlbox').roomspanel;
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
var submitRoomForm = function (converse) {
var roomspanel = converse.chatboxviews.get('controlbox').roomspanel;
var $input = roomspanel.$el.find('input.new-chatroom-name');
var $nick = roomspanel.$el.find('input.new-chatroom-nick');
var $server = roomspanel.$el.find('input.new-chatroom-server');
......@@ -768,14 +756,10 @@
$nick.val('dummy');
$server.val('muc.localhost');
roomspanel.$el.find('form').submit();
}.bind(converse));
};
afterEach(function () {
var view = this.chatboxviews.get('problematic@muc.localhost');
view.close();
}.bind(converse));
it("will show an error message if the room requires a password", function () {
it("will show an error message if the room requires a password", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -785,7 +769,7 @@
.c('error').attrs({by:'lounge@localhost', type:'auth'})
.c('not-authorized').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
var view = this.chatboxviews.get('problematic@muc.localhost');
var view = converse.chatboxviews.get('problematic@muc.localhost');
spyOn(view, 'renderPasswordForm').andCallThrough();
runs(function () {
view.onChatRoomPresence(presence);
......@@ -797,9 +781,10 @@
expect($chat_body.find('form.chatroom-form').length).toBe(1);
expect($chat_body.find('legend').text()).toBe('This chatroom requires a password');
});
}.bind(converse));
}));
it("will show an error message if the room is members-only and the user not included", function () {
it("will show an error message if the room is members-only and the user not included", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -812,9 +797,10 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe('You are not on the member list of this room');
});
}));
it("will show an error message if the user has been banned", function () {
it("will show an error message if the user has been banned", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -827,9 +813,10 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe('You have been banned from this room');
});
}));
it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false", function () {
it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -842,9 +829,9 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body form.chatroom-form label:first').text()).toBe('Please choose your nickname');
});
}));
it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true", function () {
it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true", mock.initConverse(function (converse) {
/*
<presence
from='coven@chat.shakespeare.lit/thirdwitch'
......@@ -857,6 +844,7 @@
</error>
</presence>
*/
submitRoomForm(converse);
converse.muc_nickname_from_jid = true;
var attrs = {
......@@ -895,9 +883,10 @@
.c('conflict').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
view.onChatRoomPresence(presence);
expect(view.join).toHaveBeenCalledWith('dummy-4');
});
}));
it("will show an error message if the user is not allowed to have created the room", function () {
it("will show an error message if the user is not allowed to have created the room", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -906,13 +895,14 @@
.c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
.c('error').attrs({by:'lounge@localhost', type:'cancel'})
.c('not-allowed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
var view = this.chatboxviews.get('problematic@muc.localhost');
var view = converse.chatboxviews.get('problematic@muc.localhost');
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe('You are not allowed to create new rooms');
}.bind(converse));
}));
it("will show an error message if the user's nickname doesn't conform to room policy", function () {
it("will show an error message if the user's nickname doesn't conform to room policy", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -925,9 +915,10 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe("Your nickname doesn't conform to this room's policies");
});
}));
it("will show an error message if the room doesn't yet exist", function () {
it("will show an error message if the room doesn't yet exist", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -940,9 +931,10 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe("This room does not (yet) exist");
});
}));
it("will show an error message if the room has reached its maximum number of occupants", function () {
it("will show an error message if the room has reached its maximum number of occupants", mock.initConverse(function (converse) {
submitRoomForm(converse);
var presence = $pres().attrs({
from:'lounge@localhost/thirdwitch',
id:'n13mt3l',
......@@ -955,7 +947,7 @@
spyOn(view, 'showErrorMessage').andCallThrough();
view.onChatRoomPresence(presence);
expect(view.$el.find('.chatroom-body p:last').text()).toBe("This room has reached its maximum number of occupants");
});
}.bind(converse));
}.bind(converse, mock, test_utils));
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils"
], function ($, _, mock, test_utils) {
return factory($, _, mock, test_utils);
}
);
} (this, function ($, _, mock, test_utils) {
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var $pres = converse_api.env.$pres;
var $iq = converse_api.env.$iq;
......@@ -29,52 +22,51 @@
expect($header.nextUntil('dt', 'dd').length === $header.nextUntil('dt', 'dd:visible').length).toBeTruthy();
};
describe("The Control Box", $.proxy(function (mock, test_utils) {
beforeEach(function () {
runs(function () {
test_utils.openControlBox();
});
describe("The Control Box", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be opened by clicking a DOM element with class 'toggle-controlbox'", $.proxy(function () {
runs(function () {
test_utils.closeControlBox();
});
waits(50);
it("can be opened by clicking a DOM element with class 'toggle-controlbox'", mock.initConverse(function (converse) {
runs(function () {
// This spec will only pass if the controlbox is not currently
// open yet.
expect($("div#controlbox").is(':visible')).toBe(false);
spyOn(this.controlboxtoggle, 'onClick').andCallThrough();
spyOn(this.controlboxtoggle, 'showControlBox').andCallThrough();
spyOn(converse.controlboxtoggle, 'onClick').andCallThrough();
spyOn(converse.controlboxtoggle, 'showControlBox').andCallThrough();
spyOn(converse, 'emit');
// Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick')
this.controlboxtoggle.delegateEvents();
converse.controlboxtoggle.delegateEvents();
$('.toggle-controlbox').click();
}.bind(converse));
waits(50);
runs(function () {
expect(this.controlboxtoggle.onClick).toHaveBeenCalled();
expect(this.controlboxtoggle.showControlBox).toHaveBeenCalled();
expect(this.emit).toHaveBeenCalledWith('controlBoxOpened', jasmine.any(Object));
expect(converse.controlboxtoggle.onClick).toHaveBeenCalled();
expect(converse.controlboxtoggle.showControlBox).toHaveBeenCalled();
expect(converse.emit).toHaveBeenCalledWith('controlBoxOpened', jasmine.any(Object));
expect($("div#controlbox").is(':visible')).toBe(true);
}.bind(converse));
}, converse));
describe("The Status Widget", $.proxy(function () {
}));
beforeEach(function () {
test_utils.openControlBox();
describe("The Status Widget", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("shows the user's chat status, which is online by default", $.proxy(function () {
var view = this.xmppstatusview;
it("shows the user's chat status, which is online by default", mock.initConverse(function (converse) {
test_utils.openControlBox();
var view = converse.xmppstatusview;
expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true);
expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe('I am online');
}, converse));
}));
it("can be used to set the current user's chat status", $.proxy(function () {
var view = this.xmppstatusview;
it("can be used to set the current user's chat status", mock.initConverse(function (converse) {
test_utils.openControlBox();
var view = converse.xmppstatusview;
spyOn(view, 'toggleOptions').andCallThrough();
spyOn(view, 'setStatus').andCallThrough();
spyOn(converse, 'emit');
......@@ -92,17 +84,18 @@
expect(converse.emit).toHaveBeenCalledWith('statusChanged', 'dnd');
});
waits(250);
runs($.proxy(function () {
runs(function () {
expect(view.updateStatusUI).toHaveBeenCalled();
expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(false);
expect(view.$el.find('a.choose-xmpp-status').hasClass('dnd')).toBe(true);
expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe('I am busy');
}, converse));
}, converse));
});
}));
it("can be used to set a custom status message", $.proxy(function () {
var view = this.xmppstatusview;
this.xmppstatus.save({'status': 'online'});
it("can be used to set a custom status message", mock.initConverse(function (converse) {
test_utils.openControlBox();
var view = converse.xmppstatusview;
converse.xmppstatus.save({'status': 'online'});
spyOn(view, 'setStatusMessage').andCallThrough();
spyOn(view, 'renderStatusChangeForm').andCallThrough();
spyOn(converse, 'emit');
......@@ -123,27 +116,24 @@
expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true);
expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe(msg);
});
}, converse));
}, converse));
}, converse, mock, test_utils));
}));
});
});
describe("The Contacts Roster", $.proxy(function (mock, utils) {
function _clearContacts () {
utils.clearBrowserStorage();
converse.rosterview.model.reset();
}
describe("The Contacts Roster", function () {
describe("The live filter", $.proxy(function () {
beforeEach(function () {
_clearContacts();
test_utils.openControlBox();
test_utils.openContactsPanel();
describe("The live filter", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("will only appear when roster contacts flow over the visible area", function () {
it("will only appear when roster contacts flow over the visible area", mock.initConverse(function (converse) {
var $filter = converse.rosterview.$('.roster-filter');
var names = mock.cur_names;
runs(function () {
test_utils.openControlBox();
converse.rosterview.update(); // XXX: Will normally called as event handler
});
waits(5); // Needed, due to debounce
......@@ -170,14 +160,18 @@
expect($filter.is(':visible')).toBeFalsy();
}
});
});
}));
it("can be used to filter the contacts shown", function () {
it("can be used to filter the contacts shown", mock.initConverse(function (converse) {
var $filter;
var $roster;
runs(function () {
converse.roster_groups = true;
utils.createGroupedContacts();
test_utils.openControlBox();
});
waits(50);
runs(function () {
test_utils.createGroupedContacts(converse);
$filter = converse.rosterview.$('.roster-filter');
$roster = converse.rosterview.$roster;
});
......@@ -223,15 +217,19 @@
expect($roster.find('dt:visible').length).toBe(5);
});
converse.roster_groups = false;
});
}));
it("can be used to filter the groups shown", function () {
it("can be used to filter the groups shown", mock.initConverse(function (converse) {
var $filter;
var $roster;
var $type;
runs(function () {
converse.roster_groups = true;
utils.createGroupedContacts();
test_utils.openControlBox();
});
waits(50); // Needed, due to debounce in "update" method
runs(function () {
test_utils.createGroupedContacts(converse);
converse.rosterview.filter_view.delegateEvents();
$filter = converse.rosterview.$('.roster-filter');
$roster = converse.rosterview.$roster;
......@@ -243,6 +241,9 @@
expect($roster.find('dd:visible').length).toBe(15);
expect($roster.find('dt:visible').length).toBe(5);
$filter.val("colleagues");
});
waits(50); // Needed, due to debounce
runs(function () {
expect($roster.find('dd:visible').length).toBe(15); // because no keydown event
expect($roster.find('dt:visible').length).toBe(5); // ditto
$filter.trigger('keydown');
......@@ -270,11 +271,11 @@
expect($roster.find('dt:visible').length).toBe(5);
});
converse.roster_groups = false;
});
}));
it("has a button with which its contents can be cleared", function () {
it("has a button with which its contents can be cleared", mock.initConverse(function (converse) {
converse.roster_groups = true;
utils.createGroupedContacts();
test_utils.createGroupedContacts(converse);
var $filter = converse.rosterview.$('.roster-filter');
runs (function () {
converse.rosterview.filter_view.delegateEvents();
......@@ -290,17 +291,18 @@
expect($filter.val()).toBe("");
});
converse.roster_groups = false;
});
}));
it("can be used to filter contacts by their chat state", function () {
it("can be used to filter contacts by their chat state", mock.initConverse(function (converse) {
var $filter;
var $roster;
converse.roster_groups = true;
utils.createGroupedContacts();
test_utils.createGroupedContacts(converse);
var jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@localhost';
converse.roster.get(jid).set('chat_status', 'online');
runs(function () {
test_utils.openControlBox();
converse.rosterview.filter_view.delegateEvents();
var $type = converse.rosterview.$('.filter-type');
$type.val('state').trigger('change');
......@@ -326,33 +328,31 @@
$type.val('contacts').trigger('change');
converse.roster_groups = false;
});
});
}, converse));
}));
});
describe("A Roster Group", $.proxy(function () {
beforeEach(function () {
_clearContacts();
converse.roster_groups = true;
});
describe("A Roster Group", function () {
afterEach(function () {
converse.roster_groups = false;
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be used to organize existing contacts", $.proxy(function () {
runs($.proxy(function () {
it("can be used to organize existing contacts", mock.initConverse(function (converse) {
runs(function () {
converse.roster_groups = true;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
converse.rosterview.render();
utils.createContacts('pending');
utils.createContacts('requesting');
utils.createGroupedContacts();
}, this));
test_utils.createContacts(converse, 'pending');
test_utils.createContacts(converse, 'requesting');
test_utils.createGroupedContacts(converse);
});
waits(50); // Needed, due to debounce
runs($.proxy(function () {
runs(function () {
// Check that the groups appear alphabetically and that
// requesting and pending contacts are last.
var group_titles = $.map(this.rosterview.$el.find('dt'), function (o) { return $(o).text().trim(); });
var group_titles = $.map(converse.rosterview.$el.find('dt'), function (o) { return $(o).text().trim(); });
expect(group_titles).toEqual([
"Contact requests",
"colleagues",
......@@ -363,23 +363,24 @@
"Pending contacts"
]);
// Check that usernames appear alphabetically per group
_.each(_.keys(mock.groups), $.proxy(function (name) {
var $contacts = this.rosterview.$('dt.roster-group[data-group="'+name+'"]').nextUntil('dt', 'dd');
_.each(_.keys(mock.groups), function (name) {
var $contacts = converse.rosterview.$('dt.roster-group[data-group="'+name+'"]').nextUntil('dt', 'dd');
var names = $.map($contacts, function (o) { return $(o).text().trim(); });
expect(names).toEqual(_.clone(names).sort());
}, converse));
}, this));
}, converse));
});
});
}));
it("can share contacts with other roster groups", $.proxy(function () {
it("can share contacts with other roster groups", mock.initConverse(function (converse) {
converse.roster_groups = true;
var groups = ['colleagues', 'friends'];
runs($.proxy(function () {
runs(function () {
var i=0;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
converse.rosterview.render();
for (i=0; i<mock.cur_names.length; i++) {
this.roster.create({
converse.roster.create({
jid: mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'both',
ask: null,
......@@ -387,30 +388,31 @@
fullname: mock.cur_names[i]
});
}
}, this));
});
waits(50); // Needed, due to debounce
runs($.proxy(function () {
runs(function () {
// Check that usernames appear alphabetically per group
_.each(groups, $.proxy(function (name) {
var $contacts = this.rosterview.$('dt.roster-group[data-group="'+name+'"]').nextUntil('dt', 'dd');
_.each(groups, function (name) {
var $contacts = converse.rosterview.$('dt.roster-group[data-group="'+name+'"]').nextUntil('dt', 'dd');
var names = $.map($contacts, function (o) { return $(o).text().trim(); });
expect(names).toEqual(_.clone(names).sort());
expect(names.length).toEqual(mock.cur_names.length);
}, this));
}, this));
}, converse));
});
});
}));
it("remembers whether it is closed or opened", $.proxy(function () {
it("remembers whether it is closed or opened", mock.initConverse(function (converse) {
converse.roster_groups = true;
var i=0, j=0;
var groups = {
'colleagues': 3,
'friends & acquaintences': 3,
'Ungrouped': 2
};
_.each(_.keys(groups), $.proxy(function (name) {
_.each(_.keys(groups), function (name) {
j = i;
for (i=j; i<j+groups[name]; i++) {
this.roster.create({
converse.roster.create({
jid: mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'both',
ask: null,
......@@ -418,65 +420,62 @@
fullname: mock.cur_names[i]
});
}
}, converse));
var view = this.rosterview.get('colleagues');
});
var view = converse.rosterview.get('colleagues');
var $toggle = view.$el.find('a.group-toggle');
expect(view.model.get('state')).toBe('opened');
$toggle.click();
expect(view.model.get('state')).toBe('closed');
$toggle.click();
expect(view.model.get('state')).toBe('opened');
}, converse));
}, converse));
}));
});
describe("Pending Contacts", $.proxy(function () {
function _clearContacts () {
utils.clearBrowserStorage();
converse.rosterview.model.reset();
}
describe("Pending Contacts", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
function _addContacts () {
function _addContacts (converse) {
// Must be initialized, so that render is called and documentFragment set up.
utils.createContacts('pending').openControlBox().openContactsPanel();
test_utils.createContacts(converse, 'pending').openControlBox().openContactsPanel(converse);
}
beforeEach(function () {
_clearContacts();
});
it("can be collapsed under their own header", $.proxy(function () {
it("can be collapsed under their own header", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
checkHeaderToggling.apply(this, [this.rosterview.get('Pending contacts').$el]);
}, this));
}, converse));
runs(function () {
checkHeaderToggling.apply(converse, [converse.rosterview.get('Pending contacts').$el]);
});
}));
it("can be added to the roster", $.proxy(function () {
_clearContacts();
it("can be added to the roster", mock.initConverse(function (converse) {
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
runs($.proxy(function () {
this.roster.create({
spyOn(converse.rosterview, 'update').andCallThrough();
runs(function () {
test_utils.openControlBox();
converse.roster.create({
jid: mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'none',
ask: 'subscribe',
fullname: mock.pend_names[0]
});
}, converse));
});
waits(300);
runs($.proxy(function () {
expect(this.rosterview.$el.is(':visible')).toEqual(true);
expect(this.rosterview.update).toHaveBeenCalled();
}, converse));
}, converse));
runs(function () {
expect(converse.rosterview.$el.is(':visible')).toEqual(true);
expect(converse.rosterview.update).toHaveBeenCalled();
});
}));
it("are shown in the roster when show_only_online_users", function () {
it("are shown in the roster when show_only_online_users", mock.initConverse(function (converse) {
converse.show_only_online_users = true;
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
spyOn(converse.rosterview, 'update').andCallThrough();
......@@ -490,40 +489,40 @@
expect(converse.rosterview.$el.find('dt:visible').length).toBe(1);
});
converse.show_only_online_users = false;
});
}));
it("are shown in the roster when hide_offline_users", $.proxy(function () {
it("are shown in the roster when hide_offline_users", mock.initConverse(function (converse) {
converse.hide_offline_users = true;
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
spyOn(this.rosterview, 'update').andCallThrough();
runs($.proxy(function () {
expect(this.rosterview.$el.is(':visible')).toEqual(true);
expect(this.rosterview.update).toHaveBeenCalled();
}, converse));
spyOn(converse.rosterview, 'update').andCallThrough();
runs(function () {
expect(converse.rosterview.$el.is(':visible')).toEqual(true);
expect(converse.rosterview.update).toHaveBeenCalled();
});
waits(300); // Needed, due to debounce
runs ($.proxy(function () {
expect(this.rosterview.$el.find('dd:visible').length).toBe(3);
expect(this.rosterview.$el.find('dt:visible').length).toBe(1);
}, converse));
runs (function () {
expect(converse.rosterview.$el.find('dd:visible').length).toBe(3);
expect(converse.rosterview.$el.find('dt:visible').length).toBe(1);
});
converse.hide_offline_users = false;
}, converse));
}));
it("can be removed by the user", $.proxy(function () {
runs($.proxy(function () {
_addContacts();
}, this));
it("can be removed by the user", mock.initConverse(function (converse) {
runs(function () {
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var name = mock.pend_names[0];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var contact = this.roster.get(jid);
var contact = converse.roster.get(jid);
spyOn(window, 'confirm').andReturn(true);
spyOn(contact, 'unauthorize').andCallFake(function () { return contact; });
spyOn(contact, 'removeFromRoster');
spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback) {
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback) {
if (typeof callback === "function") { return callback(); }
});
......@@ -533,40 +532,39 @@
expect(window.confirm).toHaveBeenCalled();
expect(converse.connection.sendIQ).toHaveBeenCalled();
expect(contact.removeFromRoster).toHaveBeenCalled();
expect(this.connection.sendIQ).toHaveBeenCalled();
expect(converse.connection.sendIQ).toHaveBeenCalled();
expect(converse.rosterview.$el.find(".pending-contact-name:contains('"+name+"')").length).toEqual(0);
}, this));
}, converse));
it("do not have a header if there aren't any", $.proxy(function () {
var name = mock.pend_names[0];
runs($.proxy(function () {
_clearContacts();
}, this));
waits(50);
runs($.proxy(function () {
this.roster.create({
});
}));
it("do not have a header if there aren't any", mock.initConverse(function (converse) {
runs(function () {
test_utils.openControlBox();
var name = mock.pend_names[0];
converse.roster.create({
jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'none',
ask: 'subscribe',
fullname: name
});
});
waits(20);
runs(function () {
spyOn(window, 'confirm').andReturn(true);
spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback) {
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback) {
if (typeof callback === "function") { return callback(); }
});
expect(this.rosterview.get('Pending contacts').$el.is(':visible')).toEqual(true);
expect(converse.rosterview.get('Pending contacts').$el.is(':visible')).toEqual(true);
converse.rosterview.$el.find(".pending-contact-name:contains('"+name+"')")
.siblings('.remove-xmpp-contact').click();
expect(window.confirm).toHaveBeenCalled();
expect(this.connection.sendIQ).toHaveBeenCalled();
expect(this.rosterview.get('Pending contacts').$el.is(':visible')).toEqual(false);
}, this));
}, converse));
expect(converse.connection.sendIQ).toHaveBeenCalled();
expect(converse.rosterview.get('Pending contacts').$el.is(':visible')).toEqual(false);
});
}));
it("will lose their own header once the last one has been removed", $.proxy(function () {
_addContacts();
it("will lose their own header once the last one has been removed", mock.initConverse(function (converse) {
_addContacts(converse);
var name;
spyOn(window, 'confirm').andReturn(true);
for (var i=0; i<mock.pend_names.length; i++) {
......@@ -574,10 +572,10 @@
converse.rosterview.$el.find(".pending-contact-name:contains('"+name+"')")
.siblings('.remove-xmpp-contact').click();
}
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').is(':visible')).toBeFalsy();
}, converse));
expect(converse.rosterview.$el.find('dt#pending-xmpp-contacts').is(':visible')).toBeFalsy();
}));
it("can be added to the roster and they will be sorted alphabetically", function () {
it("can be added to the roster and they will be sorted alphabetically", mock.initConverse(function (converse) {
var i, t;
spyOn(converse, 'emit');
spyOn(converse.rosterview, 'update').andCallThrough();
......@@ -593,38 +591,34 @@
// Check that they are sorted alphabetically
t = converse.rosterview.get('Pending contacts').$el.siblings('dd.pending-xmpp-contact').find('span').text();
expect(t).toEqual(mock.pend_names.slice(0,i+1).sort().join(''));
});
}, converse));
}));
describe("Existing Contacts", $.proxy(function () {
function _clearContacts () {
utils.clearBrowserStorage();
converse.rosterview.model.reset();
}
});
var _addContacts = function () {
utils.createContacts('current').openControlBox().openContactsPanel();
describe("Existing Contacts", function () {
var _addContacts = function (converse) {
test_utils.createContacts(converse, 'current').openControlBox().openContactsPanel(converse);
};
beforeEach(function () {
_clearContacts();
utils.openControlBox().openContactsPanel();
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be collapsed under their own header", $.proxy(function () {
it("can be collapsed under their own header", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
checkHeaderToggling.apply(this, [this.rosterview.$el.find('dt.roster-group')]);
}, this));
}, converse));
it("will be hidden when appearing under a collapsed group", $.proxy(function () {
_addContacts();
this.rosterview.$el.find('dt.roster-group').find('a.group-toggle').click();
runs(function () {
checkHeaderToggling.apply(converse, [converse.rosterview.$el.find('dt.roster-group')]);
});
}));
it("will be hidden when appearing under a collapsed group", mock.initConverse(function (converse) {
_addContacts(converse);
converse.rosterview.$el.find('dt.roster-group').find('a.group-toggle').click();
var name = "Max Mustermann";
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
converse.roster.create({
......@@ -634,45 +628,44 @@
requesting: false,
subscription: 'both'
});
var view = this.rosterview.get('My contacts').get(jid);
var view = converse.rosterview.get('My contacts').get(jid);
expect(view.$el.is(':visible')).toBe(false);
}, converse));
}));
it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
it("can be added to the roster and they will be sorted alphabetically", mock.initConverse(function (converse) {
var i, t;
spyOn(converse.rosterview, 'update').andCallThrough();
runs(function () {
_clearContacts();
});
waits(50);
runs($.proxy(function () {
var i, t;
spyOn(this.rosterview, 'update').andCallThrough();
for (i=0; i<mock.cur_names.length; i++) {
this.roster.create({
converse.roster.create({
jid: mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'both',
ask: null,
fullname: mock.cur_names[i]
});
expect(this.rosterview.update).toHaveBeenCalled();
expect(converse.rosterview.update).toHaveBeenCalled();
}
});
waits(10);
runs(function () {
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.offline').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.offline').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
}, this));
}, converse));
});
}));
it("can be removed by the user", $.proxy(function () {
it("can be removed by the user", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var name = mock.cur_names[0];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var contact = this.roster.get(jid);
var contact = converse.roster.get(jid);
spyOn(window, 'confirm').andReturn(true);
spyOn(contact, 'removeFromRoster');
spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback) {
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback) {
if (typeof callback === "function") { return callback(); }
});
......@@ -683,168 +676,168 @@
expect(converse.connection.sendIQ).toHaveBeenCalled();
expect(contact.removeFromRoster).toHaveBeenCalled();
expect(converse.rosterview.$el.find(".open-chat:contains('"+name+"')").length).toEqual(0);
}, this));
}, converse));
});
}));
it("do not have a header if there aren't any", $.proxy(function () {
it("do not have a header if there aren't any", mock.initConverse(function (converse) {
var name = mock.cur_names[0];
var contact;
runs(function () {
_clearContacts();
});
waits(50);
runs($.proxy(function () {
var contact = this.roster.create({
contact = converse.roster.create({
jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'both',
ask: null,
fullname: name
});
});
waits(50);
runs(function () {
spyOn(window, 'confirm').andReturn(true);
spyOn(contact, 'removeFromRoster');
spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback) {
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback) {
if (typeof callback === "function") { return callback(); }
});
expect(this.rosterview.$el.find('dt.roster-group').css('display')).toEqual('block');
expect(converse.rosterview.$el.find('dt.roster-group').css('display')).toEqual('block');
converse.rosterview.$el.find(".open-chat:contains('"+name+"')")
.siblings('.remove-xmpp-contact').click();
expect(window.confirm).toHaveBeenCalled();
expect(this.connection.sendIQ).toHaveBeenCalled();
expect(converse.connection.sendIQ).toHaveBeenCalled();
expect(contact.removeFromRoster).toHaveBeenCalled();
expect(this.rosterview.$el.find('dt.roster-group').css('display')).toEqual('none');
}, this));
}, converse));
expect(converse.rosterview.$el.find('dt.roster-group').css('display')).toEqual('none');
});
}));
it("can change their status to online and be sorted alphabetically", $.proxy(function () {
it("can change their status to online and be sorted alphabetically", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var jid, t;
spyOn(converse, 'emit');
spyOn(converse.rosterview, 'update').andCallThrough();
for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'online');
converse.roster.get(jid).set('chat_status', 'online');
expect(converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.online').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.online').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
}
}, this));
}, converse));
});
}));
it("can change their status to busy and be sorted alphabetically", $.proxy(function () {
it("can change their status to busy and be sorted alphabetically", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var jid, t;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'dnd');
expect(this.rosterview.update).toHaveBeenCalled();
converse.roster.get(jid).set('chat_status', 'dnd');
expect(converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.dnd').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.dnd').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
}
}, this));
}, converse));
});
}));
it("can change their status to away and be sorted alphabetically", $.proxy(function () {
it("can change their status to away and be sorted alphabetically", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var jid, t;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'away');
expect(this.rosterview.update).toHaveBeenCalled();
converse.roster.get(jid).set('chat_status', 'away');
expect(converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.away').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.away').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
}
}, this));
}, converse));
});
}));
it("can change their status to xa and be sorted alphabetically", $.proxy(function () {
it("can change their status to xa and be sorted alphabetically", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var jid, t;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'xa');
expect(this.rosterview.update).toHaveBeenCalled();
converse.roster.get(jid).set('chat_status', 'xa');
expect(converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.xa').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.xa').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
}
}, this));
}, converse));
});
}));
it("can change their status to unavailable and be sorted alphabetically", $.proxy(function () {
it("can change their status to unavailable and be sorted alphabetically", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var jid, t;
spyOn(converse, 'emit');
spyOn(this.rosterview, 'update').andCallThrough();
spyOn(converse.rosterview, 'update').andCallThrough();
for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'unavailable');
expect(this.rosterview.update).toHaveBeenCalled();
converse.roster.get(jid).set('chat_status', 'unavailable');
expect(converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
t = this.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.unavailable').find('a.open-chat').text();
t = converse.rosterview.$el.find('dt.roster-group').siblings('dd.current-xmpp-contact.unavailable').find('a.open-chat').text();
expect(t).toEqual(mock.cur_names.slice(0, i+1).sort().join(''));
}
}, this));
}, converse));
});
}));
it("are ordered according to status: online, busy, away, xa, unavailable, offline", $.proxy(function () {
it("are ordered according to status: online, busy, away, xa, unavailable, offline", mock.initConverse(function (converse) {
runs(function () {
_addContacts();
_addContacts(converse);
});
waits(50);
runs($.proxy(function () {
runs(function () {
var i, jid;
for (i=0; i<3; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'online');
converse.roster.get(jid).set('chat_status', 'online');
}
for (i=3; i<6; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'dnd');
converse.roster.get(jid).set('chat_status', 'dnd');
}
for (i=6; i<9; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'away');
converse.roster.get(jid).set('chat_status', 'away');
}
for (i=9; i<12; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'xa');
converse.roster.get(jid).set('chat_status', 'xa');
}
for (i=12; i<15; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
this.roster.get(jid).set('chat_status', 'unavailable');
converse.roster.get(jid).set('chat_status', 'unavailable');
}
var contacts = this.rosterview.$el.find('dd.current-xmpp-contact');
var contacts = converse.rosterview.$el.find('dd.current-xmpp-contact');
for (i=0; i<3; i++) {
expect($(contacts[i]).hasClass('online')).toBeTruthy();
expect($(contacts[i]).hasClass('both')).toBeTruthy();
......@@ -899,24 +892,20 @@
expect($(contacts[i]).hasClass('xa')).toBeFalsy();
expect($(contacts[i]).hasClass('unavailable')).toBeFalsy();
}
}, this));
}, converse));
}, converse));
describe("Requesting Contacts", $.proxy(function () {
beforeEach($.proxy(function () {
runs(function () {
utils.clearBrowserStorage();
converse.rosterview.model.reset();
utils.createContacts('requesting').openControlBox();
});
waits(50);
runs(function () {
utils.openContactsPanel();
});
}, converse));
}));
});
describe("Requesting Contacts", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be added to the roster and they will be sorted alphabetically", function () {
it("can be added to the roster and they will be sorted alphabetically", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'requesting').openControlBox();
test_utils.openContactsPanel(converse);
converse.rosterview.model.reset(); // We want to manually create users so that we can spy
var i, children;
var names = [];
......@@ -946,65 +935,77 @@
names = [];
children.each(addName);
expect(names.join('')).toEqual(mock.req_names.slice(0,i+1).sort().join(''));
});
}));
it("do not have a header if there aren't any", mock.initConverse(function (converse) {
test_utils.openContactsPanel(converse);
it("do not have a header if there aren't any", $.proxy(function () {
converse.rosterview.model.reset(); // We want to manually create users so that we can spy
var name = mock.req_names[0];
runs($.proxy(function () {
runs(function () {
spyOn(window, 'confirm').andReturn(true);
this.roster.create({
converse.roster.create({
jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
subscription: 'none',
ask: null,
requesting: true,
fullname: name
});
}, this));
});
waits(50);
runs($.proxy(function () {
expect(this.rosterview.get('Contact requests').$el.is(':visible')).toEqual(true);
runs(function () {
expect(converse.rosterview.get('Contact requests').$el.is(':visible')).toEqual(true);
converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')")
.siblings('.request-actions')
.find('.decline-xmpp-request').click();
expect(window.confirm).toHaveBeenCalled();
expect(this.rosterview.get('Contact requests').$el.is(':visible')).toEqual(false);
}, this));
}, converse));
it("can be collapsed under their own header", $.proxy(function () {
checkHeaderToggling.apply(this, [this.rosterview.get('Contact requests').$el]);
}, converse));
it("can have their requests accepted by the user", $.proxy(function () {
// TODO: Testing can be more thorough here, the user is
// actually not accepted/authorized because of
// mock_connection.
var name = mock.req_names.sort()[0];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var contact = this.roster.get(jid);
spyOn(converse.roster, 'sendContactAddIQ').andCallFake(function (jid, fullname, groups, callback) {
callback();
});
spyOn(contact, 'authorize').andCallFake(function () { return contact; });
converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')")
.siblings('.request-actions')
.find('.accept-xmpp-request').click();
expect(converse.roster.sendContactAddIQ).toHaveBeenCalled();
expect(contact.authorize).toHaveBeenCalled();
}, converse));
it("can have their requests denied by the user", $.proxy(function () {
this.rosterview.model.reset();
runs($.proxy(function () {
utils.createContacts('requesting').openControlBox();
expect(converse.rosterview.get('Contact requests').$el.is(':visible')).toEqual(false);
});
}));
it("can be collapsed under their own header", mock.initConverse(function (converse) {
runs(function () {
test_utils.createContacts(converse, 'requesting').openControlBox();
});
waits(10);
runs(function () {
checkHeaderToggling.apply(converse, [converse.rosterview.get('Contact requests').$el]);
});
}));
it("can have their requests accepted by the user", mock.initConverse(function (converse) {
runs(function () {
test_utils.createContacts(converse, 'requesting').openControlBox();
});
waits(10);
runs(function () {
// TODO: Testing can be more thorough here, the user is
// actually not accepted/authorized because of
// mock_connection.
var name = mock.req_names.sort()[0];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var contact = converse.roster.get(jid);
spyOn(converse.roster, 'sendContactAddIQ').andCallFake(function (jid, fullname, groups, callback) {
callback();
});
spyOn(contact, 'authorize').andCallFake(function () { return contact; });
converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')")
.siblings('.request-actions')
.find('.accept-xmpp-request').click();
expect(converse.roster.sendContactAddIQ).toHaveBeenCalled();
expect(contact.authorize).toHaveBeenCalled();
});
}));
it("can have their requests denied by the user", mock.initConverse(function (converse) {
runs(function () {
test_utils.createContacts(converse, 'requesting').openControlBox();
converse.rosterview.update(); // XXX: Hack to make sure $roster element is attaced.
}, this));
});
waits(50);
runs($.proxy(function () {
runs(function () {
var name = mock.req_names.sort()[1];
var jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var contact = this.roster.get(jid);
var contact = converse.roster.get(jid);
spyOn(window, 'confirm').andReturn(true);
spyOn(contact, 'unauthorize').andCallFake(function () { return contact; });
converse.rosterview.$el.find(".req-contact-name:contains('"+name+"')")
......@@ -1013,26 +1014,25 @@
expect(window.confirm).toHaveBeenCalled();
expect(contact.unauthorize).toHaveBeenCalled();
// There should now be one less contact
expect(this.roster.length).toEqual(mock.req_names.length-1);
}, this));
}, converse));
expect(converse.roster.length).toEqual(mock.req_names.length-1);
});
}));
it("are persisted even if other contacts' change their presence ", $.proxy(function() {
it("are persisted even if other contacts' change their presence ", mock.initConverse(function (converse) {
/* This is a regression test.
* https://github.com/jcbrand/converse.js/issues/262
*/
this.rosterview.model.reset();
expect(this.roster.pluck('jid').length).toBe(0);
expect(converse.roster.pluck('jid').length).toBe(0);
var stanza = $pres({from: 'data@enterprise/resource', type: 'subscribe'});
this.connection._dataRecv(test_utils.createRequest(stanza));
expect(this.roster.pluck('jid').length).toBe(1);
expect(_.contains(this.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(converse.roster.pluck('jid').length).toBe(1);
expect(_.contains(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
// Taken from the spec
// http://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3
stanza = $iq({
to: this.connection.jid,
to: converse.connection.jid,
type: 'result',
id: 'roster_1'
}).c('query', {
......@@ -1052,32 +1052,27 @@
name: 'Benvolio',
subscription:'both'
}).c('group').t('Friends');
this.roster.onReceivedFromServer(stanza.tree());
expect(_.contains(this.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
}, converse));
}, converse));
converse.roster.onReceivedFromServer(stanza.tree());
expect(_.contains(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
}));
});
describe("All Contacts", $.proxy(function () {
beforeEach($.proxy(function () {
runs(function () {
utils.clearBrowserStorage();
converse.rosterview.model.reset();
utils.createContacts('all').openControlBox();
});
waits(50);
runs(function () {
utils.openContactsPanel();
});
}, converse));
describe("All Contacts", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("are saved to, and can be retrieved from, browserStorage", $.proxy(function () {
it("are saved to, and can be retrieved from browserStorage", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'all').openControlBox();
test_utils.openContactsPanel(converse);
var new_attrs, old_attrs, attrs;
var num_contacts = this.roster.length;
var new_roster = new this.RosterContacts();
var num_contacts = converse.roster.length;
var new_roster = new converse.RosterContacts();
// Roster items are yet to be fetched from browserStorage
expect(new_roster.length).toEqual(0);
new_roster.browserStorage = this.roster.browserStorage;
new_roster.browserStorage = converse.roster.browserStorage;
new_roster.fetch();
expect(new_roster.length).toEqual(num_contacts);
// Check that the roster items retrieved from browserStorage
......@@ -1085,78 +1080,84 @@
attrs = ['jid', 'fullname', 'subscription', 'ask'];
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(new_roster.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(this.roster.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.roster.models, 'attributes'), attrs[i]);
// Roster items in storage are not necessarily sorted,
// so we have to sort them here to do a proper
// comparison
expect(_.isEqual(new_attrs.sort(), old_attrs.sort())).toEqual(true);
}
}, converse));
it("will show fullname and jid properties on tooltip", $.proxy(function () {
var jid, name, i;
for (i=0; i<mock.cur_names.length; i++) {
name = mock.cur_names[i];
jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var $dd = this.rosterview.$el.find("dd:contains('"+name+"')").children().first();
var dd_text = $dd.text();
var dd_title = $dd.attr('title');
expect(dd_text).toBe(name);
expect(dd_title).toContain(name);
expect(dd_title).toContain(jid);
}
}, converse));
}));
it("will show fullname and jid properties on tooltip", mock.initConverse(function (converse) {
runs(function () {
test_utils.createContacts(converse, 'all').openControlBox();
test_utils.openContactsPanel(converse);
});
waits(10);
runs(function () {
var jid, name, i;
for (i=0; i<mock.cur_names.length; i++) {
name = mock.cur_names[i];
jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var $dd = converse.rosterview.$el.find("dd:contains('"+name+"')").children().first();
var dd_text = $dd.text();
var dd_title = $dd.attr('title');
expect(dd_text).toBe(name);
expect(dd_title).toContain(name);
expect(dd_title).toContain(jid);
}
});
}));
}, converse));
}, converse, mock, test_utils));
});
});
describe("The 'Add Contact' widget", $.proxy(function (mock, test_utils) {
it("opens up an add form when you click on it", $.proxy(function () {
var panel = this.chatboxviews.get('controlbox').contactspanel;
describe("The 'Add Contact' widget", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("opens up an add form when you click on it", mock.initConverse(function (converse) {
var panel = converse.chatboxviews.get('controlbox').contactspanel;
spyOn(panel, 'toggleContactForm').andCallThrough();
panel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
panel.$el.find('a.toggle-xmpp-contact-form').click();
expect(panel.toggleContactForm).toHaveBeenCalled();
// XXX: Awaiting more tests, close it again for now...
panel.$el.find('a.toggle-xmpp-contact-form').click();
}, converse));
}, converse, mock, test_utils));
describe("The Controlbox Tabs", $.proxy(function () {
beforeEach($.proxy(function () {
runs(function () {
test_utils.closeAllChatBoxes();
});
waits(50);
runs(function () {
test_utils.openControlBox();
});
}, converse));
}));
});
describe("The Controlbox Tabs", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("contains two tabs, 'Contacts' and 'ChatRooms'", $.proxy(function () {
var cbview = this.chatboxviews.get('controlbox');
it("contains two tabs, 'Contacts' and 'ChatRooms'", mock.initConverse(function (converse) {
test_utils.openControlBox();
var cbview = converse.chatboxviews.get('controlbox');
var $panels = cbview.$el.find('.controlbox-panes');
expect($panels.children().length).toBe(2);
expect($panels.children().first().attr('id')).toBe('users');
expect($panels.children().first().is(':visible')).toBe(true);
expect($panels.children().last().attr('id')).toBe('chatrooms');
expect($panels.children().last().is(':visible')).toBe(false);
}, converse));
}));
describe("chatrooms panel", $.proxy(function () {
beforeEach($.proxy(function () {
runs(function () {
test_utils.closeAllChatBoxes();
});
waits(50);
runs(function () {
test_utils.openControlBox();
});
}, converse));
describe("chatrooms panel", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is opened by clicking the 'Chatrooms' tab", $.proxy(function () {
var cbview = this.chatboxviews.get('controlbox');
it("is opened by clicking the 'Chatrooms' tab", mock.initConverse(function (converse) {
test_utils.openControlBox();
var cbview = converse.chatboxviews.get('controlbox');
var $tabs = cbview.$el.find('#controlbox-tabs');
var $panels = cbview.$el.find('.controlbox-panes');
var $contacts = $panels.children().first();
......@@ -1167,10 +1168,11 @@
expect($contacts.is(':visible')).toBe(false);
expect($chatrooms.is(':visible')).toBe(true);
expect(cbview.switchTab).toHaveBeenCalled();
}, converse));
}));
it("contains a form through which a new chatroom can be created", $.proxy(function () {
var roomspanel = this.chatboxviews.get('controlbox').roomspanel;
it("contains a form through which a new chatroom can be created", mock.initConverse(function (converse) {
test_utils.openControlBox();
var roomspanel = converse.chatboxviews.get('controlbox').roomspanel;
var $input = roomspanel.$el.find('input.new-chatroom-name');
var $nick = roomspanel.$el.find('input.new-chatroom-nick');
var $server = roomspanel.$el.find('input.new-chatroom-server');
......@@ -1190,13 +1192,14 @@
expect(roomspanel.createChatRoom).toHaveBeenCalled();
});
waits('250');
runs($.proxy(function () {
runs(function () {
expect($('.chatroom:visible').length).toBe(1); // There should now be an open chatroom
}, converse));
}, converse));
});
}));
it("can list rooms publically available on the server", $.proxy(function () {
var panel = this.chatboxviews.get('controlbox').roomspanel;
it("can list rooms publically available on the server", mock.initConverse(function (converse) {
test_utils.openControlBox();
var panel = converse.chatboxviews.get('controlbox').roomspanel;
panel.$tabs.find('li').last().find('a').click(); // Click the chatrooms tab
panel.model.set({'muc_domain': 'muc.localhost'}); // Make sure the domain is set
// See: http://xmpp.org/extensions/xep-0045.html#disco-rooms
......@@ -1217,7 +1220,7 @@
expect(panel.$('#available-chatrooms').children('dt').length).toBe(1);
expect(panel.$('#available-chatrooms').children('dt').first().text()).toBe("Rooms on muc.localhost");
expect(panel.$('#available-chatrooms').children('dd').length).toBe(4);
}, converse));
}, converse));
}, converse, mock, test_utils));
}));
});
});
}));
......@@ -15,6 +15,7 @@
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
......
/*global converse */
(function (root, factory) {
define([
"jquery",
......@@ -12,15 +11,21 @@
"use strict";
var Strophe = converse_api.env.Strophe;
describe("Service Discovery", $.proxy(function (mock, test_utils) {
describe("Service Discovery", function () {
describe("Whenever converse.js discovers a new server feature", $.proxy(function (mock, test_utils) {
it("emits the serviceDiscovered event", function () {
describe("Whenever converse.js discovers a new server feature", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("emits the serviceDiscovered event", mock.initConverse(function (converse) {
spyOn(converse, 'emit');
converse.features.create({'var': Strophe.NS.MAM});
expect(converse.emit).toHaveBeenCalled();
expect(converse.emit.argsForCall[0][1].get('var')).toBe(Strophe.NS.MAM);
});
}, converse, mock, test_utils));
}, converse, mock, test_utils));
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"mock",
"test_utils"
], function ($, mock, test_utils) {
return factory($, mock, test_utils);
}
);
} (this, function ($, mock, test_utils) {
return describe("The Converse Event Emitter", $.proxy(function(mock, test_utils) {
window.localStorage.clear();
window.sessionStorage.clear();
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
it("allows you to subscribe to emitted events", function () {
return describe("The Converse Event Emitter", function() {
it("allows you to subscribe to emitted events", mock.initConverse(function (converse) {
this.callback = function () {};
spyOn(this, 'callback');
converse.on('connected', this.callback);
......@@ -23,9 +14,9 @@
expect(this.callback.callCount, 2);
converse.emit('connected');
expect(this.callback.callCount, 3);
});
}));
it("allows you to listen once for an emitted event", function () {
it("allows you to listen once for an emitted event", mock.initConverse(function (converse) {
this.callback = function () {};
spyOn(this, 'callback');
converse.once('connected', this.callback);
......@@ -35,9 +26,9 @@
expect(this.callback.callCount, 1);
converse.emit('connected');
expect(this.callback.callCount, 1);
});
}));
it("allows you to stop listening or subscribing to an event", function () {
it("allows you to stop listening or subscribing to an event", mock.initConverse(function (converse) {
this.callback = function () {};
this.anotherCallback = function () {};
this.neverCalled = function () {};
......@@ -65,6 +56,6 @@
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled();
});
}, converse, mock, test_utils));
}));
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
......@@ -13,12 +12,12 @@
describe("A headlines box", function () {
beforeEach(function () {
test_utils.openControlBox();
test_utils.openContactsPanel();
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("will not open nor display non-headline messages", function () {
it("will not open nor display non-headline messages", mock.initConverse(function (converse) {
/* XMPP spam message:
*
* <message xmlns="jabber:client"
......@@ -29,6 +28,8 @@
* <body>SORRY FOR THIS ADVERT</body
* </message
*/
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
sinon.spy(utils, 'isHeadlineMessage');
runs(function () {
var stanza = $msg({
......@@ -47,11 +48,10 @@
expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
utils.isHeadlineMessage.restore();
});
});
}));
it("will open and display headline messages", function () {
it("will open and display headline messages", mock.initConverse(function (converse) {
/*
* <message from='notify.example.com'
* to='romeo@im.example.com'
......@@ -66,6 +66,8 @@
* </x>
* </message>
*/
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
sinon.spy(utils, 'isHeadlineMessage');
runs(function () {
var stanza = $msg({
......@@ -91,6 +93,6 @@
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
utils.isHeadlineMessage.restore(); // unwraps
});
});
}));
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils"
], function ($, _, mock, test_utils) {
return factory($, _, mock, test_utils);
}
);
} (this, function ($, _, mock, test_utils) {
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
"use strict";
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var Strophe = converse_api.env.Strophe;
var $iq = converse_api.env.$iq;
var $msg = converse_api.env.$msg;
var moment = converse_api.env.moment;
// See: https://xmpp.org/rfcs/rfc3921.html
describe("Message Archive Management", $.proxy(function (mock, test_utils) {
describe("Message Archive Management", function () {
// Implement the protocol defined in https://xmpp.org/extensions/xep-0313.html#config
describe("The archive.query API", $.proxy(function (mock, test_utils) {
describe("The archive.query API", function () {
it("can be used to query for all archived messages", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("can be used to query for all archived messages", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -36,9 +35,9 @@
var queryid = $(sent_stanza.toString()).find('query').attr('queryid');
expect(sent_stanza.toString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'><query xmlns='urn:xmpp:mam:0' queryid='"+queryid+"'/></iq>");
});
}));
it("can be used to query for all messages to/from a particular JID", function () {
it("can be used to query for all messages to/from a particular JID", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -64,9 +63,9 @@
"</query>"+
"</iq>"
);
});
}));
it("can be used to query for all messages in a certain timespan", function () {
it("can be used to query for all messages in a certain timespan", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -101,15 +100,18 @@
"</query>"+
"</iq>"
);
});
}));
it("throws a TypeError if an invalid date is provided", function () {
it("throws a TypeError if an invalid date is provided", mock.initConverse(function (converse) {
if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
converse.features.create({'var': Strophe.NS.MAM});
}
expect(_.partial(converse_api.archive.query, {'start': 'not a real date'})).toThrow(
new TypeError('archive.query: invalid date provided for: start')
);
});
}));
it("can be used to query for all messages after a certain time", function () {
it("can be used to query for all messages after a certain time", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -136,9 +138,9 @@
"</query>"+
"</iq>"
);
});
}));
it("can be used to query for a limited set of results", function () {
it("can be used to query for a limited set of results", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -168,9 +170,9 @@
"</query>"+
"</iq>"
);
});
}));
it("can be used to page through results", function () {
it("can be used to page through results", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -205,9 +207,9 @@
"</query>"+
"</iq>"
);
});
}));
it("accepts \"before\" with an empty string as value to reverse the order", function () {
it("accepts \"before\" with an empty string as value to reverse the order", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -234,9 +236,9 @@
"</query>"+
"</iq>"
);
});
}));
it("accepts a Strophe.RSM object for the query options", function () {
it("accepts a Strophe.RSM object for the query options", mock.initConverse(function (converse) {
// Normally the user wouldn't manually make a Strophe.RSM object
// and pass it in. However, in the callback method an RSM object is
// returned which can be reused for easy paging. This test is
......@@ -276,9 +278,9 @@
"</query>"+
"</iq>"
);
});
}));
it("accepts a callback function, which it passes the messages and a Strophe.RSM object", function () {
it("accepts a callback function, which it passes the messages and a Strophe.RSM object", mock.initConverse(function (converse) {
if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
converse.features.create({'var': Strophe.NS.MAM});
}
......@@ -365,13 +367,19 @@
expect(args[1].count).toBe('16');
expect(args[1].first).toBe('23452-4534-1');
expect(args[1].last).toBe('390-2342-22');
});
}));
}, converse, mock, test_utils));
});
describe("The default preference", $.proxy(function (mock, test_utils) {
describe("The default preference", function () {
it("is set once server support for MAM has been confirmed", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is set once server support for MAM has been confirmed", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -443,7 +451,7 @@
// Restore
converse.message_archiving = 'never';
});
}, converse, mock, test_utils));
}, converse, mock, test_utils));
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils"
], function ($, _, mock, test_utils) {
return factory($, _, mock, test_utils);
}
);
} (this, function ($, _, mock, test_utils) {
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
var _ = converse_api.env._;
var $msg = converse_api.env.$msg;
return describe("The Minimized Chats Widget", $.proxy(function(mock, test_utils) {
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.removeControlBox();
converse.roster.browserStorage._clear();
test_utils.initConverse();
test_utils.createContacts('current');
test_utils.openControlBox();
test_utils.openContactsPanel();
converse.minimized_chats.toggleview.model.browserStorage._clear();
converse.minimized_chats.initToggle();
});
describe("The Minimized Chats Widget", function () {
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("shows chats that have been minimized", $.proxy(function () {
it("shows chats that have been minimized", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
converse.minimized_chats.toggleview.model.browserStorage._clear();
converse.minimized_chats.initToggle();
var contact_jid, chatview;
contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy();
expect(this.minimized_chats.$el.is(':visible')).toBeFalsy();
expect(converse.minimized_chats.$el.is(':visible')).toBeFalsy();
chatview.$el.find('.toggle-chatbox-button').click();
expect(chatview.model.get('minimized')).toBeTruthy();
expect(this.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(this.minimized_chats.keys().length).toBe(1);
expect(this.minimized_chats.keys()[0]).toBe(contact_jid);
expect(converse.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(converse.minimized_chats.keys().length).toBe(1);
expect(converse.minimized_chats.keys()[0]).toBe(contact_jid);
contact_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
chatview = converse.chatboxviews.get(contact_jid);
expect(chatview.model.get('minimized')).toBeFalsy();
chatview.$el.find('.toggle-chatbox-button').click();
expect(chatview.model.get('minimized')).toBeTruthy();
expect(this.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(this.minimized_chats.keys().length).toBe(2);
expect(_.contains(this.minimized_chats.keys(), contact_jid)).toBeTruthy();
}, converse));
expect(converse.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(converse.minimized_chats.keys().length).toBe(2);
expect(_.contains(converse.minimized_chats.keys(), contact_jid)).toBeTruthy();
}));
it("can be toggled to hide or show minimized chats", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
converse.minimized_chats.toggleview.model.browserStorage._clear();
converse.minimized_chats.initToggle();
it("can be toggled to hide or show minimized chats", $.proxy(function () {
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var chatview = converse.chatboxviews.get(contact_jid);
expect(this.minimized_chats.$el.is(':visible')).toBeFalsy();
expect(converse.minimized_chats.$el.is(':visible')).toBeFalsy();
chatview.model.set({'minimized': true});
expect(this.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(this.minimized_chats.keys().length).toBe(1);
expect(this.minimized_chats.keys()[0]).toBe(contact_jid);
expect(this.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeTruthy();
expect(this.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
this.minimized_chats.$('#toggle-minimized-chats').click();
expect(this.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeFalsy();
expect(this.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
}, converse));
expect(converse.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(converse.minimized_chats.keys().length).toBe(1);
expect(converse.minimized_chats.keys()[0]).toBe(contact_jid);
expect(converse.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeTruthy();
expect(converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
converse.minimized_chats.$('#toggle-minimized-chats').click();
expect(converse.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeFalsy();
expect(converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
}));
it("shows the number messages received to minimized chats", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
converse.minimized_chats.toggleview.model.browserStorage._clear();
converse.minimized_chats.initToggle();
it("shows the number messages received to minimized chats", $.proxy(function () {
var i, contact_jid, chatview, msg;
this.minimized_chats.toggleview.model.set({'collapsed': true});
expect(this.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeFalsy();
converse.minimized_chats.toggleview.model.set({'collapsed': true});
expect(converse.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeFalsy();
for (i=0; i<3; i++) {
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
chatview = converse.chatboxviews.get(contact_jid);
chatview.model.set({'minimized': true});
msg = $msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('This message is sent to a minimized chatbox').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
this.chatboxes.onMessage(msg);
expect(this.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeTruthy();
expect(this.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i+1).toString());
converse.chatboxes.onMessage(msg);
expect(converse.minimized_chats.toggleview.$('.unread-message-count').is(':visible')).toBeTruthy();
expect(converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i+1).toString());
}
// Chat state notifications don't increment the unread messages counter
// <composing> state
this.chatboxes.onMessage($msg({
converse.chatboxes.onMessage($msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('composing', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect(this.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
expect(converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
// <paused> state
this.chatboxes.onMessage($msg({
converse.chatboxes.onMessage($msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('paused', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect(this.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
expect(converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
// <gone> state
this.chatboxes.onMessage($msg({
converse.chatboxes.onMessage($msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('gone', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect(this.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
expect(converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
// <inactive> state
this.chatboxes.onMessage($msg({
converse.chatboxes.onMessage($msg({
from: contact_jid,
to: this.connection.jid,
to: converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('inactive', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect(this.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
}, converse));
}, converse, mock, test_utils));
expect(converse.minimized_chats.toggleview.$('.unread-message-count').text()).toBe((i).toString());
}));
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils"
], function ($, _, mock, test_utils) {
return factory($, _, mock, test_utils);
}
);
} (this, function ($, _, mock, test_utils) {
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
"use strict";
var $msg = converse_api.env.$msg;
describe("Notifications", function () {
// Implement the protocol defined in https://xmpp.org/extensions/xep-0313.html#config
beforeEach(function () {
runs(function () {
test_utils.closeAllChatBoxes();
test_utils.createContacts('current');
});
});
describe("When show_desktop_notifications is set to true", function () {
describe("And the desktop is not focused", function () {
describe("an HTML5 Notification", function () {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("is shown when a new private message is received", function () {
it("is shown when a new private message is received", mock.initConverse(function (converse) {
// TODO: not yet testing show_desktop_notifications setting
test_utils.createContacts(converse, 'current');
spyOn(converse, 'showMessageNotification');
spyOn(converse, 'areDesktopNotificationsEnabled').andReturn(true);
......@@ -43,10 +33,11 @@
converse.chatboxes.onMessage(msg); // This will emit 'message'
expect(converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
expect(converse.showMessageNotification).toHaveBeenCalled();
});
}));
it("is shown when you are mentioned in a chat room", function () {
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
it("is shown when you are mentioned in a chat room", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var no_notification = false;
......@@ -75,39 +66,46 @@
if (no_notification) {
delete window.Notification;
}
});
}));
it("is shown when a user changes their chat state", function () {
it("is shown when a user changes their chat state", mock.initConverse(function (converse) {
// TODO: not yet testing show_desktop_notifications setting
test_utils.createContacts(converse, 'current');
spyOn(converse, 'areDesktopNotificationsEnabled').andReturn(true);
spyOn(converse, 'showChatStateNotification');
var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
converse.roster.get(jid).set('chat_status', 'busy'); // This will emit 'contactStatusChanged'
expect(converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
expect(converse.showChatStateNotification).toHaveBeenCalled();
});
}));
});
});
describe("When a new contact request is received", function () {
it("an HTML5 Notification is received", function () {
it("an HTML5 Notification is received", mock.initConverse(function (converse) {
spyOn(converse, 'areDesktopNotificationsEnabled').andReturn(true);
spyOn(converse, 'showContactRequestNotification');
converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
expect(converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
expect(converse.showContactRequestNotification).toHaveBeenCalled();
});
}));
});
});
describe("When play_sounds is set to true", function () {
describe("A notification sound", function () {
it("is played when the current user is mentioned in a chat room", function () {
test_utils.openAndEnterChatRoom('lounge', 'localhost', 'dummy');
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("is played when the current user is mentioned in a chat room", mock.initConverse(function (converse) {
test_utils.createContacts(converse, 'current');
test_utils.openAndEnterChatRoom(converse, 'lounge', 'localhost', 'dummy');
converse.play_sounds = true;
spyOn(converse, 'playSoundNotification');
var view = this.chatboxviews.get('lounge@localhost');
var view = converse.chatboxviews.get('lounge@localhost');
if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
var text = 'This message will play a sound because it mentions dummy';
var message = $msg({
......@@ -140,7 +138,7 @@
view.onChatRoomMessage(message.nodeTree);
expect(converse.playSoundNotification, 1);
converse.play_sounds = false;
}.bind(converse));
}));
});
});
});
......
/*global converse */
(function (root, factory) {
define([
"jquery",
"mock",
"test_utils"
], function ($, mock, test_utils) {
return factory($, mock, test_utils);
}
);
} (this, function ($, mock, test_utils) {
define(["mock","test_utils" ], factory);
} (this, function (mock, test_utils) {
var $ = converse_api.env.jQuery;
var Strophe = converse_api.env.Strophe;
var b64_sha1 = converse_api.env.b64_sha1;
return describe("The OTR module", function() {
beforeEach(function () {
test_utils.openControlBox();
test_utils.openContactsPanel();
test_utils.createContacts('current');
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("can store a session passphrase in session storage", function () {
it("can store a session passphrase in session storage", mock.initConverse(function (converse) {
// With no prebind, the user's XMPP password is used and nothing is
// stored in session storage.
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
test_utils.createContacts(converse, 'current');
var auth = converse.authentication;
var pass = converse.connection.pass;
converse.authentication = "manual";
......@@ -38,13 +34,17 @@
// Clean up
converse.authentication = auth;
converse.connection.pass = pass;
});
}));
it("will add processing hints to sent out encrypted <message> stanzas", mock.initConverse(function (converse) {
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
test_utils.createContacts(converse, 'current');
it("will add processing hints to sent out encrypted <message> stanzas", function () {
var UNVERIFIED = 1, UNENCRYPTED = 0;
var contact_name = mock.cur_names[0];
var contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(contact_jid);
test_utils.openChatBoxFor(converse, contact_jid);
var chatview = converse.chatboxviews.get(contact_jid);
chatview.model.set('otr_status', UNVERIFIED);
var stanza = chatview.createMessageStanza(new converse.Message({ message: 'hello world'}));
......@@ -54,11 +54,15 @@
expect($hints.get(1).tagName).toBe('no-permanent-store');
expect($hints.get(2).tagName).toBe('no-copy');
chatview.model.set('otr_status', UNENCRYPTED); // Reset again to UNENCRYPTED
});
}));
describe("An OTR Chat Message", function () {
it("will not be carbon copied when it's sent out", function () {
it("will not be carbon copied when it's sent out", mock.initConverse(function (converse) {
test_utils.openControlBox();
test_utils.openContactsPanel(converse);
test_utils.createContacts(converse, 'current');
var msgtext = "?OTR,1,3,?OTR:AAIDAAAAAAEAAAABAAAAwCQ8HKsag0y0DGKsneo0kzKu1ua5L93M4UKTkCf1I2kbm2RgS5kIxDTxrTj3wVRB+H5Si86E1fKtuBgsDf/bKkGTM0h/49vh5lOD9HkE8cnSrFEn5GN,";
var sender_jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@localhost';
converse_api.chats.open(sender_jid);
......@@ -71,7 +75,7 @@
expect($sent.find('private').length).toBe(1);
expect($sent.find('private').attr('xmlns')).toBe('urn:xmpp:carbons:2');
chatbox.set('otr_status', 0); // Reset again to UNENCRYPTED
});
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"converse-ping"
], function ($) {
return factory($);
}
);
} (this, function ($) {
define(["mock", "test_utils", "converse-ping"], factory);
} (this, function (mock, test_utils) {
"use strict";
describe("XMPP Ping", function () {
describe("Ping and pong handlers", function () {
it("are registered when converse.js is connected", function () {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("are registered when converse.js is connected", mock.initConverse(function (converse) {
spyOn(converse, 'registerPingHandler').andCallThrough();
spyOn(converse, 'registerPongHandler').andCallThrough();
converse.emit('connected');
expect(converse.registerPingHandler).toHaveBeenCalled();
expect(converse.registerPongHandler).toHaveBeenCalled();
});
}));
it("are registered when converse.js reconnected", function () {
it("are registered when converse.js reconnected", mock.initConverse(function (converse) {
spyOn(converse, 'registerPingHandler').andCallThrough();
spyOn(converse, 'registerPongHandler').andCallThrough();
converse.emit('reconnected');
expect(converse.registerPingHandler).toHaveBeenCalled();
expect(converse.registerPongHandler).toHaveBeenCalled();
});
}));
});
describe("An IQ stanza", function () {
it("is sent out when converse.js pings a server", function () {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("is sent out when converse.js pings a server", mock.initConverse(function (converse) {
var sent_stanza, IQ_id;
var sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
......@@ -42,7 +45,7 @@
"<iq type='get' to='localhost' id='"+IQ_id+"' xmlns='jabber:client'>"+
"<ping xmlns='urn:xmpp:ping'/>"+
"</iq>");
});
}));
});
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"underscore",
"mock",
"test_utils"
], function ($, _, mock, test_utils) {
return factory($, _, mock, test_utils);
}
);
} (this, function ($, _, mock, test_utils) {
var Strophe = converse_api.env.Strophe;
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
var _ = converse_api.env._;
var $iq = converse_api.env.$iq;
describe("Profiling", function() {
beforeEach(function() {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
converse.rosterview.model.reset();
converse.connection._changeConnectStatus(Strophe.Status.CONNECTED);
});
xit("adds hundreds of contacts to the roster", $.proxy(function() {
xit("adds hundreds of contacts to the roster", mock.initConverse(function(converse) {
converse.roster_groups = false;
expect(this.roster.pluck('jid').length).toBe(0);
var stanza = $iq({
......@@ -41,9 +31,9 @@
});
this.roster.onReceivedFromServer(stanza.tree());
// expect(this.roster.pluck('jid').length).toBe(400);
}, converse));
}));
xit("adds hundreds of contacts to the roster, with roster groups", $.proxy(function() {
xit("adds hundreds of contacts to the roster, with roster groups", mock.initConverse(function(converse) {
// converse.show_only_online_users = true;
converse.roster_groups = true;
expect(this.roster.pluck('jid').length).toBe(0);
......@@ -65,6 +55,6 @@
});
this.roster.onReceivedFromServer(stanza.tree());
//expect(this.roster.pluck('jid').length).toBe(400);
}, converse));
}));
});
}));
......@@ -23,6 +23,7 @@
afterEach(function () {
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
......
/*global converse */
(function (root, factory) {
define(["jquery", "mock", "test_utils"], factory);
} (this, function ($, mock, test_utils) {
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
var $ = converse_api.env.jQuery;
var Strophe = converse_api.env.Strophe;
var $iq = converse_api.env.$iq;
var original_connection = converse.connection;
describe("The Registration Panel", function () {
beforeEach(function () {
test_utils.closeControlBox();
converse._tearDown();
converse.initialized_plugins = [];
});
afterEach(function () {
test_utils.closeControlBox();
converse.connection = original_connection;
converse._initialize();
converse_api.user.logout();
converse_api.listen.not();
test_utils.clearBrowserStorage();
});
it("is not available unless allow_registration=true", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
test_utils.closeControlBox();
it("is not available unless allow_registration=true", mock.initConverse(function (converse) {
runs(test_utils.openControlBox);
waits(50);
runs(function () {
var cbview = converse.chatboxviews.get('controlbox');
expect(cbview.$('#controlbox-tabs li').length).toBe(1);
expect(cbview.$('#controlbox-tabs li').text().trim()).toBe("Sign in");
cbview = converse.chatboxviews.get('controlbox');
expect(cbview.$el.find('#controlbox-tabs li').length).toBe(2);
expect(cbview.$('#controlbox-tabs li').first().text().trim()).toBe("Sign in");
expect(cbview.$('#controlbox-tabs li').last().text().trim()).toBe("Register");
});
});
it("can be opened by clicking on the registration tab", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
test_utils.closeControlBox();
var cbview = converse.chatboxviews.get('controlbox');
}, { auto_login: false,
allow_registration: false,
}));
it("can be opened by clicking on the registration tab", mock.initConverse(function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
runs(test_utils.openControlBox);
waits(50);
runs(function () {
var $tabs = cbview.$('#controlbox-tabs');
var $panels = cbview.$('.controlbox-panes');
var $login = $panels.children().first();
......@@ -68,221 +43,184 @@
expect($registration.is(':visible')).toBe(true);
expect(cbview.switchTab).toHaveBeenCalled();
});
});
it("allows the user to choose an XMPP provider's domain", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
test_utils.closeControlBox();
var cbview = converse.chatboxviews.get('controlbox');
var registerview = cbview.registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect');
var $tabs = cbview.$('#controlbox-tabs');
$tabs.find('li').last().find('a').click(); // Click the Register tab
// Check the form layout
var $form = cbview.$('#converse-register');
expect($form.find('input').length).toEqual(2);
expect($form.find('input').first().attr('name')).toEqual('domain');
expect($form.find('input').last().attr('type')).toEqual('submit');
// Check that the input[type=domain] input is required
$form.find('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect($form.find('input[name=domain]').hasClass('error')).toBeTruthy();
// Check that the form is accepted if input[type=domain] has a value
$form.find('input[name=domain]').val('conversejs.org');
$form.find('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect(converse.connection.connect).toHaveBeenCalled();
});
});
it("will render a registration form as received from the XMPP provider", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
expect(registerview._registering).toBeFalsy();
expect(converse.connection.connected).toBeFalsy();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect(registerview._registering).toBeTruthy();
expect(converse.connection.connect).toHaveBeenCalled();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
expect(registerview.getRegistrationFields).toHaveBeenCalled();
expect(converse.connection.connected).toBeTruthy();
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Please choose a username, password and provide your email address').up()
.c('username').up()
.c('password').up()
.c('email');
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.onRegistrationFields).toHaveBeenCalled();
expect(registerview.renderRegistrationForm).toHaveBeenCalled();
expect(registerview.$('input').length).toBe(5);
expect(registerview.$('input[type=submit]').length).toBe(1);
expect(registerview.$('input[type=button]').length).toBe(1);
});
});
it("will set form_type to legacy and submit it as legacy", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
test_utils.closeControlBox();
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Please choose a username, password and provide your email address').up()
.c('username').up()
.c('password').up()
.c('email');
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.form_type).toBe('legacy');
registerview.$('input[name=username]').val('testusername');
registerview.$('input[name=password]').val('testpassword');
registerview.$('input[name=email]').val('test@email.local');
spyOn(converse.connection, 'send');
registerview.$('input[type=submit]').click();
expect(converse.connection.send).toHaveBeenCalled();
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.children('query').children().length).toBe(3);
expect($stanza.children('query').children()[0].tagName).toBe('username');
});
});
it("will set form_type to xform and submit it as xform", function () {
converse.initialize({
i18n: window.locales.en,
bosh_service_url: 'localhost',
allow_registration: true,
auto_subscribe: false,
animate: false,
connection: mock.mock_connection,
no_trimming: true,
debug: false
}, function (converse) {
test_utils.closeControlBox();
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Using xform data').up()
.c('x', { 'xmlns': 'jabber:x:data', 'type': 'form' })
.c('instructions').t('xform instructions').up()
.c('field', {'type': 'text-single', 'var': 'username'}).c('required').up().up()
.c('field', {'type': 'text-private', 'var': 'password'}).c('required').up().up()
.c('field', {'type': 'text-single', 'var': 'email'}).c('required').up().up();
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.form_type).toBe('xform');
registerview.$('input[name=username]').val('testusername');
registerview.$('input[name=password]').val('testpassword');
registerview.$('input[name=email]').val('test@email.local');
spyOn(converse.connection, 'send');
registerview.$('input[type=submit]').click();
expect(converse.connection.send).toHaveBeenCalled();
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.children('query').children().length).toBe(1);
expect($stanza.children('query').children().children().length).toBe(3);
expect($stanza.children('query').children().children()[0].tagName).toBe('field');
});
});
}, { auto_login: false,
allow_registration: true,
}));
it("allows the user to choose an XMPP provider's domain", mock.initConverse(function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
var registerview = cbview.registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect');
var $tabs = cbview.$('#controlbox-tabs');
$tabs.find('li').last().find('a').click(); // Click the Register tab
// Check the form layout
var $form = cbview.$('#converse-register');
expect($form.find('input').length).toEqual(2);
expect($form.find('input').first().attr('name')).toEqual('domain');
expect($form.find('input').last().attr('type')).toEqual('submit');
// Check that the input[type=domain] input is required
$form.find('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect($form.find('input[name=domain]').hasClass('error')).toBeTruthy();
// Check that the form is accepted if input[type=domain] has a value
$form.find('input[name=domain]').val('conversejs.org');
$form.find('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect(converse.connection.connect).toHaveBeenCalled();
}, { auto_login: false,
allow_registration: true,
}));
it("will render a registration form as received from the XMPP provider", mock.initConverse(function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
expect(registerview._registering).toBeFalsy();
expect(converse.connection.connected).toBeFalsy();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
expect(registerview.onProviderChosen).toHaveBeenCalled();
expect(registerview._registering).toBeTruthy();
expect(converse.connection.connect).toHaveBeenCalled();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
expect(registerview.getRegistrationFields).toHaveBeenCalled();
expect(converse.connection.connected).toBeTruthy();
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Please choose a username, password and provide your email address').up()
.c('username').up()
.c('password').up()
.c('email');
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.onRegistrationFields).toHaveBeenCalled();
expect(registerview.renderRegistrationForm).toHaveBeenCalled();
expect(registerview.$('input').length).toBe(5);
expect(registerview.$('input[type=submit]').length).toBe(1);
expect(registerview.$('input[type=button]').length).toBe(1);
}, { auto_login: false,
allow_registration: true,
}));
it("will set form_type to legacy and submit it as legacy", mock.initConverse(function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Please choose a username, password and provide your email address').up()
.c('username').up()
.c('password').up()
.c('email');
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.form_type).toBe('legacy');
registerview.$('input[name=username]').val('testusername');
registerview.$('input[name=password]').val('testpassword');
registerview.$('input[name=email]').val('test@email.local');
spyOn(converse.connection, 'send');
registerview.$('input[type=submit]').click();
expect(converse.connection.send).toHaveBeenCalled();
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.children('query').children().length).toBe(3);
expect($stanza.children('query').children()[0].tagName).toBe('username');
}, { auto_login: false,
allow_registration: true,
}));
it("will set form_type to xform and submit it as xform", mock.initConverse(function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(converse.connection, 'connect').andCallThrough();
registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click();
var stanza = new Strophe.Builder("stream:features", {
'xmlns:stream': "http://etherx.jabber.org/streams",
'xmlns': "jabber:client"
})
.c('register', {xmlns: "http://jabber.org/features/iq-register"}).up()
.c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"});
converse.connection._connect_cb(test_utils.createRequest(stanza));
stanza = $iq({
'type': 'result',
'id': 'reg1'
}).c('query', {'xmlns': 'jabber:iq:register'})
.c('instructions')
.t('Using xform data').up()
.c('x', { 'xmlns': 'jabber:x:data', 'type': 'form' })
.c('instructions').t('xform instructions').up()
.c('field', {'type': 'text-single', 'var': 'username'}).c('required').up().up()
.c('field', {'type': 'text-private', 'var': 'password'}).c('required').up().up()
.c('field', {'type': 'text-single', 'var': 'email'}).c('required').up().up();
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(registerview.form_type).toBe('xform');
registerview.$('input[name=username]').val('testusername');
registerview.$('input[name=password]').val('testpassword');
registerview.$('input[name=email]').val('test@email.local');
spyOn(converse.connection, 'send');
registerview.$('input[type=submit]').click();
expect(converse.connection.send).toHaveBeenCalled();
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.children('query').children().length).toBe(1);
expect($stanza.children('query').children().children().length).toBe(3);
expect($stanza.children('query').children().children()[0].tagName).toBe('field');
}, { auto_login: false,
allow_registration: true,
}));
});
}));
/*global converse */
(function (root, factory) {
define([
"jquery",
"mock",
"test_utils"
], function ($, mock, test_utils) {
return factory($, mock, test_utils);
}
);
} (this, function ($, mock, test_utils) {
return describe("The XMPPStatus model", $.proxy(function(mock, test_utils) {
beforeEach($.proxy(function () {
window.localStorage.clear();
window.sessionStorage.clear();
}, converse));
it("won't send <show>online when setting a custom status message", $.proxy(function () {
this.xmppstatus.save({'status': 'online'});
spyOn(this.xmppstatus, 'setStatusMessage').andCallThrough();
define(["mock", "test_utils"], factory);
} (this, function (mock, test_utils) {
var $ = converse_api.env.jQuery;
return describe("The XMPPStatus model", function() {
afterEach(function () {
converse_api.user.logout();
test_utils.clearBrowserStorage();
});
it("won't send <show>online when setting a custom status message", mock.initConverse(function (converse) {
converse.xmppstatus.save({'status': 'online'});
spyOn(converse.xmppstatus, 'setStatusMessage').andCallThrough();
spyOn(converse.connection, 'send');
this.xmppstatus.setStatusMessage("I'm also happy!");
converse.xmppstatus.setStatusMessage("I'm also happy!");
runs (function () {
expect(converse.connection.send).toHaveBeenCalled();
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
expect($stanza.children().length).toBe(1);
expect($stanza.children('show').length).toBe(0);
});
}, converse));
}, converse, mock, test_utils));
}));
});
}));
......@@ -164,11 +164,13 @@
callback = options;
errback = callback;
}
/*
if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
converse.log('This server does not support XEP-0313, Message Archive Management');
errback(null);
return;
}
*/
var queryid = converse.connection.getUniqueId();
var attrs = {'type':'set'};
if (typeof options !== "undefined" && options.groupchat) {
......
......@@ -10,6 +10,14 @@
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<script src="config.js"></script>
<script data-main="tests/main" src="node_modules/requirejs/require.js"></script>
<style>
body {
background-color: lightgoldenrodyellow;
}
h2 {
color: darkgray;
}
</style>
</head>
<body>
......
......@@ -50,13 +50,10 @@ require([
//"spec/transcripts",
"spec/utils",
"spec/converse",
/*
"spec/bookmarks",
"spec/headline",
"spec/disco",
*/
"spec/protocol",
/*
"spec/mam",
"spec/otr",
"spec/eventemitter",
......@@ -68,8 +65,7 @@ require([
"spec/profiling",
"spec/ping",
"spec/register",
"spec/xmppstatus",
*/
"spec/xmppstatus"
], function () {
// Jasmine stuff
var jasmineEnv = jasmine.getEnv();
......
......@@ -75,9 +75,9 @@
};
}();
mock.initConverse = function (func) {
mock.initConverse = function (func, settings) {
return function () {
var converse = converse_api.initialize({
var converse = converse_api.initialize(_.extend({
i18n: window.locales.en,
auto_subscribe: false,
bosh_service_url: 'localhost',
......@@ -86,9 +86,8 @@
no_trimming: true,
auto_login: true,
jid: 'dummy@localhost',
password: 'secret',
debug: true
});
password: 'secret'
}, settings || {}));
converse.ChatBoxViews.prototype.trimChat = function () {};
return func(converse);
};
......
......@@ -79,14 +79,14 @@
$tabs.find('li').first().find('a').click();
};
utils.openRoomsPanel = function () {
utils.openRoomsPanel = function (converse) {
utils.openControlBox();
var cbview = converse.chatboxviews.get('controlbox');
var $tabs = cbview.$el.find('#controlbox-tabs');
$tabs.find('li').last().find('a').click();
};
utils.openChatBoxes = function (amount) {
utils.openChatBoxes = function (converse, amount) {
var i = 0, jid, views = [];
for (i; i<amount; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
......@@ -99,25 +99,25 @@
return converse.roster.get(jid).trigger("open");
};
utils.openChatRoom = function (room, server, nick) {
utils.openChatRoom = function (converse, room, server, nick) {
// Open a new chatroom
this.openControlBox();
this.openRoomsPanel();
this.openControlBox(converse);
this.openRoomsPanel(converse);
var roomspanel = converse.chatboxviews.get('controlbox').roomspanel;
roomspanel.$el.find('input.new-chatroom-name').val(room);
roomspanel.$el.find('input.new-chatroom-nick').val(nick);
roomspanel.$el.find('input.new-chatroom-server').val(server);
roomspanel.$el.find('form').submit();
this.closeControlBox();
this.closeControlBox(converse);
};
utils.openAndEnterChatRoom = function (room, server, nick) {
utils.openAndEnterChatRoom = function (converse, room, server, nick) {
var IQ_id, sendIQ = converse.connection.sendIQ;
spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
utils.openChatRoom(room, server);
utils.openChatRoom(converse, room, server);
var view = converse.chatboxviews.get(room+'@'+server);
// The XMPP server returns the reserved nick for this user.
......@@ -160,7 +160,7 @@
return this;
};
utils.clearChatBoxMessages = function (jid) {
utils.clearChatBoxMessages = function (converse, jid) {
var view = converse.chatboxviews.get(jid);
view.$el.find('.chat-content').empty();
view.model.messages.reset();
......@@ -190,7 +190,9 @@
requesting = false;
ask = null;
} else if (type === 'all') {
this.createContacts('current').createContacts('requesting').createContacts('pending');
this.createContacts(converse, 'current')
.createContacts(converse, 'requesting')
.createContacts(converse, 'pending');
return this;
} else {
throw "Need to specify the type of contact to create";
......@@ -214,7 +216,7 @@
return this;
};
utils.createGroupedContacts = function () {
utils.createGroupedContacts = function (converse) {
/* Create grouped contacts
*/
var i=0, j=0;
......
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