diff --git a/spec/converse.js b/spec/converse.js
index 07091f650..33ec45582 100644
--- a/spec/converse.js
+++ b/spec/converse.js
@@ -1,4 +1,3 @@
-/*global converse */
(function (root, factory) {
define([
"jquery",
@@ -12,10 +11,15 @@
} (this, function ($, _, mock, test_utils) {
var b64_sha1 = converse_api.env.b64_sha1;
- return describe("Converse", $.proxy(function(mock, test_utils) {
+ describe("Converse", function() {
+
+ afterEach(function () {
+ converse_api.user.logout();
+ test_utils.clearBrowserStorage();
+ });
describe("Authentication", function () {
- it("needs either a bosh_service_url a websocket_url or both", function () {
+ it("needs either a bosh_service_url a websocket_url or both", mock.initConverse(function (converse) {
var url = converse.bosh_service_url;
var connection = converse.connection;
delete converse.bosh_service_url;
@@ -24,10 +28,10 @@
new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both."));
converse.bosh_service_url = url;
converse.connection = connection;
- });
+ }));
describe("with prebind", function () {
- it("needs a jid when also using keepalive", function () {
+ it("needs a jid when also using keepalive", mock.initConverse(function (converse) {
var authentication = converse.authentication;
var jid = converse.jid;
delete converse.jid;
@@ -38,9 +42,9 @@
converse.authentication= authentication;
converse.jid = jid;
converse.keepalive = false;
- });
+ }));
- it("needs jid, rid and sid values when not using keepalive", function () {
+ it("needs jid, rid and sid values when not using keepalive", mock.initConverse(function (converse) {
var authentication = converse.authentication;
var jid = converse.jid;
delete converse.jid;
@@ -50,13 +54,13 @@
converse.authentication= authentication;
converse.bosh_service_url = undefined;
converse.jid = jid;
- });
+ }));
});
});
describe("A chat state indication", function () {
- it("are sent out when the client becomes or stops being idle", function () {
+ it("are sent out when the client becomes or stops being idle", mock.initConverse(function (converse) {
spyOn(converse, 'sendCSI').andCallThrough();
var sent_stanza;
spyOn(converse.connection, 'send').andCallFake(function (stanza) {
@@ -85,12 +89,12 @@
// Reset values
converse.csi_waiting_time = 0;
converse.features['urn:xmpp:csi:0'] = false;
- });
+ }));
});
describe("Automatic status change", function () {
- it("happens when the client is idle for long enough", function () {
+ it("happens when the client is idle for long enough", mock.initConverse(function (converse) {
var i = 0;
// Usually initialized by registerIntervalHandler
converse.idle_seconds = 0;
@@ -124,26 +128,21 @@
converse.auto_away = 0;
converse.auto_xa = 0;
converse.auto_changed_status = false;
- });
+ }));
});
describe("The \"user\" grouping", function () {
describe("The \"status\" API", function () {
- beforeEach(function () {
- test_utils.closeAllChatBoxes();
- test_utils.clearBrowserStorage();
- converse.rosterview.model.reset();
- });
- it("has a method for getting the user's availability", function () {
+ it("has a method for getting the user's availability", mock.initConverse(function (converse) {
converse.xmppstatus.set('status', 'online');
expect(converse_api.user.status.get()).toBe('online');
converse.xmppstatus.set('status', 'dnd');
expect(converse_api.user.status.get()).toBe('dnd');
- });
+ }));
- it("has a method for setting the user's availability", function () {
+ it("has a method for setting the user's availability", mock.initConverse(function (converse) {
converse_api.user.status.set('away');
expect(converse.xmppstatus.get('status')).toBe('away');
converse_api.user.status.set('dnd');
@@ -155,38 +154,33 @@
expect(_.partial(converse_api.user.status.set, 'invalid')).toThrow(
new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1')
);
- });
+ }));
- it("allows setting the status message as well", function () {
+ it("allows setting the status message as well", mock.initConverse(function (converse) {
converse_api.user.status.set('away', "I'm in a meeting");
expect(converse.xmppstatus.get('status')).toBe('away');
expect(converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
- });
+ }));
- it("has a method for getting the user's status message", function () {
+ it("has a method for getting the user's status message", mock.initConverse(function (converse) {
converse.xmppstatus.set('status_message', undefined);
expect(converse_api.user.status.message.get()).toBe(undefined);
converse.xmppstatus.set('status_message', "I'm in a meeting");
expect(converse_api.user.status.message.get()).toBe("I'm in a meeting");
- });
+ }));
- it("has a method for setting the user's status message", function () {
+ it("has a method for setting the user's status message", mock.initConverse(function (converse) {
converse.xmppstatus.set('status_message', undefined);
converse_api.user.status.message.set("I'm in a meeting");
expect(converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
- });
+ }));
});
});
- describe("The \"tokens\" API", $.proxy(function () {
- beforeEach(function () {
- test_utils.closeAllChatBoxes();
- test_utils.clearBrowserStorage();
- converse.rosterview.model.reset();
- test_utils.createContacts('current');
- });
+ describe("The \"tokens\" API", function () {
- it("has a method for retrieving the next RID", $.proxy(function () {
+ it("has a method for retrieving the next RID", mock.initConverse(function (converse) {
+ test_utils.createContacts(converse, 'current');
var old_connection = converse.connection;
converse.connection._proto.rid = '1234';
converse.expose_rid_and_sid = false;
@@ -197,9 +191,10 @@
expect(converse_api.tokens.get('rid')).toBe(null);
// Restore the connection
converse.connection = old_connection;
- }, converse));
+ }));
- it("has a method for retrieving the SID", $.proxy(function () {
+ it("has a method for retrieving the SID", mock.initConverse(function (converse) {
+ test_utils.createContacts(converse, 'current');
var old_connection = converse.connection;
converse.connection._proto.sid = '1234';
converse.expose_rid_and_sid = false;
@@ -210,19 +205,14 @@
expect(converse_api.tokens.get('sid')).toBe(null);
// Restore the connection
converse.connection = old_connection;
- }, converse));
- }, converse));
+ }));
+ });
- describe("The \"contacts\" API", $.proxy(function () {
- beforeEach($.proxy(function () {
- test_utils.closeAllChatBoxes();
- test_utils.clearBrowserStorage();
- converse.rosterview.model.reset();
- test_utils.createContacts('current');
- }, converse));
+ describe("The \"contacts\" API", function () {
- it("has a method 'get' which returns wrapped contacts", $.proxy(function () {
+ it("has a method 'get' which returns wrapped contacts", mock.initConverse(function (converse) {
// Check that it returns nothing if a non-existing JID is given
+ test_utils.createContacts(converse, 'current');
expect(converse_api.contacts.get('non-existing@jabber.org')).toBeFalsy();
// Check when a single jid is given
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -239,28 +229,23 @@
// Check that all JIDs are returned if you call without any parameters
list = converse_api.contacts.get();
expect(list.length).toBe(mock.cur_names.length);
- }, converse));
+ }));
- it("has a method 'add' with which contacts can be added", $.proxy(function () {
+ it("has a method 'add' with which contacts can be added", mock.initConverse(function (converse) {
+ test_utils.createContacts(converse, 'current');
var error = new TypeError('contacts.add: invalid jid');
expect(converse_api.contacts.add).toThrow(error);
expect(converse_api.contacts.add.bind(converse_api, "invalid jid")).toThrow(error);
spyOn(converse.roster, 'addAndSubscribe');
converse_api.contacts.add("newcontact@example.org");
expect(converse.roster.addAndSubscribe).toHaveBeenCalled();
- }, converse));
+ }));
+ });
- }, converse));
+ describe("The \"chats\" API", function() {
- describe("The \"chats\" API", $.proxy(function() {
- beforeEach($.proxy(function () {
- test_utils.closeAllChatBoxes();
- test_utils.clearBrowserStorage();
- converse.rosterview.model.reset();
- test_utils.createContacts('current');
- }, converse));
-
- it("has a method 'get' which returns a wrapped chat box", function () {
+ it("has a method 'get' which returns a wrapped chat box", mock.initConverse(function (converse) {
+ test_utils.createContacts(converse, 'current');
// Test on chat that doesn't exist.
expect(converse_api.chats.get('non-existing@jabber.org')).toBeFalsy();
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -271,7 +256,7 @@
var chatboxview = converse.chatboxviews.get(jid);
// Test for single JID
- test_utils.openChatBoxFor(jid);
+ test_utils.openChatBoxFor(converse, jid);
box = converse_api.chats.get(jid);
expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid));
@@ -279,14 +264,15 @@
expect(chatboxview.$el.is(':visible')).toBeTruthy();
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
- test_utils.openChatBoxFor(jid2);
+ test_utils.openChatBoxFor(converse, jid2);
var list = converse_api.chats.get([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
- });
+ }));
- 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 jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var chatboxview;
waits('300'); // ChatBox.show() is debounced for 250ms
@@ -309,18 +295,11 @@
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
});
- });
- }, converse));
+ }));
+ });
- describe("The \"settings\" API", $.proxy(function() {
- beforeEach($.proxy(function () {
- test_utils.closeAllChatBoxes();
- test_utils.clearBrowserStorage();
- converse.rosterview.model.reset();
- test_utils.createContacts('current');
- }, converse));
-
- it("has methods 'get' and 'set' to set configuration settings", $.proxy(function () {
+ describe("The \"settings\" API", function() {
+ it("has methods 'get' and 'set' to set configuration settings", mock.initConverse(function (converse) {
expect(Object.keys(converse_api.settings)).toEqual(["get", "set"]);
expect(converse_api.settings.get("play_sounds")).toBe(false);
converse_api.settings.set("play_sounds", true);
@@ -331,7 +310,7 @@
expect(typeof converse_api.settings.get("non_existing")).toBe("undefined");
converse_api.settings.set("non_existing", true);
expect(typeof converse_api.settings.get("non_existing")).toBe("undefined");
- }, converse));
- }, converse));
- }, converse, mock, test_utils));
+ }));
+ });
+ });
}));
diff --git a/spec/protocol.js b/spec/protocol.js
index 6313dbbd0..ccb63641d 100644
--- a/spec/protocol.js
+++ b/spec/protocol.js
@@ -1,4 +1,3 @@
-/*global converse */
(function (root, factory) {
define([
"jquery",
@@ -16,14 +15,17 @@
// See:
// https://xmpp.org/rfcs/rfc3921.html
- describe("The Protocol", $.proxy(function (mock, test_utils) {
- beforeEach(function () {
- test_utils.removeControlBox();
- converse.roster.browserStorage._clear();
- test_utils.initConverse();
- });
+ describe("The Protocol", function () {
+
+ describe("Integration of Roster Items and Presence Subscriptions", function () {
+ // Stub the trimChat method. It causes havoc when running with
+ // phantomJS.
+
+ afterEach(function () {
+ converse_api.user.logout();
+ test_utils.clearBrowserStorage();
+ });
- describe("Integration of Roster Items and Presence Subscriptions", $.proxy(function (mock, test_utils) {
/* Some level of integration between roster items and presence
* subscriptions is normally expected by an instant messaging user
* regarding the user's subscriptions to and from other contacts. This
@@ -52,26 +54,24 @@
* that session. A client MUST acknowledge each roster push with an IQ
* stanza of type "result".
*/
- beforeEach(function () {
- test_utils.closeAllChatBoxes();
- test_utils.openControlBox();
- test_utils.openContactsPanel();
- });
-
- it("Subscribe to contact, contact accepts and subscribes back", $.proxy(function () {
+ it("Subscribe to contact, contact accepts and subscribes back", mock.initConverse(function (converse) {
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
var contact, stanza, sent_stanza, IQ_id;
- runs($.proxy(function () {
- var panel = this.chatboxviews.get('controlbox').contactspanel;
+ runs(function () {
+ test_utils.openControlBox(converse);
+ });
+ waits(100);
+ runs(function () {
+ var panel = converse.chatboxviews.get('controlbox').contactspanel;
spyOn(panel, "addContactFromForm").andCallThrough();
- spyOn(this.roster, "addAndSubscribe").andCallThrough();
- spyOn(this.roster, "addContact").andCallThrough();
- spyOn(this.roster, "sendContactAddIQ").andCallThrough();
- spyOn(this, "getVCard").andCallThrough();
- var sendIQ = this.connection.sendIQ;
- spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+ spyOn(converse.roster, "addAndSubscribe").andCallThrough();
+ spyOn(converse.roster, "addContact").andCallThrough();
+ spyOn(converse.roster, "sendContactAddIQ").andCallThrough();
+ spyOn(converse, "getVCard").andCallThrough();
+ var sendIQ = converse.connection.sendIQ;
+ spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@@ -99,7 +99,7 @@
// The form should not be visible anymore.
expect($form.is(":visible")).toBeFalsy();
- /* This request consists of sending an IQ
+ /* converse request consists of sending an IQ
* stanza of type='set' containing a element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an
* element that defines the new roster item; the
@@ -127,7 +127,7 @@
);
/* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated
- * with this user that have requested the roster, setting the
+ * with converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the
* success of the roster set:
@@ -157,17 +157,17 @@
'jid': 'contact@example.org',
'subscription': 'none',
'name': 'contact@example.org'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
/*
*
*/
stanza = $iq({'type': 'result', 'id':IQ_id});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
// A contact should now have been created
- expect(this.roster.get('contact@example.org') instanceof this.RosterContact).toBeTruthy();
+ expect(converse.roster.get('contact@example.org') instanceof converse.RosterContact).toBeTruthy();
expect(contact.get('jid')).toBe('contact@example.org');
- expect(this.getVCard).toHaveBeenCalled();
+ expect(converse.getVCard).toHaveBeenCalled();
/* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of
@@ -184,7 +184,7 @@
/* As a result, the user's server MUST initiate a second roster
* push to all of the user's available resources that have
* requested the roster, setting the contact to the pending
- * sub-state of the 'none' subscription state; this pending
+ * sub-state of the 'none' subscription state; converse pending
* sub-state is denoted by the inclusion of the ask='subscribe'
* attribute in the roster item:
*
@@ -208,11 +208,11 @@
'subscription': 'none',
'ask': 'subscribe',
'name': 'contact@example.org'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(converse.roster.updateContact).toHaveBeenCalled();
- }, this));
+ });
waits(50);
- runs($.proxy(function () {
+ runs(function () {
// Check that the user is now properly shown as a pending
// contact in the roster.
var $header = $('a:contains("Pending contacts")');
@@ -223,46 +223,46 @@
spyOn(contact, "ackSubscribe").andCallThrough();
/* Here we assume the "happy path" that the contact
- * approves the subscription request
- *
- *
- */
+ * approves the subscription request
+ *
+ *
+ */
stanza = $pres({
'to': converse.bare_jid,
'from': 'contact@example.org',
'type': 'subscribed'
});
sent_stanza = ""; // Reset
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
/* Upon receiving the presence stanza of type "subscribed",
- * the user SHOULD acknowledge receipt of that
- * subscription state notification by sending a presence
- * stanza of type "subscribe".
- */
+ * the user SHOULD acknowledge receipt of that
+ * subscription state notification by sending a presence
+ * stanza of type "subscribe".
+ */
expect(contact.ackSubscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
""
);
/* The user's server MUST initiate a roster push to all of the user's
- * available resources that have requested the roster,
- * containing an updated roster item for the contact with
- * the 'subscription' attribute set to a value of "to";
- *
- *
- *
- * -
- * MyBuddies
- *
- *
- *
- */
+ * available resources that have requested the roster,
+ * containing an updated roster item for the contact with
+ * the 'subscription' attribute set to a value of "to";
+ *
+ *
+ *
+ * -
+ * MyBuddies
+ *
+ *
+ *
+ */
IQ_id = converse.connection.getUniqueId('roster');
stanza = $iq({'type': 'set', 'id': IQ_id})
.c('query', {'xmlns': 'jabber:iq:roster'})
@@ -270,7 +270,7 @@
'jid': 'contact@example.org',
'subscription': 'to',
'name': 'contact@example.org'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
// Check that the IQ set was acknowledged.
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
""
@@ -292,78 +292,82 @@
expect(contact.get('chat_status')).toBe('offline');
/*
- */
+ * from='contact@example.org/resource'
+ * to='user@example.com/resource'/>
+ */
stanza = $pres({'to': converse.bare_jid, 'from': 'contact@example.org/resource'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
// Now the contact should also be online.
expect(contact.get('chat_status')).toBe('online');
/* Section 8.3. Creating a Mutual Subscription
- *
- * If the contact wants to create a mutual subscription,
- * the contact MUST send a subscription request to the
- * user.
- *
- *
- */
+ *
+ * If the contact wants to create a mutual subscription,
+ * the contact MUST send a subscription request to the
+ * user.
+ *
+ *
+ */
spyOn(contact, 'authorize').andCallThrough();
- spyOn(this.roster, 'handleIncomingSubscription').andCallThrough();
+ spyOn(converse.roster, 'handleIncomingSubscription').andCallThrough();
stanza = $pres({
'to': converse.bare_jid,
'from': 'contact@example.org/resource',
'type': 'subscribe'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
- expect(this.roster.handleIncomingSubscription).toHaveBeenCalled();
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
+ expect(converse.roster.handleIncomingSubscription).toHaveBeenCalled();
/* The user's client MUST send a presence stanza of type
- * "subscribed" to the contact in order to approve the
- * subscription request.
- *
- *
- */
+ * "subscribed" to the contact in order to approve the
+ * subscription request.
+ *
+ *
+ */
expect(contact.authorize).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
""
);
/* As a result, the user's server MUST initiate a
- * roster push containing a roster item for the
- * contact with the 'subscription' attribute set to
- * a value of "both".
- *
- *
- *
- * -
- * MyBuddies
- *
- *
- *
- */
+ * roster push containing a roster item for the
+ * contact with the 'subscription' attribute set to
+ * a value of "both".
+ *
+ *
+ *
+ * -
+ * MyBuddies
+ *
+ *
+ *
+ */
stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
'jid': 'contact@example.org',
'subscription': 'both',
'name': 'contact@example.org'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(converse.roster.updateContact).toHaveBeenCalled();
// The class on the contact will now have switched.
expect($contacts.hasClass('to')).toBeFalsy();
expect($contacts.hasClass('both')).toBeTruthy();
- }, this));
- }, converse));
+ });
+ }));
- it("Alternate Flow: Contact Declines Subscription Request", $.proxy(function () {
+ it("Alternate Flow: Contact Declines Subscription Request", mock.initConverse(function (converse) {
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
var contact, stanza, sent_stanza, sent_IQ;
- runs($.proxy(function () {
+ runs(function () {
+ test_utils.openControlBox(converse);
+ });
+ waits(100);
+ runs(function () {
// Add a new roster contact via roster push
stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
@@ -371,69 +375,69 @@
'subscription': 'none',
'ask': 'subscribe',
'name': 'contact@example.org'});
- this.connection._dataRecv(test_utils.createRequest(stanza));
- }, this));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
+ });
waits(50);
- runs($.proxy(function () {
+ runs(function () {
// A pending contact should now exist.
- contact = this.roster.get('contact@example.org');
- expect(this.roster.get('contact@example.org') instanceof this.RosterContact).toBeTruthy();
+ contact = converse.roster.get('contact@example.org');
+ expect(converse.roster.get('contact@example.org') instanceof converse.RosterContact).toBeTruthy();
spyOn(contact, "ackUnsubscribe").andCallThrough();
spyOn(converse.connection, 'send').andCallFake(function (stanza) {
sent_stanza = stanza;
});
- spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+ spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_IQ = iq;
});
/* We now assume the contact declines the subscription
- * requests.
- *
+ * requests.
+ *
/* Upon receiving the presence stanza of type "unsubscribed"
- * addressed to the user, the user's server (1) MUST deliver
- * that presence stanza to the user and (2) MUST initiate a
- * roster push to all of the user's available resources that
- * have requested the roster, containing an updated roster
- * item for the contact with the 'subscription' attribute
- * set to a value of "none" and with no 'ask' attribute:
- *
- *
- *
- *
- *
- * -
- * MyBuddies
- *
- *
- *
- */
+ * addressed to the user, the user's server (1) MUST deliver
+ * that presence stanza to the user and (2) MUST initiate a
+ * roster push to all of the user's available resources that
+ * have requested the roster, containing an updated roster
+ * item for the contact with the 'subscription' attribute
+ * set to a value of "none" and with no 'ask' attribute:
+ *
+ *
+ *
+ *
+ *
+ * -
+ * MyBuddies
+ *
+ *
+ *
+ */
// FIXME: also add the
stanza = $pres({
'to': converse.bare_jid,
'from': 'contact@example.org',
'type': 'unsubscribed'
});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
/* Upon receiving the presence stanza of type "unsubscribed",
- * the user SHOULD acknowledge receipt of that subscription
- * state notification through either "affirming" it by
- * sending a presence stanza of type "unsubscribe
- */
+ * the user SHOULD acknowledge receipt of that subscription
+ * state notification through either "affirming" it by
+ * sending a presence stanza of type "unsubscribe
+ */
expect(contact.ackUnsubscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
""
);
/* Converse.js will then also automatically remove the
- * contact from the user's roster.
- */
+ * contact from the user's roster.
+ */
expect(sent_IQ.toLocaleString()).toBe(
""+
""+
@@ -441,22 +445,23 @@
""+
""
);
- }, this));
- }, converse));
+ });
+ }));
- it("Unsubscribe to a contact when subscription is mutual", function () {
+ it("Unsubscribe to a contact when subscription is mutual", mock.initConverse(function (converse) {
var sent_IQ, IQ_id, jid = 'annegreet.gomez@localhost';
runs(function () {
- test_utils.createContacts('current');
+ test_utils.openControlBox(converse);
+ test_utils.createContacts(converse, 'current');
});
waits(50);
runs(function () {
spyOn(window, 'confirm').andReturn(true);
// We now have a contact we want to remove
- expect(this.roster.get(jid) instanceof this.RosterContact).toBeTruthy();
+ expect(converse.roster.get(jid) instanceof converse.RosterContact).toBeTruthy();
- var sendIQ = this.connection.sendIQ;
- spyOn(this.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+ var sendIQ = converse.connection.sendIQ;
+ spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_IQ = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@@ -467,24 +472,24 @@
expect(window.confirm).toHaveBeenCalled();
/* Section 8.6 Removing a Roster Item and Cancelling All
- * Subscriptions
- *
- * First the user is removed from the roster
- * Because there may be many steps involved in completely
- * removing a roster item and cancelling subscriptions in
- * both directions, the roster management protocol includes
- * a "shortcut" method for doing so. The process may be
- * initiated no matter what the current subscription state
- * is by sending a roster set containing an item for the
- * contact with the 'subscription' attribute set to a value
- * of "remove":
- *
- *
- *
- *
- *
- *
- */
+ * Subscriptions
+ *
+ * First the user is removed from the roster
+ * Because there may be many steps involved in completely
+ * removing a roster item and cancelling subscriptions in
+ * both directions, the roster management protocol includes
+ * a "shortcut" method for doing so. The process may be
+ * initiated no matter what the current subscription state
+ * is by sending a roster set containing an item for the
+ * contact with the 'subscription' attribute set to a value
+ * of "remove":
+ *
+ *
+ *
+ *
+ *
+ *
+ */
expect(sent_IQ.toLocaleString()).toBe(
""+
""+
@@ -495,21 +500,21 @@
// Receive confirmation from the contact's server
//
var stanza = $iq({'type': 'result', 'id':IQ_id});
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
// Our contact has now been removed
- expect(typeof this.roster.get(jid) === "undefined").toBeTruthy();
- }.bind(converse));
- }.bind(converse));
+ expect(typeof converse.roster.get(jid) === "undefined").toBeTruthy();
+ });
+ }));
- it("Receiving a subscription request", function () {
+ it("Receiving a subscription request", mock.initConverse(function (converse) {
runs(function () {
- test_utils.createContacts('current'); // Create some contacts so that we can test positioning
+ test_utils.openControlBox(converse);
+ test_utils.createContacts(converse, 'current'); // Create some contacts so that we can test positioning
});
waits(50);
runs(function () {
spyOn(converse, "emit");
- /*
- *
@@ -521,15 +526,15 @@
}).c('nick', {
'xmlns': Strophe.NS.NICK,
}).t('Clint Contact');
- this.connection._dataRecv(test_utils.createRequest(stanza));
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
var $header = $('a:contains("Contact requests")');
expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy();
var $contacts = $header.parent().nextUntil('dt', 'dd');
expect($contacts.length).toBe(1);
- }.bind(converse));
- }.bind(converse));
- }, converse, mock, test_utils));
- }, converse, mock, test_utils));
+ });
+ }));
+ });
+ });
}));
diff --git a/src/converse-core.js b/src/converse-core.js
index c72aa02c4..2c284c0d2 100755
--- a/src/converse-core.js
+++ b/src/converse-core.js
@@ -1950,6 +1950,15 @@
utils.merge(converse, settings);
utils.applyUserSettings(converse, settings, converse.user_settings);
};
+
+ // If initialize gets called a second time (e.g. during tests), then we
+ // need to re-apply all plugins (for a new converse instance), and we
+ // therefore need to clear this array that prevents plugins from being
+ // initialized twice.
+ // If initialize is called for the first time, then this array is empty
+ // in any case.
+ converse.pluggable.initialized_plugins = [];
+
converse.pluggable.initializePlugins({
'updateSettings': updateSettings,
'converse': converse
diff --git a/tests/main.js b/tests/main.js
index f21583c4a..6e0b32a9e 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -45,71 +45,49 @@ require([
window.localStorage.clear();
window.sessionStorage.clear();
- converse.initialize({
- i18n: window.locales.en,
- auto_subscribe: false,
- bosh_service_url: 'localhost',
- connection: mock.mock_connection,
- animate: false,
- no_trimming: true,
- auto_login: true,
- jid: 'dummy@localhost',
- password: 'secret',
- debug: true
- }).then(function (converse) {
- window.converse = converse;
- window.crypto = {
- getRandomValues: function (buf) {
- var i;
- for (i=0, len=buf.length; i-1; i--) {
chatbox = converse.chatboxes.models[i];
@@ -78,7 +73,7 @@
$('#controlbox').remove();
};
- utils.openContactsPanel = function () {
+ utils.openContactsPanel = function (converse) {
var cbview = converse.chatboxviews.get('controlbox');
var $tabs = cbview.$el.find('#controlbox-tabs');
$tabs.find('li').first().find('a').click();
@@ -100,7 +95,7 @@
return views;
};
- utils.openChatBoxFor = function (jid) {
+ utils.openChatBoxFor = function (converse, jid) {
return converse.roster.get(jid).trigger("open");
};
@@ -172,7 +167,7 @@
view.model.messages.browserStorage._clear();
};
- utils.createContacts = function (type, length) {
+ utils.createContacts = function (converse, type, length) {
/* Create current (as opposed to requesting or pending) contacts
* for the user's roster.
*