浏览代码

Make `converse.initialize` an `async` function

- Combine all test init functions into `initConverse`
- Use `async` functions in more tests
- Replace `var` with `let` and `const` in more tests
- New utils method `toStanza` which converts a string to a Node
JC Brand 6 年之前
父节点
当前提交
9f5031c278

+ 16 - 7
dist/converse.js

@@ -62984,7 +62984,7 @@ function cleanup() {
   initClientConfig();
   initClientConfig();
 }
 }
 
 
-_converse.initialize = function (settings, callback) {
+_converse.initialize = async function (settings, callback) {
   settings = !_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.isUndefined(settings) ? settings : {};
   settings = !_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.isUndefined(settings) ? settings : {};
   const init_promise = _converse_headless_utils_core__WEBPACK_IMPORTED_MODULE_11__["default"].getResolveablePromise();
   const init_promise = _converse_headless_utils_core__WEBPACK_IMPORTED_MODULE_11__["default"].getResolveablePromise();
 
 
@@ -63821,17 +63821,22 @@ _converse.initialize = function (settings, callback) {
     this.connection = settings.connection;
     this.connection = settings.connection;
   }
   }
 
 
-  if (!_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.isUndefined(_converse.connection) && _converse.connection.service === 'jasmine tests') {
+  if (_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.get(_converse.connection, 'service') === 'jasmine tests') {
     finishInitialization();
     finishInitialization();
     return _converse;
     return _converse;
-  } else if (_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.isUndefined(_i18n__WEBPACK_IMPORTED_MODULE_6__["default"])) {
-    finishInitialization();
-  } else {
-    _i18n__WEBPACK_IMPORTED_MODULE_6__["default"].fetchTranslations(_converse.locale, _converse.locales, _converse_headless_utils_core__WEBPACK_IMPORTED_MODULE_11__["default"].interpolate(_converse.locales_url, {
+  } else if (!_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.isUndefined(_i18n__WEBPACK_IMPORTED_MODULE_6__["default"])) {
+    const url = _converse_headless_utils_core__WEBPACK_IMPORTED_MODULE_11__["default"].interpolate(_converse.locales_url, {
       'locale': _converse.locale
       'locale': _converse.locale
-    })).catch(e => _converse.log(e.message, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.FATAL)).finally(finishInitialization).catch(e => _converse.log(e.message, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.FATAL));
+    });
+
+    try {
+      await _i18n__WEBPACK_IMPORTED_MODULE_6__["default"].fetchTranslations(_converse.locale, _converse.locales, url);
+    } catch (e) {
+      _converse.log(e.message, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.FATAL);
+    }
   }
   }
 
 
+  finishInitialization();
   return init_promise;
   return init_promise;
 };
 };
 /**
 /**
@@ -69717,6 +69722,10 @@ __webpack_require__.r(__webpack_exports__);
 
 
 const u = {};
 const u = {};
 
 
+u.toStanza = function (string) {
+  return strophe_js__WEBPACK_IMPORTED_MODULE_2__["Strophe"].xmlHtmlNode(string).firstElementChild;
+};
+
 u.getLongestSubstring = function (string, candidates) {
 u.getLongestSubstring = function (string, candidates) {
   function reducer(accumulator, current_value) {
   function reducer(accumulator, current_value) {
     if (string.startsWith(current_value)) {
     if (string.startsWith(current_value)) {

+ 2 - 2
spec/autocomplete.js

@@ -16,7 +16,7 @@
     describe("The nickname autocomplete feature", function () {
     describe("The nickname autocomplete feature", function () {
 
 
         it("shows all autocompletion options when the user presses @",
         it("shows all autocompletion options when the user presses @",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -60,7 +60,7 @@
         }));
         }));
 
 
         it("autocompletes when the user presses tab",
         it("autocompletes when the user presses tab",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 

+ 10 - 10
spec/bookmarks.js

@@ -19,7 +19,7 @@
 
 
     describe("A chat room", function () {
     describe("A chat room", function () {
 
 
-        it("can be bookmarked", mock.initConverseWithPromises(
+        it("can be bookmarked", mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
             async function (done, _converse) {
                 
                 
@@ -141,7 +141,7 @@
         }));
         }));
 
 
 
 
-        it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverseWithPromises(
+        it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
             async function (done, _converse) {
 
 
@@ -173,7 +173,7 @@
 
 
         describe("when bookmarked", function () {
         describe("when bookmarked", function () {
 
 
-            it("displays that it's bookmarked through its bookmark icon", mock.initConverseWithPromises(
+            it("displays that it's bookmarked through its bookmark icon", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -194,7 +194,7 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("can be unbookmarked", mock.initConverseWithPromises(
+            it("can be unbookmarked", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -270,7 +270,7 @@
 
 
         describe("and when autojoin is set", function () {
         describe("and when autojoin is set", function () {
 
 
-            it("will be be opened and joined automatically upon login", mock.initConverseWithPromises(
+            it("will be be opened and joined automatically upon login", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -303,7 +303,7 @@
 
 
     describe("Bookmarks", function () {
     describe("Bookmarks", function () {
 
 
-        it("can be pushed from the XMPP server", mock.initConverseWithPromises(
+        it("can be pushed from the XMPP server", mock.initConverse(
             ['send'], ['rosterGroupsFetched', 'connected'], {},
             ['send'], ['rosterGroupsFetched', 'connected'], {},
             async function (done, _converse) {
             async function (done, _converse) {
 
 
@@ -361,7 +361,7 @@
         }));
         }));
 
 
 
 
-        it("can be retrieved from the XMPP server", mock.initConverseWithPromises(
+        it("can be retrieved from the XMPP server", mock.initConverse(
             ['send'], ['chatBoxesFetched', 'roomsPanelRendered', 'rosterGroupsFetched'], {},
             ['send'], ['chatBoxesFetched', 'roomsPanelRendered', 'rosterGroupsFetched'], {},
             async function (done, _converse) {
             async function (done, _converse) {
 
 
@@ -452,7 +452,7 @@
 
 
         describe("The rooms panel", function () {
         describe("The rooms panel", function () {
 
 
-            it("shows a list of bookmarks", mock.initConverseWithPromises(
+            it("shows a list of bookmarks", mock.initConverse(
                 ['send'], ['rosterGroupsFetched'], {},
                 ['send'], ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -540,7 +540,7 @@
             }));
             }));
 
 
 
 
-            it("remembers the toggle state of the bookmarks list", mock.initConverseWithPromises(
+            it("remembers the toggle state of the bookmarks list", mock.initConverse(
                 ['send'], ['rosterGroupsFetched'], {},
                 ['send'], ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -606,7 +606,7 @@
 
 
     describe("When hide_open_bookmarks is true and a bookmarked room is opened", function () {
     describe("When hide_open_bookmarks is true and a bookmarked room is opened", function () {
 
 
-        it("can be closed", mock.initConverseWithPromises(
+        it("can be closed", mock.initConverse(
             null, ['rosterGroupsFetched'],
             null, ['rosterGroupsFetched'],
             { hide_open_bookmarks: true },
             { hide_open_bookmarks: true },
             async function (done, _converse) {
             async function (done, _converse) {

+ 61 - 61
spec/chatbox.js

@@ -19,7 +19,7 @@
         describe("A Chatbox", function () {
         describe("A Chatbox", function () {
 
 
             it("has a /help command to show the available commands",
             it("has a /help command to show the available commands",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -52,7 +52,7 @@
 
 
 
 
             it("supports the /me command",
             it("supports the /me command",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -99,7 +99,7 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("is created when you click on a roster item", mock.initConverseWithPromises(
+            it("is created when you click on a roster item", mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -140,17 +140,17 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("opens when a new message is received", mock.initConverseWithPromises(
+            it("opens when a new message is received", mock.initConverse(
                 null, ['rosterGroupsFetched'], {'allow_non_roster_messaging': true},
                 null, ['rosterGroupsFetched'], {'allow_non_roster_messaging': true},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-                const stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+sender_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>Hey\nHave you heard the news?</body>"+
-                    "</message>").firstChild;
+                const stanza = u.toStanza(`
+                    <message from="${sender_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>Hey\nHave you heard the news?</body>
+                    </message>`);
 
 
                 const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve));
                 const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
@@ -159,18 +159,18 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("doesn't open when a message without body is received", mock.initConverseWithPromises(
+            it("doesn't open when a message without body is received", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
                 test_utils.createContacts(_converse, 'current', 1);
                 test_utils.createContacts(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-                const stanza = Strophe.xmlHtmlNode(`
+                const stanza = u.toStanza(`
                     <message from="${sender_jid}"
                     <message from="${sender_jid}"
                              type="chat"
                              type="chat"
                              to="dummy@localhost/resource">
                              to="dummy@localhost/resource">
                         <composing xmlns="http://jabber.org/protocol/chatstates"/>
                         <composing xmlns="http://jabber.org/protocol/chatstates"/>
-                    </message>`).firstChild;
+                    </message>`);
                 const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve))
                 const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve))
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await test_utils.waitUntil(() => message_promise);
                 await test_utils.waitUntil(() => message_promise);
@@ -179,7 +179,7 @@
             }));
             }));
 
 
             it("can be trimmed to conserve space",
             it("can be trimmed to conserve space",
-                mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {},
+                mock.initConverse(null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
                 spyOn(_converse.chatboxviews, 'trimChats');
                 spyOn(_converse.chatboxviews, 'trimChats');
@@ -237,7 +237,7 @@
             }));
             }));
 
 
             it("can be opened in minimized mode initially",
             it("can be opened in minimized mode initially",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -259,7 +259,7 @@
 
 
 
 
             it("is focused if its already open and you click on its corresponding roster item",
             it("is focused if its already open and you click on its corresponding roster item",
-                mock.initConverseWithPromises(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
+                mock.initConverse(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
 
 
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
                 _converse.emit('rosterContactsFetched');
                 _converse.emit('rosterContactsFetched');
@@ -286,7 +286,7 @@
             }));
             }));
 
 
             it("can be saved to, and retrieved from, browserStorage",
             it("can be saved to, and retrieved from, browserStorage",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched',], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched',], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -323,7 +323,7 @@
             }));
             }));
 
 
             it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
             it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -359,7 +359,7 @@
             }));
             }));
 
 
             it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
             it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -401,7 +401,7 @@
             }));
             }));
 
 
             it("will be removed from browserStorage when closed",
             it("will be removed from browserStorage when closed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -443,7 +443,7 @@
             describe("A chat toolbar", function () {
             describe("A chat toolbar", function () {
 
 
                 it("can be found on each chat box",
                 it("can be found on each chat box",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -464,7 +464,7 @@
                 }));
                 }));
 
 
                 it("contains a button for inserting emojis",
                 it("contains a button for inserting emojis",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -495,7 +495,7 @@
                 }));
                 }));
 
 
                 it("can contain a button for starting a call",
                 it("can contain a button for starting a call",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -531,7 +531,7 @@
             describe("A Chat Status Notification", function () {
             describe("A Chat Status Notification", function () {
 
 
                 it("is ignored when it's a carbon copy of one of my own",
                 it("is ignored when it's a carbon copy of one of my own",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -540,30 +540,30 @@
 
 
                     const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                     const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                     await test_utils.openChatBoxFor(_converse, sender_jid);
                     await test_utils.openChatBoxFor(_converse, sender_jid);
-                    let stanza = Strophe.xmlHtmlNode(
+                    let stanza = u.toStanza(
                         `<message from="${sender_jid}"
                         `<message from="${sender_jid}"
                                  type="chat"
                                  type="chat"
                                  to="dummy@localhost/resource">
                                  to="dummy@localhost/resource">
                             <composing xmlns="http://jabber.org/protocol/chatstates"/>
                             <composing xmlns="http://jabber.org/protocol/chatstates"/>
                             <no-store xmlns="urn:xmpp:hints"/>
                             <no-store xmlns="urn:xmpp:hints"/>
                             <no-permanent-store xmlns="urn:xmpp:hints"/>
                             <no-permanent-store xmlns="urn:xmpp:hints"/>
-                        </message>`).firstChild;
+                        </message>`);
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
 
-                    stanza = Strophe.xmlHtmlNode(
+                    stanza = u.toStanza(
                         `<message from="${sender_jid}"
                         `<message from="${sender_jid}"
                                  type="chat"
                                  type="chat"
                                  to="dummy@localhost/resource">
                                  to="dummy@localhost/resource">
                             <paused xmlns="http://jabber.org/protocol/chatstates"/>
                             <paused xmlns="http://jabber.org/protocol/chatstates"/>
                             <no-store xmlns="urn:xmpp:hints"/>
                             <no-store xmlns="urn:xmpp:hints"/>
                             <no-permanent-store xmlns="urn:xmpp:hints"/>
                             <no-permanent-store xmlns="urn:xmpp:hints"/>
-                        </message>`).firstChild;
+                        </message>`);
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
                     done();
                     done();
                 }));
                 }));
 
 
                 it("does not open a new chatbox",
                 it("does not open a new chatbox",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -587,7 +587,7 @@
                 describe("An active notification", function () {
                 describe("An active notification", function () {
 
 
                     it("is sent when the user opens a chat box",
                     it("is sent when the user opens a chat box",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -610,7 +610,7 @@
                         done();
                         done();
                     }));
                     }));
 
 
-                    it("is sent when the user maximizes a minimized a chat box", mock.initConverseWithPromises(
+                    it("is sent when the user maximizes a minimized a chat box", mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -645,7 +645,7 @@
                 describe("A composing notification", function () {
                 describe("A composing notification", function () {
 
 
                     it("is sent as soon as the user starts typing a message which is not a command",
                     it("is sent as soon as the user starts typing a message which is not a command",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -683,7 +683,7 @@
                     }));
                     }));
 
 
                     it("will be shown if received",
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -729,7 +729,7 @@
                     }));
                     }));
 
 
                     it("can be a composing carbon message that this user sent from a different client",
                     it("can be a composing carbon message that this user sent from a different client",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -776,7 +776,7 @@
                 describe("A paused notification", function () {
                 describe("A paused notification", function () {
 
 
                     it("is sent if the user has stopped typing since 30 seconds",
                     it("is sent if the user has stopped typing since 30 seconds",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -831,7 +831,7 @@
                     }));
                     }));
 
 
                     it("will be shown if received",
                     it("will be shown if received",
-                            mock.initConverseWithPromises(
+                            mock.initConverse(
                                 null, ['rosterGroupsFetched'], {},
                                 null, ['rosterGroupsFetched'], {},
                                 async function (done, _converse) {
                                 async function (done, _converse) {
 
 
@@ -860,7 +860,7 @@
                     }));
                     }));
 
 
                     it("can be a paused carbon message that this user sent from a different client",
                     it("can be a paused carbon message that this user sent from a different client",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -907,7 +907,7 @@
                 describe("An inactive notifciation", function () {
                 describe("An inactive notifciation", function () {
 
 
                     it("is sent if the user has stopped typing since 2 minutes",
                     it("is sent if the user has stopped typing since 2 minutes",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -959,7 +959,7 @@
                     }));
                     }));
 
 
                     it("is sent when the user a minimizes a chat box",
                     it("is sent when the user a minimizes a chat box",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -981,7 +981,7 @@
                     }));
                     }));
 
 
                     it("is sent if the user closes a chat box",
                     it("is sent if the user closes a chat box",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -1006,7 +1006,7 @@
                     }));
                     }));
 
 
                     it("will clear any other chat status notifications",
                     it("will clear any other chat status notifications",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -1049,7 +1049,7 @@
                 describe("A gone notifciation", function () {
                 describe("A gone notifciation", function () {
 
 
                     it("will be shown if received",
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -1080,7 +1080,7 @@
         describe("Special Messages", function () {
         describe("Special Messages", function () {
 
 
             it("'/clear' can be used to clear messages in a conversation",
             it("'/clear' can be used to clear messages in a conversation",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1123,7 +1123,7 @@
         describe("A Message Counter", function () {
         describe("A Message Counter", function () {
 
 
             it("is incremented when the message is received and the window is not focused",
             it("is incremented when the message is received and the window is not focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1163,7 +1163,7 @@
             }));
             }));
 
 
             it("is cleared when the window is focused",
             it("is cleared when the window is focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1178,7 +1178,7 @@
             }));
             }));
 
 
             it("is not incremented when the message is received and the window is focused",
             it("is not incremented when the message is received and the window is focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1204,7 +1204,7 @@
             }));
             }));
 
 
             it("is incremented from zero when chatbox was closed after viewing previously received messages and the window is not focused now",
             it("is incremented from zero when chatbox was closed after viewing previously received messages and the window is not focused now",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1256,7 +1256,7 @@
         describe("A ChatBox's Unread Message Count", function () {
         describe("A ChatBox's Unread Message Count", function () {
 
 
             it("is incremented when the message is received and ChatBoxView is scrolled up",
             it("is incremented when the message is received and ChatBoxView is scrolled up",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1275,7 +1275,7 @@
             }));
             }));
 
 
             it("is not incremented when the message is received and ChatBoxView is scrolled down",
             it("is not incremented when the message is received and ChatBoxView is scrolled down",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1293,7 +1293,7 @@
             }));
             }));
 
 
             it("is incremeted when message is received, chatbox is scrolled down and the window is not focused",
             it("is incremeted when message is received, chatbox is scrolled down and the window is not focused",
-                mock.initConverseWithPromises(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
+                mock.initConverse(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
@@ -1313,7 +1313,7 @@
             }));
             }));
 
 
             it("is incremeted when message is received, chatbox is scrolled up and the window is not focused",
             it("is incremeted when message is received, chatbox is scrolled up and the window is not focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1332,7 +1332,7 @@
             }));
             }));
 
 
             it("is cleared when ChatBoxView was scrolled down and the window become focused",
             it("is cleared when ChatBoxView was scrolled down and the window become focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1352,7 +1352,7 @@
             }));
             }));
 
 
             it("is not cleared when ChatBoxView was scrolled up and the windows become focused",
             it("is not cleared when ChatBoxView was scrolled up and the windows become focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1376,7 +1376,7 @@
         describe("A RosterView's Unread Message Count", function () {
         describe("A RosterView's Unread Message Count", function () {
 
 
             it("is updated when message is received and chatbox is scrolled up",
             it("is updated when message is received and chatbox is scrolled up",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1405,7 +1405,7 @@
             }));
             }));
 
 
             it("is updated when message is received and chatbox is minimized",
             it("is updated when message is received and chatbox is minimized",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1436,7 +1436,7 @@
             }));
             }));
 
 
             it("is cleared when chatbox is maximzied after receiving messages in minimized mode",
             it("is cleared when chatbox is maximzied after receiving messages in minimized mode",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1463,7 +1463,7 @@
             }));
             }));
 
 
             it("is cleared when unread messages are viewed which were received in scrolled-up chatbox",
             it("is cleared when unread messages are viewed which were received in scrolled-up chatbox",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1488,7 +1488,7 @@
             }));
             }));
 
 
             it("is not cleared after user clicks on roster view when chatbox is already opened and scrolled up",
             it("is not cleared after user clicks on roster view when chatbox is already opened and scrolled up",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1517,7 +1517,7 @@
         describe("A Minimized ChatBoxView's Unread Message Count", function () {
         describe("A Minimized ChatBoxView's Unread Message Count", function () {
 
 
             it("is displayed when scrolled up chatbox is minimized after receiving unread messages",
             it("is displayed when scrolled up chatbox is minimized after receiving unread messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1546,7 +1546,7 @@
             }));
             }));
 
 
             it("is incremented when message is received and windows is not focused",
             it("is incremented when message is received and windows is not focused",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1572,7 +1572,7 @@
             }));
             }));
 
 
             it("will render Openstreetmap-URL from geo-URI",
             it("will render Openstreetmap-URL from geo-URI",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 

+ 8 - 8
spec/controlbox.js

@@ -12,7 +12,7 @@
     describe("The Controlbox", function () {
     describe("The Controlbox", function () {
 
 
         it("can be opened by clicking a DOM element with class 'toggle-controlbox'",
         it("can be opened by clicking a DOM element with class 'toggle-controlbox'",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 
@@ -35,7 +35,7 @@
         describe("The \"Contacts\" section", function () {
         describe("The \"Contacts\" section", function () {
 
 
             it("can be used to add contact and it checks for case-sensivity", 
             it("can be used to add contact and it checks for case-sensivity", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -63,7 +63,7 @@
             }));
             }));
 
 
             it("shows the number of unread mentions received",
             it("shows the number of unread mentions received",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -113,7 +113,7 @@
         describe("The Status Widget", function () {
         describe("The Status Widget", function () {
 
 
             it("shows the user's chat status, which is online by default",
             it("shows the user's chat status, which is online by default",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -125,7 +125,7 @@
             }));
             }));
 
 
             it("can be used to set the current user's chat status",
             it("can be used to set the current user's chat status",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -149,7 +149,7 @@
             }));
             }));
 
 
             it("can be used to set a custom status message",
             it("can be used to set a custom status message",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -178,7 +178,7 @@
     describe("The 'Add Contact' widget", function () {
     describe("The 'Add Contact' widget", function () {
 
 
         it("opens up an add modal when you click on it",
         it("opens up an add modal when you click on it",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -215,7 +215,7 @@
 
 
 
 
         it("integrates with xhr_user_search_url to search for contacts", 
         it("integrates with xhr_user_search_url to search for contacts", 
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'],
                 null, ['rosterGroupsFetched'],
                 { 'xhr_user_search': true,
                 { 'xhr_user_search': true,
                   'xhr_user_search_url': 'http://example.org/'
                   'xhr_user_search_url': 'http://example.org/'

+ 54 - 38
spec/converse.js

@@ -12,7 +12,7 @@
         
         
         describe("Authentication", function () {
         describe("Authentication", function () {
 
 
-            it("needs either a bosh_service_url a websocket_url or both", mock.initConverse(function (_converse) {
+            it("needs either a bosh_service_url a websocket_url or both", mock.initConverse((done, _converse) => {
                 const url = _converse.bosh_service_url;
                 const url = _converse.bosh_service_url;
                 const connection = _converse.connection;
                 const connection = _converse.connection;
                 delete _converse.bosh_service_url;
                 delete _converse.bosh_service_url;
@@ -21,12 +21,13 @@
                     new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both."));
                     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.bosh_service_url = url;
                 _converse.connection = connection;
                 _converse.connection = connection;
+                done();
             }));
             }));
 
 
             describe("with prebind", function () {
             describe("with prebind", function () {
-                it("needs a jid when also using keepalive", mock.initConverse(function (_converse) {
-                    var authentication = _converse.authentication;
-                    var jid = _converse.jid;
+                it("needs a jid when also using keepalive", mock.initConverse((done, _converse) => {
+                    const authentication = _converse.authentication;
+                    const jid = _converse.jid;
                     delete _converse.jid;
                     delete _converse.jid;
                     _converse.keepalive = true;
                     _converse.keepalive = true;
                     _converse.authentication = "prebind";
                     _converse.authentication = "prebind";
@@ -37,10 +38,11 @@
                     _converse.authentication= authentication;
                     _converse.authentication= authentication;
                     _converse.jid = jid;
                     _converse.jid = jid;
                     _converse.keepalive = false;
                     _converse.keepalive = false;
+                    done();
                 }));
                 }));
 
 
-                it("needs jid, rid and sid values when not using keepalive", mock.initConverse(function (_converse) {
-                    var jid = _converse.jid;
+                it("needs jid, rid and sid values when not using keepalive", mock.initConverse((done, _converse) => {
+                    const jid = _converse.jid;
                     delete _converse.jid;
                     delete _converse.jid;
                     _converse.keepalive = false;
                     _converse.keepalive = false;
                     _converse.authentication = "prebind";
                     _converse.authentication = "prebind";
@@ -48,6 +50,7 @@
                         new Error("attemptPreboundSession: If you use prebind and not keepalive, then you MUST supply JID, RID and SID values or a prebind_url."));
                         new Error("attemptPreboundSession: If you use prebind and not keepalive, then you MUST supply JID, RID and SID values or a prebind_url."));
                     _converse.bosh_service_url = undefined;
                     _converse.bosh_service_url = undefined;
                     _converse.jid = jid;
                     _converse.jid = jid;
+                    done();
                 }));
                 }));
             });
             });
         });
         });
@@ -55,16 +58,14 @@
         describe("A chat state indication", function () {
         describe("A chat state indication", function () {
 
 
             it("are sent out when the client becomes or stops being idle",
             it("are sent out when the client becomes or stops being idle",
-                mock.initConverseWithPromises(
-                    null, ['discoInitialized'], {},
-                    function (done, _converse) {
+                mock.initConverse(null, ['discoInitialized'], {}, (done, _converse) => {
 
 
                 spyOn(_converse, 'sendCSI').and.callThrough();
                 spyOn(_converse, 'sendCSI').and.callThrough();
-                var sent_stanza;
+                let sent_stanza;
                 spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
                 spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
                     sent_stanza = stanza;
                     sent_stanza = stanza;
                 });
                 });
-                var i = 0;
+                let i = 0;
                 _converse.idle_seconds = 0; // Usually initialized by registerIntervalHandler
                 _converse.idle_seconds = 0; // Usually initialized by registerIntervalHandler
                 _converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = true; // Mock that the server supports CSI
                 _converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = true; // Mock that the server supports CSI
 
 
@@ -88,8 +89,8 @@
 
 
         describe("Automatic status change", function () {
         describe("Automatic status change", function () {
 
 
-            it("happens when the client is idle for long enough", mock.initConverse(function (_converse) {
-                var i = 0;
+            it("happens when the client is idle for long enough", mock.initConverse((done, _converse) => {
+                let i = 0;
                 // Usually initialized by registerIntervalHandler
                 // Usually initialized by registerIntervalHandler
                 _converse.idle_seconds = 0;
                 _converse.idle_seconds = 0;
                 _converse.auto_changed_status = false;
                 _converse.auto_changed_status = false;
@@ -156,6 +157,7 @@
                 _converse.onUserActivity();
                 _converse.onUserActivity();
                 expect(_converse.api.user.status.get()).toBe('dnd');
                 expect(_converse.api.user.status.get()).toBe('dnd');
                 expect(_converse.auto_changed_status).toBe(false);
                 expect(_converse.auto_changed_status).toBe(false);
+                done();
             }));
             }));
         });
         });
 
 
@@ -163,14 +165,15 @@
 
 
             describe("The \"status\" API", function () {
             describe("The \"status\" API", function () {
 
 
-                it("has a method for getting the user's availability", mock.initConverse(function (_converse) {
+                it("has a method for getting the user's availability", mock.initConverse((done, _converse) => {
                     _converse.xmppstatus.set('status', 'online');
                     _converse.xmppstatus.set('status', 'online');
                     expect(_converse.api.user.status.get()).toBe('online');
                     expect(_converse.api.user.status.get()).toBe('online');
                     _converse.xmppstatus.set('status', 'dnd');
                     _converse.xmppstatus.set('status', 'dnd');
                     expect(_converse.api.user.status.get()).toBe('dnd');
                     expect(_converse.api.user.status.get()).toBe('dnd');
+                    done();
                 }));
                 }));
 
 
-                it("has a method for setting the user's availability", mock.initConverse(function (_converse) {
+                it("has a method for setting the user's availability", mock.initConverse((done, _converse) => {
                     _converse.api.user.status.set('away');
                     _converse.api.user.status.set('away');
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     _converse.api.user.status.set('dnd');
                     _converse.api.user.status.set('dnd');
@@ -182,34 +185,38 @@
                     expect(_.partial(_converse.api.user.status.set, 'invalid')).toThrow(
                     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')
                         new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1')
                     );
                     );
+                    done();
                 }));
                 }));
 
 
-                it("allows setting the status message as well", mock.initConverse(function (_converse) {
+                it("allows setting the status message as well", mock.initConverse((done, _converse) => {
                     _converse.api.user.status.set('away', "I'm in a meeting");
                     _converse.api.user.status.set('away', "I'm in a meeting");
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     expect(_converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
                     expect(_converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
+                    done();
                 }));
                 }));
 
 
-                it("has a method for getting the user's status message", mock.initConverse(function (_converse) {
+                it("has a method for getting the user's status message", mock.initConverse((done, _converse) => {
                     _converse.xmppstatus.set('status_message', undefined);
                     _converse.xmppstatus.set('status_message', undefined);
                     expect(_converse.api.user.status.message.get()).toBe(undefined);
                     expect(_converse.api.user.status.message.get()).toBe(undefined);
                     _converse.xmppstatus.set('status_message', "I'm in a meeting");
                     _converse.xmppstatus.set('status_message', "I'm in a meeting");
                     expect(_converse.api.user.status.message.get()).toBe("I'm in a meeting");
                     expect(_converse.api.user.status.message.get()).toBe("I'm in a meeting");
+                    done();
                 }));
                 }));
 
 
-                it("has a method for setting the user's status message", mock.initConverse(function (_converse) {
+                it("has a method for setting the user's status message", mock.initConverse((done, _converse) => {
                     _converse.xmppstatus.set('status_message', undefined);
                     _converse.xmppstatus.set('status_message', undefined);
                     _converse.api.user.status.message.set("I'm in a meeting");
                     _converse.api.user.status.message.set("I'm in a meeting");
                     expect(_converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
                     expect(_converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
+                    done();
                 }));
                 }));
             });
             });
         });
         });
 
 
         describe("The \"tokens\" API", function () {
         describe("The \"tokens\" API", function () {
 
 
-            it("has a method for retrieving the next RID", mock.initConverse(function (_converse) {
+            it("has a method for retrieving the next RID", mock.initConverse((done, _converse) => {
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
-                var old_connection = _converse.connection;
+                const old_connection = _converse.connection;
                 _converse.connection._proto.rid = '1234';
                 _converse.connection._proto.rid = '1234';
                 _converse.expose_rid_and_sid = false;
                 _converse.expose_rid_and_sid = false;
                 expect(_converse.api.tokens.get('rid')).toBe(null);
                 expect(_converse.api.tokens.get('rid')).toBe(null);
@@ -219,11 +226,12 @@
                 expect(_converse.api.tokens.get('rid')).toBe(null);
                 expect(_converse.api.tokens.get('rid')).toBe(null);
                 // Restore the connection
                 // Restore the connection
                 _converse.connection = old_connection;
                 _converse.connection = old_connection;
+                done();
             }));
             }));
 
 
-            it("has a method for retrieving the SID", mock.initConverse(function (_converse) {
+            it("has a method for retrieving the SID", mock.initConverse((done, _converse) => {
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
-                var old_connection = _converse.connection;
+                const old_connection = _converse.connection;
                 _converse.connection._proto.sid = '1234';
                 _converse.connection._proto.sid = '1234';
                 _converse.expose_rid_and_sid = false;
                 _converse.expose_rid_and_sid = false;
                 expect(_converse.api.tokens.get('sid')).toBe(null);
                 expect(_converse.api.tokens.get('sid')).toBe(null);
@@ -233,47 +241,50 @@
                 expect(_converse.api.tokens.get('sid')).toBe(null);
                 expect(_converse.api.tokens.get('sid')).toBe(null);
                 // Restore the connection
                 // Restore the connection
                 _converse.connection = old_connection;
                 _converse.connection = old_connection;
+                done();
             }));
             }));
         });
         });
 
 
         describe("The \"contacts\" API", function () {
         describe("The \"contacts\" API", function () {
 
 
-            it("has a method 'get' which returns wrapped contacts", mock.initConverse(function (_converse) {
+            it("has a method 'get' which returns wrapped contacts", mock.initConverse((done, _converse) => {
                 // Check that it returns nothing if a non-existing JID is given
                 // Check that it returns nothing if a non-existing JID is given
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
                 expect(_converse.api.contacts.get('non-existing@jabber.org')).toBeFalsy();
                 expect(_converse.api.contacts.get('non-existing@jabber.org')).toBeFalsy();
                 // Check when a single jid is given
                 // Check when a single jid is given
-                var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-                var contact = _converse.api.contacts.get(jid);
+                const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+                const contact = _converse.api.contacts.get(jid);
                 expect(contact.get('fullname')).toBe(mock.cur_names[0]);
                 expect(contact.get('fullname')).toBe(mock.cur_names[0]);
                 expect(contact.get('jid')).toBe(jid);
                 expect(contact.get('jid')).toBe(jid);
                 // You can retrieve multiple contacts by passing in an array
                 // You can retrieve multiple contacts by passing in an array
-                var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
-                var list = _converse.api.contacts.get([jid, jid2]);
+                const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
+                let list = _converse.api.contacts.get([jid, jid2]);
                 expect(_.isArray(list)).toBeTruthy();
                 expect(_.isArray(list)).toBeTruthy();
                 expect(list[0].get('fullname')).toBe(mock.cur_names[0]);
                 expect(list[0].get('fullname')).toBe(mock.cur_names[0]);
                 expect(list[1].get('fullname')).toBe(mock.cur_names[1]);
                 expect(list[1].get('fullname')).toBe(mock.cur_names[1]);
                 // Check that all JIDs are returned if you call without any parameters
                 // Check that all JIDs are returned if you call without any parameters
                 list = _converse.api.contacts.get();
                 list = _converse.api.contacts.get();
                 expect(list.length).toBe(mock.cur_names.length);
                 expect(list.length).toBe(mock.cur_names.length);
+                done();
             }));
             }));
 
 
-            it("has a method 'add' with which contacts can be added", mock.initConverse(function (_converse) {
+            it("has a method 'add' with which contacts can be added", mock.initConverse((done, _converse) => {
                 test_utils.createContacts(_converse, 'current');
                 test_utils.createContacts(_converse, 'current');
-                var error = new TypeError('contacts.add: invalid jid');
+                const error = new TypeError('contacts.add: invalid jid');
                 expect(_converse.api.contacts.add).toThrow(error);
                 expect(_converse.api.contacts.add).toThrow(error);
                 expect(_converse.api.contacts.add.bind(_converse.api, "invalid jid")).toThrow(error);
                 expect(_converse.api.contacts.add.bind(_converse.api, "invalid jid")).toThrow(error);
                 spyOn(_converse.roster, 'addAndSubscribe');
                 spyOn(_converse.roster, 'addAndSubscribe');
                 _converse.api.contacts.add("newcontact@example.org");
                 _converse.api.contacts.add("newcontact@example.org");
                 expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
                 expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
+                done();
             }));
             }));
         });
         });
 
 
         describe("The \"chats\" API", function() {
         describe("The \"chats\" API", function() {
 
 
-            it("has a method 'get' which returns the promise that resolves to a chat model", mock.initConverseWithPromises(
+            it("has a method 'get' which returns the promise that resolves to a chat model", mock.initConverse(
                 null, ['rosterInitialized', 'chatBoxesInitialized'], {},
                 null, ['rosterInitialized', 'chatBoxesInitialized'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
                 test_utils.openControlBox();
                 test_utils.openControlBox();
                 test_utils.createContacts(_converse, 'current', 2);
                 test_utils.createContacts(_converse, 'current', 2);
@@ -308,9 +319,9 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("has a method 'open' which opens and returns a promise that resolves to a chat model", mock.initConverseWithPromises(
+            it("has a method 'open' which opens and returns a promise that resolves to a chat model", mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesInitialized'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesInitialized'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
                 test_utils.openControlBox();
                 test_utils.openControlBox();
                 test_utils.createContacts(_converse, 'current', 2);
                 test_utils.createContacts(_converse, 'current', 2);
@@ -341,8 +352,8 @@
 
 
         describe("The \"settings\" API", function() {
         describe("The \"settings\" API", function() {
             it("has methods 'get' and 'set' to set configuration settings", mock.initConverse(
             it("has methods 'get' and 'set' to set configuration settings", mock.initConverse(
-                    {'play_sounds': true}, 
-                    function (_converse) {
+                    null, null, {'play_sounds': true}, 
+                    (done, _converse) => {
 
 
                 expect(_.keys(_converse.api.settings)).toEqual(["update", "get", "set"]);
                 expect(_.keys(_converse.api.settings)).toEqual(["update", "get", "set"]);
                 expect(_converse.api.settings.get("play_sounds")).toBe(true);
                 expect(_converse.api.settings.get("play_sounds")).toBe(true);
@@ -354,11 +365,12 @@
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
                 _converse.api.settings.set("non_existing", true);
                 _converse.api.settings.set("non_existing", true);
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
+                done();
             }));
             }));
         });
         });
 
 
         describe("The \"plugins\" API", function() {
         describe("The \"plugins\" API", function() {
-            it("only has a method 'add' for registering plugins", mock.initConverse(function (_converse) {
+            it("only has a method 'add' for registering plugins", mock.initConverse((done, _converse) => {
                 expect(_.keys(converse.plugins)).toEqual(["add"]);
                 expect(_.keys(converse.plugins)).toEqual(["add"]);
                 // Cheating a little bit. We clear the plugins to test more easily.
                 // Cheating a little bit. We clear the plugins to test more easily.
                 const _old_plugins = _converse.pluggable.plugins;
                 const _old_plugins = _converse.pluggable.plugins;
@@ -368,13 +380,17 @@
                 converse.plugins.add('plugin2', {});
                 converse.plugins.add('plugin2', {});
                 expect(_.keys(_converse.pluggable.plugins)).toEqual(['plugin1', 'plugin2']);
                 expect(_.keys(_converse.pluggable.plugins)).toEqual(['plugin1', 'plugin2']);
                 _converse.pluggable.plugins = _old_plugins;
                 _converse.pluggable.plugins = _old_plugins;
+                done();
             }));
             }));
 
 
             describe("The \"plugins.add\" method", function() {
             describe("The \"plugins.add\" method", function() {
-                it("throws an error when multiple plugins attempt to register with the same name", mock.initConverse(function (_converse) {
+                it("throws an error when multiple plugins attempt to register with the same name",
+                        mock.initConverse((done, _converse) => {
+
                     converse.plugins.add('myplugin', {});
                     converse.plugins.add('myplugin', {});
-                    var error = new TypeError('Error: plugin with name "myplugin" has already been registered!');
+                    const error = new TypeError('Error: plugin with name "myplugin" has already been registered!');
                     expect(_.partial(converse.plugins.add, 'myplugin', {})).toThrow(error);
                     expect(_.partial(converse.plugins.add, 'myplugin', {})).toThrow(error);
+                    done();
                 }));
                 }));
             });
             });
         });
         });

+ 2 - 2
spec/disco.js

@@ -15,7 +15,7 @@
         describe("Whenever converse.js queries a server for its features", function () {
         describe("Whenever converse.js queries a server for its features", function () {
 
 
             it("stores the features it receives",
             it("stores the features it receives",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     null, ['discoInitialized'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -183,7 +183,7 @@
 
 
         describe("Whenever converse.js discovers a new server feature", function () {
         describe("Whenever converse.js discovers a new server feature", function () {
            it("emits the serviceDiscovered event",
            it("emits the serviceDiscovered event",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     null, ['discoInitialized'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 

+ 6 - 3
spec/eventemitter.js

@@ -4,7 +4,7 @@
 
 
     return describe("The _converse Event Emitter", function() {
     return describe("The _converse Event Emitter", function() {
 
 
-        it("allows you to subscribe to emitted events", mock.initConverse(function (_converse) {
+        it("allows you to subscribe to emitted events", mock.initConverse((done, _converse) => {
             this.callback = function () {};
             this.callback = function () {};
             spyOn(this, 'callback');
             spyOn(this, 'callback');
             _converse.on('connected', this.callback);
             _converse.on('connected', this.callback);
@@ -14,9 +14,10 @@
             expect(this.callback.calls.count(), 2);
             expect(this.callback.calls.count(), 2);
             _converse.emit('connected');
             _converse.emit('connected');
             expect(this.callback.calls.count(), 3);
             expect(this.callback.calls.count(), 3);
+            done();
         }));
         }));
 
 
-        it("allows you to listen once for an emitted event", mock.initConverse(function (_converse) {
+        it("allows you to listen once for an emitted event", mock.initConverse((done, _converse) => {
             this.callback = function () {};
             this.callback = function () {};
             spyOn(this, 'callback');
             spyOn(this, 'callback');
             _converse.once('connected', this.callback);
             _converse.once('connected', this.callback);
@@ -26,9 +27,10 @@
             expect(this.callback.calls.count(), 1);
             expect(this.callback.calls.count(), 1);
             _converse.emit('connected');
             _converse.emit('connected');
             expect(this.callback.calls.count(), 1);
             expect(this.callback.calls.count(), 1);
+            done();
         }));
         }));
 
 
-        it("allows you to stop listening or subscribing to an event", mock.initConverse(function (_converse) {
+        it("allows you to stop listening or subscribing to an event", mock.initConverse((done, _converse) => {
             this.callback = function () {};
             this.callback = function () {};
             this.anotherCallback = function () {};
             this.anotherCallback = function () {};
             this.neverCalled = function () {};
             this.neverCalled = function () {};
@@ -56,6 +58,7 @@
             expect(this.callback.calls.count(), 1);
             expect(this.callback.calls.count(), 1);
             expect(this.anotherCallback.calls.count(), 3);
             expect(this.anotherCallback.calls.count(), 3);
             expect(this.neverCalled).not.toHaveBeenCalled();
             expect(this.neverCalled).not.toHaveBeenCalled();
+            done();
         }));
         }));
     });
     });
 }));
 }));

+ 5 - 3
spec/headline.js

@@ -13,7 +13,7 @@
 
 
     describe("A headlines box", function () {
     describe("A headlines box", function () {
 
 
-        it("will not open nor display non-headline messages", mock.initConverse(function (_converse) {
+        it("will not open nor display non-headline messages", mock.initConverse((done, _converse) => {
             /* XMPP spam message:
             /* XMPP spam message:
              *
              *
              *  <message xmlns="jabber:client"
              *  <message xmlns="jabber:client"
@@ -37,9 +37,10 @@
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
             utils.isHeadlineMessage.restore();
             utils.isHeadlineMessage.restore();
+            done();
         }));
         }));
 
 
-        it("will open and display headline messages", mock.initConverseWithPromises(
+        it("will open and display headline messages", mock.initConverse(
             null, ['rosterGroupsFetched'], {}, function (done, _converse) {
             null, ['rosterGroupsFetched'], {}, function (done, _converse) {
 
 
             /* <message from='notify.example.com'
             /* <message from='notify.example.com'
@@ -84,7 +85,7 @@
         }));
         }));
 
 
         it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
         it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
-            mock.initConverse(function (_converse) {
+            mock.initConverse((done, _converse) => {
 
 
             _converse.allow_non_roster_messaging = false;
             _converse.allow_non_roster_messaging = false;
             sinon.spy(utils, 'isHeadlineMessage');
             sinon.spy(utils, 'isHeadlineMessage');
@@ -101,6 +102,7 @@
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
             utils.isHeadlineMessage.restore(); // unwraps
             utils.isHeadlineMessage.restore(); // unwraps
+            done();
         }));
         }));
     });
     });
 }));
 }));

+ 100 - 123
spec/http-file-upload.js

@@ -5,19 +5,19 @@
         "test-utils"], factory);
         "test-utils"], factory);
 } (this, function (jasmine, mock, test_utils) {
 } (this, function (jasmine, mock, test_utils) {
     "use strict";
     "use strict";
-    var Strophe = converse.env.Strophe;
-    var $iq = converse.env.$iq;
-    var _ = converse.env._;
-    var f = converse.env.f;
+    const Strophe = converse.env.Strophe;
+    const $iq = converse.env.$iq;
+    const _ = converse.env._;
+    const u = converse.env.utils;
+    const f = converse.env.f;
 
 
     describe("XEP-0363: HTTP File Upload", function () {
     describe("XEP-0363: HTTP File Upload", function () {
 
 
         describe("Discovering support", function () {
         describe("Discovering support", function () {
 
 
-            it("is done automatically", mock.initConverseWithAsync(async function (done, _converse) {
-                var IQ_stanzas = _converse.connection.IQ_stanzas;
-                var IQ_ids =  _converse.connection.IQ_ids;
-
+            it("is done automatically", mock.initConverse(async (done, _converse) => {
+                const IQ_stanzas = _converse.connection.IQ_stanzas;
+                const IQ_ids =  _converse.connection.IQ_ids;
                 await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []);
                 await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []);
                 await test_utils.waitUntil(() => _.filter(
                 await test_utils.waitUntil(() => _.filter(
                     IQ_stanzas,
                     IQ_stanzas,
@@ -41,8 +41,7 @@
                     return iq.nodeTree.querySelector(
                     return iq.nodeTree.querySelector(
                         'iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]');
                         'iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]');
                 });
                 });
-                var info_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
-
+                const info_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
                 stanza = $iq({
                 stanza = $iq({
                     'type': 'result',
                     'type': 'result',
                     'from': 'localhost',
                     'from': 'localhost',
@@ -173,43 +172,37 @@
         describe("When not supported", function () {
         describe("When not supported", function () {
             describe("A file upload toolbar button", function () {
             describe("A file upload toolbar button", function () {
 
 
-                it("does not appear in private chats", mock.initConverseWithAsync(function (done, _converse) {
+                it("does not appear in private chats", mock.initConverse(async (done, _converse) => {
                     var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
                     var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
                     test_utils.createContacts(_converse, 'current');
                     test_utils.createContacts(_converse, 'current');
                     test_utils.openChatBoxFor(_converse, contact_jid);
                     test_utils.openChatBoxFor(_converse, contact_jid);
 
 
-                    test_utils.waitUntilDiscoConfirmed(
+                    await test_utils.waitUntilDiscoConfirmed(
                         _converse, _converse.domain,
                         _converse, _converse.domain,
                         [{'category': 'server', 'type':'IM'}],
                         [{'category': 'server', 'type':'IM'}],
-                        ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
+                        ['http://jabber.org/protocol/disco#items'], [], 'info');
 
 
-                        test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], [], 'items').then(function () {
-                            var view = _converse.chatboxviews.get(contact_jid);
-                            expect(view.el.querySelector('.chat-toolbar .upload-file')).toBe(null);
-                            done();
-                        });
-                    });
+                    await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], [], 'items');
+                    const view = _converse.chatboxviews.get(contact_jid);
+                    expect(view.el.querySelector('.chat-toolbar .upload-file')).toBe(null);
+                    done();
                 }));
                 }));
 
 
-                it("does not appear in MUC chats", mock.initConverseWithPromises(
+                it("does not appear in MUC chats", mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
-                        function (done, _converse) {
+                        async (done, _converse) => {
 
 
-                    test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
-                        test_utils.waitUntilDiscoConfirmed(
-                            _converse, _converse.domain,
-                            [{'category': 'server', 'type':'IM'}],
-                            ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
+                    await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                    test_utils.waitUntilDiscoConfirmed(
+                        _converse, _converse.domain,
+                        [{'category': 'server', 'type':'IM'}],
+                        ['http://jabber.org/protocol/disco#items'], [], 'info');
 
 
-                            test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items').then(function () {
-                                test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []).then(function () {
-                                    var view = _converse.chatboxviews.get('lounge@localhost');
-                                    expect(view.el.querySelector('.chat-toolbar .upload-file')).toBe(null);
-                                    done();
-                                });
-                            });
-                        });
-                    });
+                    await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items');
+                    await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []);
+                    const view = _converse.chatboxviews.get('lounge@localhost');
+                    expect(view.el.querySelector('.chat-toolbar .upload-file')).toBe(null);
+                    done();
                 }));
                 }));
 
 
             });
             });
@@ -219,60 +212,46 @@
 
 
             describe("A file upload toolbar button", function () {
             describe("A file upload toolbar button", function () {
 
 
-                it("appears in private chats", mock.initConverseWithAsync(function (done, _converse) {
-                    test_utils.waitUntilDiscoConfirmed(
+                it("appears in private chats", mock.initConverse(async (done, _converse) => {
+                    await test_utils.waitUntilDiscoConfirmed(
                         _converse, _converse.domain,
                         _converse, _converse.domain,
                         [{'category': 'server', 'type':'IM'}],
                         [{'category': 'server', 'type':'IM'}],
-                        ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
-
-                        let contact_jid, view;
-
-                        test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items')
-                        .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []))
-                        .then(() => {
-                            test_utils.createContacts(_converse, 'current', 3);
-                            _converse.emit('rosterContactsFetched');
+                        ['http://jabber.org/protocol/disco#items'], [], 'info');
 
 
-                            contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
-                            return test_utils.openChatBoxFor(_converse, contact_jid);
-                        }).then(() => {
-                            view = _converse.chatboxviews.get(contact_jid);
-                            test_utils.waitUntil(() => view.el.querySelector('.upload-file'));
-                        }).then(() => {
-                            expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
-                            done();
-                        });
-                    });
+                    await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items')
+                    await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []);
+                    test_utils.createContacts(_converse, 'current', 3);
+                    _converse.emit('rosterContactsFetched');
+                    const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
+                    await test_utils.openChatBoxFor(_converse, contact_jid);
+                    const view = _converse.chatboxviews.get(contact_jid);
+                    test_utils.waitUntil(() => view.el.querySelector('.upload-file'));
+                    expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
+                    done();
                 }));
                 }));
 
 
-                it("appears in MUC chats", mock.initConverseWithPromises(
+                it("appears in MUC chats", mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
-                        function (done, _converse) {
+                        async (done, _converse) => {
 
 
-                    test_utils.waitUntilDiscoConfirmed(
+                    await test_utils.waitUntilDiscoConfirmed(
                         _converse, _converse.domain,
                         _converse, _converse.domain,
                         [{'category': 'server', 'type':'IM'}],
                         [{'category': 'server', 'type':'IM'}],
-                        ['http://jabber.org/protocol/disco#items'], [], 'info').then(function () {
+                        ['http://jabber.org/protocol/disco#items'], [], 'info');
 
 
-                        test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items')
-                        .then(() => test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []))
-                        .then(() => test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'))
-                        .then(() => test_utils.waitUntil(() => _converse.chatboxviews.get('lounge@localhost').el.querySelector('.upload-file')))
-                        .then(() => {
-                            const view = _converse.chatboxviews.get('lounge@localhost');
-                            expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
-                            done();
-                        }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
-                    });
+                    await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.localhost'], 'items');
+                    await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.localhost', [], [Strophe.NS.HTTPUPLOAD], []);
+                    await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                    await test_utils.waitUntil(() => _converse.chatboxviews.get('lounge@localhost').el.querySelector('.upload-file'));
+                    const view = _converse.chatboxviews.get('lounge@localhost');
+                    expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
+                    done();
                 }));
                 }));
 
 
                 describe("when clicked and a file chosen", function () {
                 describe("when clicked and a file chosen", function () {
 
 
-                    it("is uploaded and sent out", mock.initConverseWithAsync(
-                        async function (done, _converse) {
-
+                    it("is uploaded and sent out", mock.initConverse(async (done, _converse) => {
                         const base_url = 'https://conversejs.org';
                         const base_url = 'https://conversejs.org';
-
                         await test_utils.waitUntilDiscoConfirmed(
                         await test_utils.waitUntilDiscoConfirmed(
                             _converse, _converse.domain,
                             _converse, _converse.domain,
                             [{'category': 'server', 'type':'IM'}],
                             [{'category': 'server', 'type':'IM'}],
@@ -298,7 +277,7 @@
                         await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                         await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
 
                         await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request')).length);
                         await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request')).length);
-                        var iq = IQ_stanzas.pop();
+                        const iq = IQ_stanzas.pop();
                         expect(iq.toLocaleString()).toBe(
                         expect(iq.toLocaleString()).toBe(
                             `<iq from="dummy@localhost/resource" `+
                             `<iq from="dummy@localhost/resource" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
@@ -312,21 +291,21 @@
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                             `</iq>`);
                             `</iq>`);
 
 
-                        var message = base_url+"/logo/conversejs-filled.svg";
-
-                        var stanza = Strophe.xmlHtmlNode(
-                            "<iq from='upload.montague.tld'"+
-                            "    id='"+iq.nodeTree.getAttribute('id')+"'"+
-                            "    to='dummy@localhost/resource'"+
-                            "    type='result'>"+
-                            "<slot xmlns='urn:xmpp:http:upload:0'>"+
-                            "    <put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg'>"+
-                            "    <header name='Authorization'>Basic Base64String==</header>"+
-                            "    <header name='Cookie'>foo=bar; user=romeo</header>"+
-                            "    </put>"+
-                            "    <get url='"+message+"' />"+
-                            "</slot>"+
-                            "</iq>").firstElementChild;
+                        const message = base_url+"/logo/conversejs-filled.svg";
+
+                        const stanza = u.toStanza(`
+                            <iq from="upload.montague.tld"
+                                id="${iq.nodeTree.getAttribute("id")}"
+                                to="dummy@localhost/resource"
+                                type="result">
+                            <slot xmlns="urn:xmpp:http:upload:0">
+                                <put url="https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg">
+                                <header name="Authorization">Basic Base64String==</header>
+                                <header name="Cookie">foo=bar; user=romeo</header>
+                                </put>
+                                <get url="${message}" />
+                            </slot>
+                            </iq>`);
 
 
                         spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                         spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                             const message = view.model.messages.at(0);
                             const message = view.model.messages.at(0);
@@ -375,8 +354,7 @@
                         done();
                         done();
                     }));
                     }));
 
 
-                    it("is uploaded and sent out from a groupchat", mock.initConverseWithAsync(
-                        async function (done, _converse) {
+                    it("is uploaded and sent out from a groupchat", mock.initConverse(async (done, _converse) => {
 
 
                         const base_url = 'https://conversejs.org';
                         const base_url = 'https://conversejs.org';
                         await test_utils.waitUntilDiscoConfirmed(
                         await test_utils.waitUntilDiscoConfirmed(
@@ -401,7 +379,7 @@
                         await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                         await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
 
                         await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request')).length);
                         await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[to="upload.montague.tld"] request')).length);
-                        var iq = IQ_stanzas.pop();
+                        const iq = IQ_stanzas.pop();
                         expect(iq.toLocaleString()).toBe(
                         expect(iq.toLocaleString()).toBe(
                             `<iq from="dummy@localhost/resource" `+
                             `<iq from="dummy@localhost/resource" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
@@ -415,21 +393,20 @@
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                             `</iq>`);
                             `</iq>`);
 
 
-                        var message = base_url+"/logo/conversejs-filled.svg";
-
-                        var stanza = Strophe.xmlHtmlNode(
-                            "<iq from='upload.montague.tld'"+
-                            "    id='"+iq.nodeTree.getAttribute('id')+"'"+
-                            "    to='dummy@localhost/resource'"+
-                            "    type='result'>"+
-                            "<slot xmlns='urn:xmpp:http:upload:0'>"+
-                            "    <put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg'>"+
-                            "    <header name='Authorization'>Basic Base64String==</header>"+
-                            "    <header name='Cookie'>foo=bar; user=romeo</header>"+
-                            "    </put>"+
-                            "    <get url='"+message+"' />"+
-                            "</slot>"+
-                            "</iq>").firstElementChild;
+                        const message = base_url+"/logo/conversejs-filled.svg";
+                        const stanza = u.toStanza(`
+                            <iq from='upload.montague.tld'
+                                id="${iq.nodeTree.getAttribute('id')}"
+                                to='dummy@localhost/resource'
+                                type='result'>
+                            <slot xmlns='urn:xmpp:http:upload:0'>
+                                <put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg'>
+                                <header name='Authorization'>Basic Base64String==</header>
+                                <header name='Cookie'>foo=bar; user=romeo</header>
+                                </put>
+                                <get url="${message}" />
+                            </slot>
+                            </iq>`);
 
 
                         spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                         spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                             const message = view.model.messages.at(0);
                             const message = view.model.messages.at(0);
@@ -478,7 +455,7 @@
                         done();
                         done();
                     }));
                     }));
 
 
-                    it("shows an error message if the file is too large", mock.initConverseWithAsync(async function (done, _converse) {
+                    it("shows an error message if the file is too large", mock.initConverse(async (done, _converse) => {
                         const IQ_stanzas = _converse.connection.IQ_stanzas;
                         const IQ_stanzas = _converse.connection.IQ_stanzas;
                         const IQ_ids =  _converse.connection.IQ_ids;
                         const IQ_ids =  _converse.connection.IQ_ids;
                         const send_backup = XMLHttpRequest.prototype.send;
                         const send_backup = XMLHttpRequest.prototype.send;
@@ -602,7 +579,7 @@
 
 
             describe("While a file is being uploaded", function () {
             describe("While a file is being uploaded", function () {
 
 
-                it("shows a progress bar", mock.initConverseWithPromises(
+                it("shows a progress bar", mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -646,19 +623,19 @@
 
 
                     const base_url = 'https://conversejs.org';
                     const base_url = 'https://conversejs.org';
                     const message = base_url+"/logo/conversejs-filled.svg";
                     const message = base_url+"/logo/conversejs-filled.svg";
-                    const stanza = Strophe.xmlHtmlNode(
-                        "<iq from='upload.montague.tld'"+
-                        "    id='"+iq.nodeTree.getAttribute('id')+"'"+
-                        "    to='dummy@localhost/resource'"+
-                        "    type='result'>"+
-                        "<slot xmlns='urn:xmpp:http:upload:0'>"+
-                        "    <put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg'>"+
-                        "    <header name='Authorization'>Basic Base64String==</header>"+
-                        "    <header name='Cookie'>foo=bar; user=romeo</header>"+
-                        "    </put>"+
-                        "    <get url='"+message+"' />"+
-                        "</slot>"+
-                        "</iq>").firstElementChild;
+                    const stanza = u.toStanza(`
+                        <iq from="upload.montague.tld"
+                            id="${iq.nodeTree.getAttribute("id")}"
+                            to="dummy@localhost/resource"
+                            type="result">
+                        <slot xmlns="urn:xmpp:http:upload:0">
+                            <put url="https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my-juliet.jpg">
+                                <header name="Authorization">Basic Base64String==</header>
+                                <header name="Cookie">foo=bar; user=romeo</header>
+                            </put>
+                            <get url="${message}" />
+                        </slot>
+                        </iq>`);
                     spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                     spyOn(XMLHttpRequest.prototype, 'send').and.callFake(function () {
                         const message = view.model.messages.at(0);
                         const message = view.model.messages.at(0);
                         expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');
                         expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');

+ 2 - 2
spec/login.js

@@ -5,7 +5,7 @@
     describe("The Login Form", function () {
     describe("The Login Form", function () {
 
 
         it("contains a checkbox to indicate whether the computer is trusted or not",
         it("contains a checkbox to indicate whether the computer is trusted or not",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: false },
                   allow_registration: false },
@@ -43,7 +43,7 @@
         }));
         }));
 
 
         it("checkbox can be set to false by default",
         it("checkbox can be set to false by default",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   trusted: false,
                   trusted: false,

+ 38 - 38
spec/mam.js

@@ -8,6 +8,7 @@
     const $iq = converse.env.$iq;
     const $iq = converse.env.$iq;
     const $msg = converse.env.$msg;
     const $msg = converse.env.$msg;
     const moment = converse.env.moment;
     const moment = converse.env.moment;
+    const u = converse.env.utils;
     // See: https://xmpp.org/rfcs/rfc3921.html
     // See: https://xmpp.org/rfcs/rfc3921.html
 
 
     describe("Message Archive Management", function () {
     describe("Message Archive Management", function () {
@@ -16,18 +17,17 @@
         describe("Archived Messages", function () {
         describe("Archived Messages", function () {
 
 
            it("aren't shown as duplicates by comparing their stanza-id attribute", 
            it("aren't shown as duplicates by comparing their stanza-id attribute", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     null, ['discoInitialized'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
                 await test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand');
                 await test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand');
                 const view = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
                 const view = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
-                let stanza = Strophe.xmlHtmlNode(
+                let stanza = u.toStanza(
                     `<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452" type="groupchat" from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)">
                     `<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452" type="groupchat" from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)">
                         <body>negan</body>
                         <body>negan</body>
                         <stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
                         <stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
-                    </message>`
-                ).firstElementChild;
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
                 await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
                 // XXX: we wait here until the first message appears before
                 // XXX: we wait here until the first message appears before
@@ -38,7 +38,7 @@
                 //
                 //
                 // Not sure whether such a race-condition might pose a problem
                 // Not sure whether such a race-condition might pose a problem
                 // in "real-world" situations.
                 // in "real-world" situations.
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452">
                     `<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452">
                         <result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="45fbbf2a-1059-479d-9283-c8effaf05621">
                         <result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="45fbbf2a-1059-479d-9283-c8effaf05621">
                             <forwarded xmlns="urn:xmpp:forward:0">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -48,7 +48,7 @@
                                 </message>
                                 </message>
                             </forwarded>
                             </forwarded>
                         </result>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
 
 
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 view.model.onMessage(stanza);
                 view.model.onMessage(stanza);
@@ -58,13 +58,13 @@
             }));
             }));
 
 
            it("aren't shown as duplicates by comparing their queryid attribute", 
            it("aren't shown as duplicates by comparing their queryid attribute", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     null, ['discoInitialized'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
                 await test_utils.openAndEnterChatRoom(_converse, 'discuss', 'conference.conversejs.org', 'dummy');
                 await test_utils.openAndEnterChatRoom(_converse, 'discuss', 'conference.conversejs.org', 'dummy');
                 const view = _converse.chatboxviews.get('discuss@conference.conversejs.org');
                 const view = _converse.chatboxviews.get('discuss@conference.conversejs.org');
-                let stanza = Strophe.xmlHtmlNode(
+                let stanza = u.toStanza(
                     `<message xmlns="jabber:client"
                     `<message xmlns="jabber:client"
                               to="discuss@conference.conversejs.org"
                               to="discuss@conference.conversejs.org"
                               type="groupchat" xml:lang="en"
                               type="groupchat" xml:lang="en"
@@ -74,11 +74,11 @@
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="prezel@blubber.im" role="participant"/>
                             <item affiliation="none" jid="prezel@blubber.im" role="participant"/>
                         </x>
                         </x>
-                    </message>`).firstElementChild;
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
                 await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
 
 
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<message xmlns="jabber:client" to="dummy@localhost/resource" from="discuss@conference.conversejs.org">
                     `<message xmlns="jabber:client" to="dummy@localhost/resource" from="discuss@conference.conversejs.org">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                             <forwarded xmlns="urn:xmpp:forward:0">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -91,7 +91,7 @@
                                 </message>
                                 </message>
                             </forwarded>
                             </forwarded>
                         </result>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
 
 
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 view.model.onMessage(stanza);
                 view.model.onMessage(stanza);
@@ -99,7 +99,7 @@
                 expect(view.model.isDuplicate.calls.count()).toBe(1);
                 expect(view.model.isDuplicate.calls.count()).toBe(1);
                 expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
                 expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
 
 
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<message xmlns="jabber:client" to="dummy@localhost/resource" from="discuss@conference.conversejs.org">
                     `<message xmlns="jabber:client" to="dummy@localhost/resource" from="discuss@conference.conversejs.org">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                             <forwarded xmlns="urn:xmpp:forward:0">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -112,7 +112,7 @@
                                 </message>
                                 </message>
                             </forwarded>
                             </forwarded>
                         </result>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
                 view.model.onMessage(stanza);
                 view.model.onMessage(stanza);
                 expect(view.model.isDuplicate.calls.count()).toBe(2);
                 expect(view.model.isDuplicate.calls.count()).toBe(2);
                 expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
                 expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
@@ -123,12 +123,12 @@
         describe("The archive.query API", function () {
         describe("The archive.query API", function () {
 
 
            it("can be used to query for all archived messages",
            it("can be used to query for all archived messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     null, ['discoInitialized'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
-                var sent_stanza, IQ_id;
-                var sendIQ = _converse.connection.sendIQ;
+                let sent_stanza, IQ_id;
+                const sendIQ = _converse.connection.sendIQ;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_stanza = iq;
                     sent_stanza = iq;
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
@@ -137,14 +137,14 @@
                     _converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
                     _converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
                 }
                 }
                 _converse.api.archive.query();
                 _converse.api.archive.query();
-                var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
+                const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                 expect(sent_stanza.toString()).toBe(
                 expect(sent_stanza.toString()).toBe(
                     `<iq id="${IQ_id}" type="set" xmlns="jabber:client"><query queryid="${queryid}" xmlns="urn:xmpp:mam:2"/></iq>`);
                     `<iq id="${IQ_id}" type="set" xmlns="jabber:client"><query queryid="${queryid}" xmlns="urn:xmpp:mam:2"/></iq>`);
                 done();
                 done();
             }));
             }));
 
 
            it("can be used to query for all messages to/from a particular JID",
            it("can be used to query for all messages to/from a particular JID",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -177,7 +177,7 @@
             }));
             }));
 
 
            it("can be used to query for archived messages from a chat room",
            it("can be used to query for archived messages from a chat room",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -211,7 +211,7 @@
            }));
            }));
 
 
             it("checks whether returned MAM messages from a MUC room are from the right JID",
             it("checks whether returned MAM messages from a MUC room are from the right JID",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -219,16 +219,16 @@
                 if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
                 if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
                     _converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
                     _converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
                 }
                 }
-                var sent_stanza, IQ_id;
+                let sent_stanza, IQ_id;
                 const sendIQ = _converse.connection.sendIQ;
                 const sendIQ = _converse.connection.sendIQ;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_stanza = iq;
                     sent_stanza = iq;
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
                 });
                 });
-                var callback = jasmine.createSpy('callback');
+                const callback = jasmine.createSpy('callback');
 
 
                 _converse.api.archive.query({'with': 'coven@chat.shakespear.lit', 'groupchat': true, 'max':'10'}, callback);
                 _converse.api.archive.query({'with': 'coven@chat.shakespear.lit', 'groupchat': true, 'max':'10'}, callback);
-                var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
+                const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
 
 
                 /* <message id='iasd207' from='coven@chat.shakespeare.lit' to='hag66@shakespeare.lit/pda'>
                 /* <message id='iasd207' from='coven@chat.shakespeare.lit' to='hag66@shakespeare.lit/pda'>
                  *     <result xmlns='urn:xmpp:mam:2' queryid='g27' id='34482-21985-73620'>
                  *     <result xmlns='urn:xmpp:mam:2' queryid='g27' id='34482-21985-73620'>
@@ -249,7 +249,7 @@
                  *     </result>
                  *     </result>
                  * </message>
                  * </message>
                  */
                  */
-                var msg1 = $msg({'id':'iasd207', 'from': 'other@chat.shakespear.lit', 'to': 'dummy@localhost'})
+                const msg1 = $msg({'id':'iasd207', 'from': 'other@chat.shakespear.lit', 'to': 'dummy@localhost'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'34482-21985-73620'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'34482-21985-73620'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
@@ -283,13 +283,13 @@
 
 
                 await test_utils.waitUntil(() => callback.calls.count());
                 await test_utils.waitUntil(() => callback.calls.count());
                 expect(callback).toHaveBeenCalled();
                 expect(callback).toHaveBeenCalled();
-                var args = callback.calls.argsFor(0);
+                const args = callback.calls.argsFor(0);
                 expect(args[0].length).toBe(0);
                 expect(args[0].length).toBe(0);
                 done();
                 done();
            }));
            }));
 
 
            it("can be used to query for all messages in a certain timespan",
            it("can be used to query for all messages in a certain timespan",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -332,7 +332,7 @@
            }));
            }));
 
 
            it("throws a TypeError if an invalid date is provided",
            it("throws a TypeError if an invalid date is provided",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -347,7 +347,7 @@
            }));
            }));
 
 
            it("can be used to query for all messages after a certain time",
            it("can be used to query for all messages after a certain time",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -385,7 +385,7 @@
            }));
            }));
 
 
            it("can be used to query for a limited set of results",
            it("can be used to query for a limited set of results",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -423,7 +423,7 @@
            }));
            }));
 
 
            it("can be used to page through results",
            it("can be used to page through results",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -465,7 +465,7 @@
            }));
            }));
 
 
            it("accepts \"before\" with an empty string as value to reverse the order",
            it("accepts \"before\" with an empty string as value to reverse the order",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -499,7 +499,7 @@
            }));
            }));
 
 
            it("accepts a Strophe.RSM object for the query options",
            it("accepts a Strophe.RSM object for the query options",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -546,7 +546,7 @@
            }));
            }));
 
 
            it("accepts a callback function, which it passes the messages and a Strophe.RSM object",
            it("accepts a callback function, which it passes the messages and a Strophe.RSM object",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -579,7 +579,7 @@
                  *  </result>
                  *  </result>
                  *  </message>
                  *  </message>
                  */
                  */
-                var msg1 = $msg({'id':'aeb213', 'to':'juliet@capulet.lit/chamber'})
+                const msg1 = $msg({'id':'aeb213', 'to':'juliet@capulet.lit/chamber'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'28482-98726-73623'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'28482-98726-73623'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
@@ -591,7 +591,7 @@
                                     .c('body').t("Call me but love, and I'll be new baptized;");
                                     .c('body').t("Call me but love, and I'll be new baptized;");
                 _converse.connection._dataRecv(test_utils.createRequest(msg1));
                 _converse.connection._dataRecv(test_utils.createRequest(msg1));
 
 
-                var msg2 = $msg({'id':'aeb213', 'to':'juliet@capulet.lit/chamber'})
+                const msg2 = $msg({'id':'aeb213', 'to':'juliet@capulet.lit/chamber'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'28482-98726-73624'})
                             .c('result',  {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id':'28482-98726-73624'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                 .c('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
@@ -624,7 +624,7 @@
 
 
                 await test_utils.waitUntil(() => callback.calls.count());
                 await test_utils.waitUntil(() => callback.calls.count());
                 expect(callback).toHaveBeenCalled();
                 expect(callback).toHaveBeenCalled();
-                var args = callback.calls.argsFor(0);
+                const args = callback.calls.argsFor(0);
                 expect(args[0].length).toBe(2);
                 expect(args[0].length).toBe(2);
                 expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML);
                 expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML);
                 expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML);
                 expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML);
@@ -640,7 +640,7 @@
         describe("The default preference", function () {
         describe("The default preference", function () {
 
 
             it("is set once server support for MAM has been confirmed",
             it("is set once server support for MAM has been confirmed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     null, [], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -654,7 +654,7 @@
                 spyOn(_converse, 'onMAMPreferences').and.callThrough();
                 spyOn(_converse, 'onMAMPreferences').and.callThrough();
                 _converse.message_archiving = 'never';
                 _converse.message_archiving = 'never';
 
 
-                var feature = new Backbone.Model({
+                const feature = new Backbone.Model({
                     'var': Strophe.NS.MAM
                     'var': Strophe.NS.MAM
                 });
                 });
                 spyOn(feature, 'save').and.callFake(feature.set); // Save will complain about a url not being set
                 spyOn(feature, 'save').and.callFake(feature.set); // Save will complain about a url not being set

+ 110 - 110
spec/messages.js

@@ -14,7 +14,7 @@
     describe("A Chat Message", function () {
     describe("A Chat Message", function () {
 
 
         it("can be sent as a correction by clicking the pencil icon",
         it("can be sent as a correction by clicking the pencil icon",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -119,7 +119,7 @@
 
 
 
 
         it("can be sent as a correction by using the up arrow",
         it("can be sent as a correction by using the up arrow",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -276,7 +276,7 @@
 
 
 
 
         it("can be received out of order, and will still be displayed in the right order",
         it("can be received out of order, and will still be displayed in the right order",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -461,7 +461,7 @@
         }));
         }));
 
 
         it("is ignored if it's a malformed headline message",
         it("is ignored if it's a malformed headline message",
-        mock.initConverseWithPromises(
+        mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
             async function (done, _converse) {
 
 
@@ -497,7 +497,7 @@
 
 
 
 
         it("can be a carbon message, as defined in XEP-0280",
         it("can be a carbon message, as defined in XEP-0280",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -546,7 +546,7 @@
         }));
         }));
 
 
         it("can be a carbon message that this user sent from a different client, as defined in XEP-0280",
         it("can be a carbon message that this user sent from a different client, as defined in XEP-0280",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -593,7 +593,7 @@
         }));
         }));
 
 
         it("will be discarded if it's a malicious message meant to look like a carbon copy",
         it("will be discarded if it's a malicious message meant to look like a carbon copy",
-        mock.initConverseWithPromises(
+        mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
             async function (done, _converse) {
 
 
@@ -640,7 +640,7 @@
         }));
         }));
 
 
         it("received for a minimized chat box will increment a counter on its header",
         it("received for a minimized chat box will increment a counter on its header",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -703,7 +703,7 @@
         }));
         }));
 
 
         it("will indicate when it has a time difference of more than a day between it and its predecessor",
         it("will indicate when it has a time difference of more than a day between it and its predecessor",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -797,7 +797,7 @@
         }));
         }));
 
 
         it("can be sent from a chatbox, and will appear inside it",
         it("can be sent from a chatbox, and will appear inside it",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -820,7 +820,7 @@
         }));
         }));
 
 
         it("is sanitized to prevent Javascript injection attacks",
         it("is sanitized to prevent Javascript injection attacks",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -841,7 +841,7 @@
         }));
         }));
 
 
         it("can contain hyperlinks, which will be clickable",
         it("can contain hyperlinks, which will be clickable",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -864,7 +864,7 @@
         }));
         }));
 
 
         it("will have properly escaped URLs",
         it("will have properly escaped URLs",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -908,7 +908,7 @@
         }));
         }));
 
 
         it("will render newlines",
         it("will render newlines",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -916,31 +916,31 @@
             _converse.emit('rosterContactsFetched');
             _converse.emit('rosterContactsFetched');
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const view = await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = await test_utils.openChatBoxFor(_converse, contact_jid);
-            let stanza = Strophe.xmlHtmlNode(
-                "<message from='"+contact_jid+"'"+
-                "         type='chat'"+
-                "         to='dummy@localhost/resource'>"+
-                "    <body>Hey\nHave you heard the news?</body>"+
-                "</message>").firstChild;
+            let stanza = u.toStanza(`
+                <message from="${contact_jid}"
+                         type="chat"
+                         to="dummy@localhost/resource">
+                    <body>Hey\nHave you heard the news?</body>
+                </message>`);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             const chat_content = view.el.querySelector('.chat-content');
             const chat_content = view.el.querySelector('.chat-content');
             expect(chat_content.querySelector('.chat-msg__text').innerHTML).toBe('Hey<br>Have you heard the news?');
             expect(chat_content.querySelector('.chat-msg__text').innerHTML).toBe('Hey<br>Have you heard the news?');
-            stanza = Strophe.xmlHtmlNode(
-                "<message from='"+contact_jid+"'"+
-                "         type='chat'"+
-                "         to='dummy@localhost/resource'>"+
-                "    <body>Hey\n\n\nHave you heard the news?</body>"+
-                "</message>").firstChild;
+            stanza = u.toStanza(`
+                <message from="${contact_jid}"
+                         type="chat"
+                         to="dummy@localhost/resource">
+                    <body>Hey\n\n\nHave you heard the news?</body>
+                </message>`);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             expect(chat_content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br><br>Have you heard the news?');
             expect(chat_content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br><br>Have you heard the news?');
-            stanza = Strophe.xmlHtmlNode(
-                "<message from='"+contact_jid+"'"+
-                "         type='chat'"+
-                "         to='dummy@localhost/resource'>"+
-                "    <body>Hey\nHave you heard\nthe news?</body>"+
-                "</message>").firstChild;
+            stanza = u.toStanza(`
+                <message from="${contact_jid}"
+                         type="chat"
+                         to="dummy@localhost/resource">
+                    <body>Hey\nHave you heard\nthe news?</body>
+                </message>`);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             expect(chat_content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br>Have you heard<br>the news?');
             expect(chat_content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br>Have you heard<br>the news?');
@@ -948,7 +948,7 @@
         }));
         }));
 
 
         it("will render images from their URLs",
         it("will render images from their URLs",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -997,7 +997,7 @@
         }));
         }));
 
 
         it("will render the message time as configured",
         it("will render the message time as configured",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1025,7 +1025,7 @@
         }));
         }));
 
 
         it("will be correctly identified and rendered as a followup message",
         it("will be correctly identified and rendered as a followup message",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1191,7 +1191,7 @@
         }));
         }));
 
 
         it("received may emit a message delivery receipt",
         it("received may emit a message delivery receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
             test_utils.createContacts(_converse, 'current', 1);
@@ -1215,7 +1215,7 @@
         }));
         }));
 
 
         it("carbon received does not emit a message delivery receipt",
         it("carbon received does not emit a message delivery receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
             test_utils.createContacts(_converse, 'current', 1);
@@ -1246,7 +1246,7 @@
         }));
         }));
 
 
         it("forwarded does not emit a message delivery receipt if it's mine",
         it("forwarded does not emit a message delivery receipt if it's mine",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
             test_utils.createContacts(_converse, 'current', 1);
@@ -1276,7 +1276,7 @@
         }));
         }));
 
 
         it("delivery can be acknowledged by a receipt",
         it("delivery can be acknowledged by a receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1336,7 +1336,7 @@
         describe("when received from someone else", function () {
         describe("when received from someone else", function () {
 
 
             it("will open a chatbox and be displayed inside it",
             it("will open a chatbox and be displayed inside it",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1382,7 +1382,7 @@
             }));
             }));
 
 
             it("can be replaced with a correction",
             it("can be replaced with a correction",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1445,7 +1445,7 @@
             describe("when a chatbox is opened for someone who is not in the roster", function () {
             describe("when a chatbox is opened for someone who is not in the roster", function () {
 
 
                 it("the VCard for that user is fetched and the chatbox updated with the results",
                 it("the VCard for that user is fetched and the chatbox updated with the results",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -1502,7 +1502,7 @@
             describe("who is not on the roster", function () {
             describe("who is not on the roster", function () {
 
 
                 it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
                 it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -1562,7 +1562,7 @@
             describe("and for which then an error message is received from the server", function () {
             describe("and for which then an error message is received from the server", function () {
 
 
                 it("will have the error message displayed after itself",
                 it("will have the error message displayed after itself",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -1707,7 +1707,7 @@
                 }));
                 }));
 
 
                 it("will not show to the user an error message for a CSI message",
                 it("will not show to the user an error message for a CSI message",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
                         async function (done, _converse) {
 
 
@@ -1747,7 +1747,7 @@
 
 
 
 
             it("will cause the chat area to be scrolled down only if it was at the bottom originally",
             it("will cause the chat area to be scrolled down only if it was at the bottom originally",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1801,7 +1801,7 @@
             }));
             }));
 
 
             it("is ignored if it's intended for a different resource and filter_by_resource is set to true",
             it("is ignored if it's intended for a different resource and filter_by_resource is set to true",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1853,7 +1853,7 @@
         describe("which contains an OOB URL", function () {
         describe("which contains an OOB URL", function () {
 
 
             it("will render audio from oob mp3 URLs",
             it("will render audio from oob mp3 URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1864,13 +1864,13 @@
                 const view = _converse.chatboxviews.get(contact_jid);
                 const view = _converse.chatboxviews.get(contact_jid);
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 spyOn(view.model, 'sendMessage').and.callThrough();
 
 
-                let stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>Have you heard this funny audio?</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>https://localhost/audio.mp3</url></x>"+
-                    "</message>").firstChild
+                let stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>Have you heard this funny audio?</body>
+                        <x xmlns="jabber:x:oob"><url>https://localhost/audio.mp3</url></x>
+                    </message>`)
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
@@ -1883,13 +1883,13 @@
                     '<a target="_blank" rel="noopener" href="https://localhost/audio.mp3">Download audio file "audio.mp3"</a>');
                     '<a target="_blank" rel="noopener" href="https://localhost/audio.mp3">Download audio file "audio.mp3"</a>');
 
 
                 // If the <url> and <body> contents is the same, don't duplicate.
                 // If the <url> and <body> contents is the same, don't duplicate.
-                stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>https://localhost/audio.mp3</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>https://localhost/audio.mp3</url></x>"+
-                    "</message>").firstChild;
+                stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>https://localhost/audio.mp3</body>
+                        <x xmlns="jabber:x:oob"><url>https://localhost/audio.mp3</url></x>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
                 msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
@@ -1904,7 +1904,7 @@
             }));
             }));
 
 
             it("will render video from oob mp4 URLs",
             it("will render video from oob mp4 URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1915,13 +1915,13 @@
                 const view = _converse.chatboxviews.get(contact_jid);
                 const view = _converse.chatboxviews.get(contact_jid);
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 spyOn(view.model, 'sendMessage').and.callThrough();
 
 
-                let stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>Have you seen this funny video?</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>https://localhost/video.mp4</url></x>"+
-                    "</message>").firstChild;
+                let stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>Have you seen this funny video?</body>
+                        <x xmlns="jabber:x:oob"><url>https://localhost/video.mp4</url></x>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg video').length, 2000)
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg video').length, 2000)
                 let msg = view.el.querySelector('.chat-msg .chat-msg__text');
                 let msg = view.el.querySelector('.chat-msg .chat-msg__text');
@@ -1933,13 +1933,13 @@
                     '<a target="_blank" rel="noopener" href="https://localhost/video.mp4">Download video file "video.mp4"</a>');
                     '<a target="_blank" rel="noopener" href="https://localhost/video.mp4">Download video file "video.mp4"</a>');
 
 
                 // If the <url> and <body> contents is the same, don't duplicate.
                 // If the <url> and <body> contents is the same, don't duplicate.
-                stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>https://localhost/video.mp4</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>https://localhost/video.mp4</url></x>"+
-                    "</message>").firstChild;
+                stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>https://localhost/video.mp4</body>
+                        <x xmlns="jabber:x:oob"><url>https://localhost/video.mp4</url></x>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
                 msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
@@ -1953,7 +1953,7 @@
             }));
             }));
 
 
             it("will render download links for files from oob URLs",
             it("will render download links for files from oob URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1963,13 +1963,13 @@
                 await test_utils.openChatBoxFor(_converse, contact_jid);
                 await test_utils.openChatBoxFor(_converse, contact_jid);
                 const view = _converse.chatboxviews.get(contact_jid);
                 const view = _converse.chatboxviews.get(contact_jid);
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 spyOn(view.model, 'sendMessage').and.callThrough();
-                const stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>Have you downloaded this funny file?</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>https://localhost/funny.pdf</url></x>"+
-                    "</message>").firstChild;
+                const stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>Have you downloaded this funny file?</body>
+                        <x xmlns="jabber:x:oob"><url>https://localhost/funny.pdf</url></x>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
@@ -1983,7 +1983,7 @@
             }));
             }));
 
 
             it("will render images from oob URLs",
             it("will render images from oob URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1996,13 +1996,13 @@
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 const url = base_url+"/logo/conversejs-filled.svg";
                 const url = base_url+"/logo/conversejs-filled.svg";
 
 
-                const stanza = Strophe.xmlHtmlNode(
-                    "<message from='"+contact_jid+"'"+
-                    "         type='chat'"+
-                    "         to='dummy@localhost/resource'>"+
-                    "    <body>Have you seen this funny image?</body>"+
-                    "    <x xmlns='jabber:x:oob'><url>"+url+"</url></x>"+
-                    "</message>").firstChild;
+                const stanza = u.toStanza(`
+                    <message from="${contact_jid}"
+                             type="chat"
+                             to="dummy@localhost/resource">
+                        <body>Have you seen this funny image?</body>
+                        <x xmlns="jabber:x:oob"><url>${url}</url></x>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000);
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000);
 
 
@@ -2022,7 +2022,7 @@
     describe("A XEP-0333 Chat Marker", function () {
     describe("A XEP-0333 Chat Marker", function () {
 
 
         it("is sent when a markable message is received",
         it("is sent when a markable message is received",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2031,14 +2031,14 @@
             await test_utils.openChatBoxFor(_converse, contact_jid);
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
             const msgid = u.getUniqueId();
             const msgid = u.getUniqueId();
-            const stanza = Strophe.xmlHtmlNode(`
+            const stanza = u.toStanza(`
                 <message from='${contact_jid}'
                 <message from='${contact_jid}'
                     id='${msgid}'
                     id='${msgid}'
                     type="chat"
                     type="chat"
                     to='${_converse.jid}'>
                     to='${_converse.jid}'>
                   <body>My lord, dispatch; read o'er these articles.</body>
                   <body>My lord, dispatch; read o'er these articles.</body>
                   <markable xmlns='urn:xmpp:chat-markers:0'/>
                   <markable xmlns='urn:xmpp:chat-markers:0'/>
-                </message>`).firstElementChild;
+                </message>`);
 
 
             const sent_stanzas = [];
             const sent_stanzas = [];
             spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s));
             spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s));
@@ -2055,7 +2055,7 @@
         }));
         }));
 
 
         it("is ignored if it's a carbon copy of one that I sent from a different client",
         it("is ignored if it's a carbon copy of one that I sent from a different client",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2064,7 +2064,7 @@
             await test_utils.openChatBoxFor(_converse, contact_jid);
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
 
 
-            let stanza = Strophe.xmlHtmlNode(`
+            let stanza = u.toStanza(`
                 <message xmlns="jabber:client"
                 <message xmlns="jabber:client"
                          to="${_converse.bare_jid}"
                          to="${_converse.bare_jid}"
                          type="chat"
                          type="chat"
@@ -2074,13 +2074,13 @@
                     <markable xmlns="urn:xmpp:chat-markers:0"/>
                     <markable xmlns="urn:xmpp:chat-markers:0"/>
                     <origin-id xmlns="urn:xmpp:sid:0" id="2e972ea0-0050-44b7-a830-f6638a2595b3"/>
                     <origin-id xmlns="urn:xmpp:sid:0" id="2e972ea0-0050-44b7-a830-f6638a2595b3"/>
                     <stanza-id xmlns="urn:xmpp:sid:0" id="IxVDLJ0RYbWcWvqC" by="${_converse.bare_jid}"/>
                     <stanza-id xmlns="urn:xmpp:sid:0" id="IxVDLJ0RYbWcWvqC" by="${_converse.bare_jid}"/>
-                </message>`).firstElementChild;
+                </message>`);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
             expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
             expect(view.model.messages.length).toBe(1);
             expect(view.model.messages.length).toBe(1);
 
 
-            stanza = Strophe.xmlHtmlNode(
+            stanza = u.toStanza(
                 `<message xmlns="jabber:client" to="${_converse.bare_jid}" type="chat" from="${contact_jid}">
                 `<message xmlns="jabber:client" to="${_converse.bare_jid}" type="chat" from="${contact_jid}">
                     <sent xmlns="urn:xmpp:carbons:2">
                     <sent xmlns="urn:xmpp:carbons:2">
                         <forwarded xmlns="urn:xmpp:forward:0">
                         <forwarded xmlns="urn:xmpp:forward:0">
@@ -2091,7 +2091,7 @@
                             </message>
                             </message>
                         </forwarded>
                         </forwarded>
                     </sent>
                     </sent>
-                </message>`).firstElementChild;
+                </message>`);
             spyOn(_converse, 'emit').and.callThrough();
             spyOn(_converse, 'emit').and.callThrough();
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await test_utils.waitUntil(() => _converse.emit.calls.count() === 1);
             await test_utils.waitUntil(() => _converse.emit.calls.count() === 1);
@@ -2105,7 +2105,7 @@
     describe("A Groupchat Message", function () {
     describe("A Groupchat Message", function () {
 
 
         it("is specially marked when you are mentioned in it",
         it("is specially marked when you are mentioned in it",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2129,7 +2129,7 @@
 
 
 
 
         it("keeps track whether you are the sender or not",
         it("keeps track whether you are the sender or not",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2148,7 +2148,7 @@
         }));
         }));
 
 
         it("can be replaced with a correction",
         it("can be replaced with a correction",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2214,7 +2214,7 @@
         }));
         }));
 
 
         it("can be sent as a correction by using the up arrow",
         it("can be sent as a correction by using the up arrow",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2317,7 +2317,7 @@
         }));
         }));
 
 
         it("delivery can be acknowledged by a receipt",
         it("delivery can be acknowledged by a receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -2350,7 +2350,7 @@
         describe("when received", function () {
         describe("when received", function () {
 
 
             it("highlights all users mentioned via XEP-0372 references",
             it("highlights all users mentioned via XEP-0372 references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2393,7 +2393,7 @@
         describe("in which someone is mentioned", function () {
         describe("in which someone is mentioned", function () {
 
 
             it("gets parsed for mentions which get turned into references",
             it("gets parsed for mentions which get turned into references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2454,7 +2454,7 @@
             }));
             }));
 
 
             it("can get corrected and given new references",
             it("can get corrected and given new references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2528,7 +2528,7 @@
             }));
             }));
 
 
             it("includes XEP-0372 references to that person",
             it("includes XEP-0372 references to that person",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                         function (done, _converse) {
                         function (done, _converse) {
 
 

+ 4 - 4
spec/minchats.js

@@ -9,7 +9,7 @@
     describe("The Minimized Chats Widget", function () {
     describe("The Minimized Chats Widget", function () {
 
 
         it("shows chats that have been minimized",
         it("shows chats that have been minimized",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 
@@ -48,7 +48,7 @@
         }));
         }));
 
 
         it("can be toggled to hide or show minimized chats",
         it("can be toggled to hide or show minimized chats",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 
@@ -79,7 +79,7 @@
         }));
         }));
 
 
         it("shows the number messages received to minimized chats",
         it("shows the number messages received to minimized chats",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 
@@ -158,7 +158,7 @@
         }));
         }));
 
 
         it("shows the number messages received to minimized groupchats",
         it("shows the number messages received to minimized groupchats",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 

+ 150 - 153
spec/muc.js

@@ -17,7 +17,7 @@
         describe("The \"rooms\" API", function () {
         describe("The \"rooms\" API", function () {
 
 
             it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
             it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -53,7 +53,7 @@
             }));
             }));
 
 
             it("has a method 'get' which returns a wrapped groupchat (if it exists)",
             it("has a method 'get' which returns a wrapped groupchat (if it exists)",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -99,7 +99,7 @@
             }));
             }));
 
 
             it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
             it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -207,39 +207,39 @@
                     `<iq id="${IQ_id}" to="room@conference.example.org" type="get" xmlns="jabber:client">`+
                     `<iq id="${IQ_id}" to="room@conference.example.org" type="get" xmlns="jabber:client">`+
                     `<query xmlns="http://jabber.org/protocol/muc#owner"/></iq>`
                     `<query xmlns="http://jabber.org/protocol/muc#owner"/></iq>`
                 );
                 );
-                var node = Strophe.xmlHtmlNode(
-                   '<iq xmlns="jabber:client"'+
-                   '     type="result"'+
-                   '     to="dummy@localhost/pda"'+
-                   '     from="room@conference.example.org" id="'+IQ_id+'">'+
-                   ' <query xmlns="http://jabber.org/protocol/muc#owner">'+
-                   '     <x xmlns="jabber:x:data" type="form">'+
-                   '     <title>Configuration for room@conference.example.org</title>'+
-                   '     <instructions>Complete and submit this form to configure the room.</instructions>'+
-                   '     <field var="FORM_TYPE" type="hidden">'+
-                   '         <value>http://jabber.org/protocol/muc#roomconfig</value>'+
-                   '     </field>'+
-                   '     <field type="text-single" var="muc#roomconfig_roomname" label="Name">'+
-                   '         <value>Room</value>'+
-                   '     </field>'+
-                   '     <field type="text-single" var="muc#roomconfig_roomdesc" label="Description"><value/></field>'+
-                   '     <field type="boolean" var="muc#roomconfig_persistentroom" label="Make Room Persistent?"/>'+
-                   '     <field type="boolean" var="muc#roomconfig_publicroom" label="Make Room Publicly Searchable?"><value>1</value></field>'+
-                   '     <field type="boolean" var="muc#roomconfig_changesubject" label="Allow Occupants to Change Subject?"/>'+
-                   '     <field type="list-single" var="muc#roomconfig_whois" label="Who May Discover Real JIDs?"><option label="Moderators Only">'+
-                   '        <value>moderators</value></option><option label="Anyone"><value>anyone</value></option>'+
-                   '     </field>'+
-                   '     <field type="text-private" var="muc#roomconfig_roomsecret" label="Password"><value/></field>'+
-                   '     <field type="boolean" var="muc#roomconfig_moderatedroom" label="Make Room Moderated?"/>'+
-                   '     <field type="boolean" var="muc#roomconfig_membersonly" label="Make Room Members-Only?"/>'+
-                   '     <field type="text-single" var="muc#roomconfig_historylength" label="Maximum Number of History Messages Returned by Room">'+
-                   '        <value>20</value></field>'+
-                   '     </x>'+
-                   ' </query>'+
-                   ' </iq>');
+                const node = u.toStanza(`
+                   <iq xmlns="jabber:client"
+                        type="result"
+                        to="dummy@localhost/pda"
+                        from="room@conference.example.org" id="${IQ_id}">
+                    <query xmlns="http://jabber.org/protocol/muc#owner">
+                        <x xmlns="jabber:x:data" type="form">
+                        <title>Configuration for room@conference.example.org</title>
+                        <instructions>Complete and submit this form to configure the room.</instructions>
+                        <field var="FORM_TYPE" type="hidden">
+                            <value>http://jabber.org/protocol/muc#roomconfig</value>
+                        </field>
+                        <field type="text-single" var="muc#roomconfig_roomname" label="Name">
+                            <value>Room</value>
+                        </field>
+                        <field type="text-single" var="muc#roomconfig_roomdesc" label="Description"><value/></field>
+                        <field type="boolean" var="muc#roomconfig_persistentroom" label="Make Room Persistent?"/>
+                        <field type="boolean" var="muc#roomconfig_publicroom" label="Make Room Publicly Searchable?"><value>1</value></field>
+                        <field type="boolean" var="muc#roomconfig_changesubject" label="Allow Occupants to Change Subject?"/>
+                        <field type="list-single" var="muc#roomconfig_whois" label="Who May Discover Real JIDs?"><option label="Moderators Only">
+                           <value>moderators</value></option><option label="Anyone"><value>anyone</value></option>
+                        </field>
+                        <field type="text-private" var="muc#roomconfig_roomsecret" label="Password"><value/></field>
+                        <field type="boolean" var="muc#roomconfig_moderatedroom" label="Make Room Moderated?"/>
+                        <field type="boolean" var="muc#roomconfig_membersonly" label="Make Room Members-Only?"/>
+                        <field type="text-single" var="muc#roomconfig_historylength" label="Maximum Number of History Messages Returned by Room">
+                           <value>20</value></field>
+                        </x>
+                    </query>
+                    </iq>`);
 
 
                 spyOn(chatroomview.model, 'sendConfiguration').and.callThrough();
                 spyOn(chatroomview.model, 'sendConfiguration').and.callThrough();
-                _converse.connection._dataRecv(test_utils.createRequest(node.firstElementChild));
+                _converse.connection._dataRecv(test_utils.createRequest(node));
                 await test_utils.waitUntil(() => chatroomview.model.sendConfiguration.calls.count() === 1);
                 await test_utils.waitUntil(() => chatroomview.model.sendConfiguration.calls.count() === 1);
                 var sent_stanza = sent_IQ_els.pop();
                 var sent_stanza = sent_IQ_els.pop();
                 while (sent_stanza.getAttribute('type') !== 'set') {
                 while (sent_stanza.getAttribute('type') !== 'set') {
@@ -260,7 +260,7 @@
         describe("An instant groupchat", function () {
         describe("An instant groupchat", function () {
 
 
             it("will be created when muc_instant_rooms is set to true",
             it("will be created when muc_instant_rooms is set to true",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -391,7 +391,7 @@
         describe("A Groupchat", function () {
         describe("A Groupchat", function () {
 
 
             it("is opened when an xmpp: URI is clicked inside another groupchat",
             it("is opened when an xmpp: URI is clicked inside another groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -420,7 +420,7 @@
             }));
             }));
 
 
             it("shows a notification if its not anonymous",
             it("shows a notification if its not anonymous",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -478,7 +478,7 @@
 
 
 
 
             it("shows join/leave messages when users enter or exit a groupchat",
             it("shows join/leave messages when users enter or exit a groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -753,7 +753,7 @@
             }));
             }));
 
 
             it("combines subsequent join/leave messages when users enter or exit a groupchat",
             it("combines subsequent join/leave messages when users enter or exit a groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -764,99 +764,99 @@
                 expect(sizzle('div.chat-info', chat_content).length).toBe(1);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(1);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("dummy has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("dummy has entered the groupchat");
 
 
-                let presence = Strophe.xmlHtmlNode(
+                let presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fabio has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fabio has entered the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="participant"/>
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(3);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(3);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/jcbrand">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/jcbrand">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="owner" jid="jc@opkode.com/converse.js-30645022" role="moderator"/>
                             <item affiliation="owner" jid="jc@opkode.com/converse.js-30645022" role="moderator"/>
                             <status code="110"/>
                             <status code="110"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("jcbrand has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("jcbrand has entered the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="none"/>
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="none"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered and left the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered and left the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="participant"/>
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(4);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("Dele Olajide has entered the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fuvuv" xml:lang="en">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fuvuv" xml:lang="en">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://jabber.pix-art.de" ver="5tOurnuFnp2h50hKafeUyeN4Yl8=" hash="sha-1"/>
                         <c xmlns="http://jabber.org/protocol/caps" node="http://jabber.pix-art.de" ver="5tOurnuFnp2h50hKafeUyeN4Yl8=" hash="sha-1"/>
                         <x xmlns="vcard-temp:x:update"/>
                         <x xmlns="vcard-temp:x:update"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="participant"/>
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fuvuv has entered the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fuvuv has entered the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fuvuv">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fuvuv">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="none"/>
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="none"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fuvuv has entered and left the groupchat");
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("fuvuv has entered and left the groupchat");
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
                         <status>Disconnected: Replaced by new connection</status>
                         <status>Disconnected: Replaced by new connection</status>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `fabio has entered and left the groupchat. "Disconnected: Replaced by new connection"`);
                     `fabio has entered and left the groupchat. "Disconnected: Replaced by new connection"`);
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
@@ -866,46 +866,45 @@
                 // who were already in the room when we joined.
                 // who were already in the room when we joined.
                 chat_content.innerHTML = '';
                 chat_content.innerHTML = '';
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
                         <status>Disconnected: closed</status>
                         <status>Disconnected: closed</status>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(1);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(1);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `fabio has left the groupchat. "Disconnected: closed"`);
                     `fabio has left the groupchat. "Disconnected: closed"`);
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="none"/>
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="none"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `Dele Olajide has left the groupchat`);
                     `Dele Olajide has left the groupchat`);
 
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/fabio">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="INI3xjRUioclBTP/aACfWi5m9UY=" hash="sha-1"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `fabio has left and re-entered the groupchat`);
                     `fabio has left and re-entered the groupchat`);
-
                 done();
                 done();
             }));
             }));
 
 
             it("role-change messages that follow a MUC leave are left out",
             it("role-change messages that follow a MUC leave are left out",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -936,16 +935,15 @@
                 await view.model.onMessage(msg);
                 await view.model.onMessage(msg);
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
 
-                let stanza = Strophe.xmlHtmlNode(
+                let stanza = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="conversations@conference.siacs.eu/Guus">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="conversations@conference.siacs.eu/Guus">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" role="none"/>
                             <item affiliation="none" role="none"/>
                         </x>
                         </x>
-                    </presence>`
-                ).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
 
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="conversations@conference.siacs.eu/Guus">
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="conversations@conference.siacs.eu/Guus">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="ISg6+9AoK1/cwhbNEDviSvjdPzI=" hash="sha-1"/>
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="ISg6+9AoK1/cwhbNEDviSvjdPzI=" hash="sha-1"/>
                         <x xmlns="vcard-temp:x:update">
                         <x xmlns="vcard-temp:x:update">
@@ -954,8 +952,7 @@
                         <x xmlns="http://jabber.org/protocol/muc#user">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" role="visitor"/>
                             <item affiliation="none" role="visitor"/>
                         </x>
                         </x>
-                    </presence>`
-                ).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
 
                 const chat_content = view.el.querySelector('.chat-content');
                 const chat_content = view.el.querySelector('.chat-content');
@@ -969,7 +966,7 @@
 
 
 
 
             it("shows a new day indicator if a join/leave message is received on a new day",
             it("shows a new day indicator if a join/leave message is received on a new day",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1052,14 +1049,14 @@
 
 
                 jasmine.clock().tick(ONE_DAY_LATER);
                 jasmine.clock().tick(ONE_DAY_LATER);
 
 
-                let stanza = Strophe.xmlHtmlNode(
-                    '<message xmlns="jabber:client"' +
-                    '   to="dummy@localhost/_converse.js-290929789"' +
-                    '   type="groupchat"' +
-                    '   from="coven@chat.shakespeare.lit/some1">'+
-                    '       <body>hello world</body>'+
-                    '       <delay xmlns="urn:xmpp:delay" stamp="'+moment().format()+'" from="some1@localhost"/>'+
-                    '</message>').firstChild;
+                let stanza = u.toStanza(`
+                     <message xmlns="jabber:client"
+                        to="dummy@localhost/_converse.js-290929789"
+                        type="groupchat"
+                        from="coven@chat.shakespeare.lit/some1">
+                            <body>hello world</body>
+                            <delay xmlns="urn:xmpp:delay" stamp="${moment().format()}" from="some1@localhost"/>
+                     </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
 
@@ -1087,14 +1084,14 @@
 
 
                 jasmine.clock().tick(ONE_DAY_LATER);
                 jasmine.clock().tick(ONE_DAY_LATER);
 
 
-                stanza = Strophe.xmlHtmlNode(
-                    '<message xmlns="jabber:client"' +
-                    '   to="dummy@localhost/_converse.js-290929789"' +
-                    '   type="groupchat"' +
-                    '   from="coven@chat.shakespeare.lit/some1">'+
-                    '       <body>hello world</body>'+
-                    '       <delay xmlns="urn:xmpp:delay" stamp="'+moment().format()+'" from="some1@localhost"/>'+
-                    '</message>').firstChild;
+                stanza = u.toStanza(`
+                    <message xmlns="jabber:client"
+                       to="dummy@localhost/_converse.js-290929789"
+                       type="groupchat"
+                       from="coven@chat.shakespeare.lit/some1">"+
+                           <body>hello world</body>"+
+                           <delay xmlns="urn:xmpp:delay" stamp="${moment().format()}" from="some1@localhost"/>"+
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
 
@@ -1131,7 +1128,7 @@
 
 
 
 
             it("supports the /me command",
             it("supports the /me command",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1171,7 +1168,7 @@
             }));
             }));
 
 
             it("can be configured if you're its owner",
             it("can be configured if you're its owner",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1389,7 +1386,7 @@
             }));
             }));
 
 
             it("shows all members even if they're not currently present in the groupchat",
             it("shows all members even if they're not currently present in the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1443,7 +1440,7 @@
             }));
             }));
 
 
             it("shows users currently present in the groupchat",
             it("shows users currently present in the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1497,7 +1494,7 @@
             }));
             }));
 
 
             it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
             it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
-                mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {},
+                mock.initConverse(null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
                 await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
                 await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
@@ -1528,7 +1525,7 @@
             }));
             }));
 
 
             it("indicates moderators and visitors by means of a special css class and tooltip",
             it("indicates moderators and visitors by means of a special css class and tooltip",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1591,7 +1588,7 @@
             }));
             }));
 
 
             it("properly handles notification that a room has been destroyed",
             it("properly handles notification that a room has been destroyed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1622,7 +1619,7 @@
             }));
             }));
 
 
             it("will use the user's reserved nickname, if it exists",
             it("will use the user's reserved nickname, if it exists",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1719,7 +1716,7 @@
             }));
             }));
 
 
             it("allows the user to invite their roster contacts to enter the groupchat",
             it("allows the user to invite their roster contacts to enter the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1778,7 +1775,7 @@
             }));
             }));
 
 
             it("can be joined automatically, based upon a received invite",
             it("can be joined automatically, based upon a received invite",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1798,10 +1795,10 @@
                 expect(_converse.chatboxes.models.length).toBe(1);
                 expect(_converse.chatboxes.models.length).toBe(1);
                 expect(_converse.chatboxes.models[0].id).toBe("controlbox");
                 expect(_converse.chatboxes.models[0].id).toBe("controlbox");
 
 
-                const stanza = Strophe.xmlHtmlNode(
-                    '<message xmlns="jabber:client" to="'+_converse.bare_jid+'" from="'+from_jid+'" id="9bceb415-f34b-4fa4-80d5-c0d076a24231">'+
-                        '<x xmlns="jabber:x:conference" jid="'+room_jid+'" reason="'+reason+'"/>'+
-                    '</message>').firstChild;
+                const stanza = u.toStanza(`
+                    <message xmlns="jabber:client" to="${_converse.bare_jid}" from="${from_jid}" id="9bceb415-f34b-4fa4-80d5-c0d076a24231">
+                       <x xmlns="jabber:x:conference" jid="${room_jid}" reason="${reason}"/>
+                    </message>`);
                 _converse.onDirectMUCInvitation(stanza);
                 _converse.onDirectMUCInvitation(stanza);
                 expect(window.confirm).toHaveBeenCalledWith(
                 expect(window.confirm).toHaveBeenCalledWith(
                     name + ' has invited you to join a groupchat: '+ room_jid +
                     name + ' has invited you to join a groupchat: '+ room_jid +
@@ -1813,7 +1810,7 @@
             }));
             }));
 
 
             it("shows received groupchat messages",
             it("shows received groupchat messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1846,7 +1843,7 @@
             }));
             }));
 
 
             it("shows sent groupchat messages",
             it("shows sent groupchat messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1888,7 +1885,7 @@
             }));
             }));
 
 
             it("will cause the chat area to be scrolled down only if it was at the bottom already",
             it("will cause the chat area to be scrolled down only if it was at the bottom already",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1931,18 +1928,18 @@
             }));
             }));
 
 
             it("shows the room topic in the header",
             it("shows the room topic in the header",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
                 await test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc');
                 await test_utils.openAndEnterChatRoom(_converse, 'jdev', 'conference.jabber.org', 'jc');
                 const text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
                 const text = 'Jabber/XMPP Development | RFCs and Extensions: http://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
-                let stanza = Strophe.xmlHtmlNode(
-                    '<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">'+
-                    '    <subject>'+text+'</subject>'+
-                    '    <delay xmlns="urn:xmpp:delay" stamp="2014-02-04T09:35:39Z" from="jdev@conference.jabber.org"/>'+
-                    '    <x xmlns="jabber:x:delay" stamp="20140204T09:35:39" from="jdev@conference.jabber.org"/>'+
-                    '</message>').firstChild;
+                let stanza = u.toStanza(`
+                    <message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
+                        <subject>${text}</subject>
+                        <delay xmlns="urn:xmpp:delay" stamp="2014-02-04T09:35:39Z" from="jdev@conference.jabber.org"/>
+                        <x xmlns="jabber:x:delay" stamp="20140204T09:35:39" from="jdev@conference.jabber.org"/>
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
                 const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
                 await new Promise((resolve, reject) => view.model.once('change:subject', resolve));
                 await new Promise((resolve, reject) => view.model.once('change:subject', resolve));
@@ -1951,11 +1948,11 @@
                 expect(sizzle('.chat-topic:last').pop().textContent).toBe(text);
                 expect(sizzle('.chat-topic:last').pop().textContent).toBe(text);
                 expect(view.el.querySelector('.chatroom-description').textContent).toBe(text);
                 expect(view.el.querySelector('.chatroom-description').textContent).toBe(text);
 
 
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
                     `<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
                          <subject>This is a message subject</subject>
                          <subject>This is a message subject</subject>
                          <body>This is a message</body>
                          <body>This is a message</body>
-                     </message>`).firstChild;
+                     </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 chat_content = view.el.querySelector('.chat-content');
                 chat_content = view.el.querySelector('.chat-content');
@@ -1969,7 +1966,7 @@
             }));
             }));
 
 
             it("escapes the subject before rendering it, to avoid JS-injection attacks",
             it("escapes the subject before rendering it, to avoid JS-injection attacks",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1988,7 +1985,7 @@
             }));
             }));
 
 
             it("informs users if their nicknames has been changed.",
             it("informs users if their nicknames has been changed.",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2094,7 +2091,7 @@
             }));
             }));
 
 
             it("queries for the groupchat information before attempting to join the user",
             it("queries for the groupchat information before attempting to join the user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2168,7 +2165,7 @@
             }));
             }));
 
 
             it("updates the shown features when the groupchat configuration has changed",
             it("updates the shown features when the groupchat configuration has changed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2212,7 +2209,7 @@
                         `iq[to="${jid}"] query[xmlns="${Strophe.NS.MUC_OWNER}"]`
                         `iq[to="${jid}"] query[xmlns="${Strophe.NS.MUC_OWNER}"]`
                     )).pop());
                     )).pop());
 
 
-                const response = Strophe.xmlHtmlNode(
+                const response_el = u.toStanza(
                    `<iq xmlns="jabber:client"
                    `<iq xmlns="jabber:client"
                          type="result"
                          type="result"
                          to="dummy@localhost/pda"
                          to="dummy@localhost/pda"
@@ -2277,7 +2274,6 @@
                      </x>
                      </x>
                      </query>
                      </query>
                      </iq>`);
                      </iq>`);
-                const response_el = response.firstElementChild;
                 _converse.connection._dataRecv(test_utils.createRequest(response_el));
                 _converse.connection._dataRecv(test_utils.createRequest(response_el));
                 const el = await test_utils.waitUntil(() => document.querySelector('.chatroom-form legend'));
                 const el = await test_utils.waitUntil(() => document.querySelector('.chatroom-form legend'));
                 expect(el.textContent).toBe("Configuration for room@conference.example.org");
                 expect(el.textContent).toBe("Configuration for room@conference.example.org");
@@ -2357,7 +2353,7 @@
             }));
             }));
 
 
             it("indicates when a room is no longer anonymous",
             it("indicates when a room is no longer anonymous",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2406,7 +2402,7 @@
             }));
             }));
 
 
             it("informs users if they have been kicked out of the groupchat",
             it("informs users if they have been kicked out of the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2459,7 +2455,7 @@
 
 
 
 
             it("can be saved to, and retrieved from, browserStorage",
             it("can be saved to, and retrieved from, browserStorage",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2491,7 +2487,7 @@
             }));
             }));
 
 
             it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
             it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2522,7 +2518,7 @@
             }));
             }));
 
 
             it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
             it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2544,7 +2540,7 @@
         describe("Each chat groupchat can take special commands", function () {
         describe("Each chat groupchat can take special commands", function () {
 
 
             it("takes /help to show the available commands",
             it("takes /help to show the available commands",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2582,7 +2578,7 @@
             }));
             }));
 
 
             it("takes /help to show the available commands and commands can be disabled by config",
             it("takes /help to show the available commands and commands can be disabled by config",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {muc_disable_moderator_commands: ['mute', 'voice']},
                     null, ['rosterGroupsFetched'], {muc_disable_moderator_commands: ['mute', 'voice']},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2618,7 +2614,7 @@
             }));
             }));
 
 
             it("takes /member to make an occupant a member",
             it("takes /member to make an occupant a member",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2767,7 +2763,7 @@
             }));
             }));
 
 
             it("takes /topic to set the groupchat topic",
             it("takes /topic to set the groupchat topic",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2819,7 +2815,7 @@
             }));
             }));
 
 
             it("takes /clear to clear messages",
             it("takes /clear to clear messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2838,7 +2834,7 @@
             }));
             }));
 
 
             it("takes /owner to make a user an owner",
             it("takes /owner to make a user an owner",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -2926,7 +2922,7 @@
             }));
             }));
 
 
             it("takes /ban to ban a user",
             it("takes /ban to ban a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3006,7 +3002,7 @@
             }));
             }));
 
 
             it("takes /kick to kick a user",
             it("takes /kick to kick a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3095,7 +3091,7 @@
 
 
 
 
             it("takes /op and /deop to make a user a moderator or not",
             it("takes /op and /deop to make a user a moderator or not",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3237,7 +3233,7 @@
             }));
             }));
 
 
             it("takes /mute and /voice to mute and unmute a user",
             it("takes /mute and /voice to mute and unmute a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3380,7 +3376,7 @@
             }));
             }));
 
 
             it("takes /destroy to destroy a muc",
             it("takes /destroy to destroy a muc",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3431,7 +3427,7 @@
         describe("When attempting to enter a groupchat", function () {
         describe("When attempting to enter a groupchat", function () {
 
 
             it("will use the nickname set in the global settings if the user doesn't have a VCard nickname",
             it("will use the nickname set in the global settings if the user doesn't have a VCard nickname",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3442,7 +3438,7 @@
             }));
             }));
 
 
             it("will show an error message if the groupchat requires a password",
             it("will show an error message if the groupchat requires a password",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3478,7 +3474,7 @@
             }));
             }));
 
 
             it("will show an error message if the groupchat is members-only and the user not included",
             it("will show an error message if the groupchat is members-only and the user not included",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3502,7 +3498,7 @@
             }));
             }));
 
 
             it("will show an error message if the user has been banned",
             it("will show an error message if the user has been banned",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3526,7 +3522,7 @@
             }));
             }));
 
 
             it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false",
             it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3554,7 +3550,7 @@
             }));
             }));
 
 
             it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true",
             it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3615,7 +3611,7 @@
             }));
             }));
 
 
             it("will show an error message if the user is not allowed to have created the groupchat",
             it("will show an error message if the user is not allowed to have created the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3638,7 +3634,7 @@
             }));
             }));
 
 
             it("will show an error message if the user's nickname doesn't conform to groupchat policy",
             it("will show an error message if the user's nickname doesn't conform to groupchat policy",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3662,7 +3658,7 @@
             }));
             }));
 
 
             it("will show an error message if the groupchat doesn't yet exist",
             it("will show an error message if the groupchat doesn't yet exist",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3686,7 +3682,7 @@
             }));
             }));
 
 
             it("will show an error message if the groupchat has reached its maximum number of participants",
             it("will show an error message if the groupchat has reached its maximum number of participants",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3713,7 +3709,7 @@
         describe("Someone being invited to a groupchat", function () {
         describe("Someone being invited to a groupchat", function () {
 
 
             it("will first be added to the member list if the groupchat is members only",
             it("will first be added to the member list if the groupchat is members only",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3879,7 +3875,7 @@
         describe("The affiliations delta", function () {
         describe("The affiliations delta", function () {
 
 
             it("can be computed in various ways",
             it("can be computed in various ways",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3944,7 +3940,7 @@
         describe("The \"Groupchats\" section", function () {
         describe("The \"Groupchats\" section", function () {
 
 
             it("contains a link to a modal through which a new chatroom can be created",
             it("contains a link to a modal through which a new chatroom can be created",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -3956,6 +3952,7 @@
                 test_utils.closeControlBox(_converse);
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.add_room_modal;
                 const modal = roomspanel.add_room_modal;
                 await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
                 await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
+                expect(modal.el.querySelector('.modal-title').textContent).toBe('Enter a new Groupchat');
                 spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
                 spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
                 roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
                 roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
                 modal.el.querySelector('input[name="chatroom"]').value = 'lounce@muc.localhost';
                 modal.el.querySelector('input[name="chatroom"]').value = 'lounce@muc.localhost';
@@ -3966,7 +3963,7 @@
             }));
             }));
 
 
             it("contains a link to a modal which can list groupchats publically available on the server",
             it("contains a link to a modal which can list groupchats publically available on the server",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -4028,7 +4025,7 @@
             }));
             }));
 
 
             it("shows the number of unread mentions received",
             it("shows the number of unread mentions received",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'allow_bookmarks': false},
                     null, ['rosterGroupsFetched'], {'allow_bookmarks': false},
                     async function (done, _converse) {
                     async function (done, _converse) {
                 // XXX: we set `allow_bookmarks` to false, so that the groupchats
                 // XXX: we set `allow_bookmarks` to false, so that the groupchats
@@ -4083,7 +4080,7 @@
                 describe("A composing notification", function () {
                 describe("A composing notification", function () {
 
 
                     it("will be shown if received",
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 
@@ -4239,7 +4236,7 @@
 
 
                 describe("A paused notification", function () {
                 describe("A paused notification", function () {
                     it("will be shown if received",
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
                             async function (done, _converse) {
 
 

+ 16 - 13
spec/notification.js

@@ -14,9 +14,9 @@
                 describe("an HTML5 Notification", function () {
                 describe("an HTML5 Notification", function () {
 
 
                     it("is shown when a new private message is received",
                     it("is shown when a new private message is received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
 
                         // TODO: not yet testing show_desktop_notifications setting
                         // TODO: not yet testing show_desktop_notifications setting
                         test_utils.createContacts(_converse, 'current');
                         test_utils.createContacts(_converse, 'current');
@@ -42,9 +42,9 @@
                     }));
                     }));
 
 
                     it("is shown when you are mentioned in a groupchat",
                     it("is shown when you are mentioned in a groupchat",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
 
                         await test_utils.createContacts(_converse, 'current');
                         await test_utils.createContacts(_converse, 'current');
                         await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
                         await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
@@ -83,9 +83,9 @@
                     }));
                     }));
 
 
                     it("is shown for headline messages",
                     it("is shown for headline messages",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
 
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
                         spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
@@ -112,11 +112,11 @@
                         done();
                         done();
                     }));
                     }));
 
 
-                    it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse(function (_converse) {
+                    it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse((done, _converse) => {
                         _converse.allow_non_roster_messaging = false;
                         _converse.allow_non_roster_messaging = false;
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
-                        var stanza = $msg({
+                        const stanza = $msg({
                                 'type': 'headline',
                                 'type': 'headline',
                                 'from': 'someone@notify.example.com',
                                 'from': 'someone@notify.example.com',
                                 'to': 'dummy@localhost',
                                 'to': 'dummy@localhost',
@@ -132,30 +132,33 @@
                                 'someone@notify.example.com')
                                 'someone@notify.example.com')
                             ).toBeFalsy();
                             ).toBeFalsy();
                         expect(_converse.showMessageNotification).not.toHaveBeenCalled();
                         expect(_converse.showMessageNotification).not.toHaveBeenCalled();
+                        done();
                     }));
                     }));
 
 
-                    it("is shown when a user changes their chat state (if show_chatstate_notifications is true)", mock.initConverse(function (_converse) {
+                    it("is shown when a user changes their chat state (if show_chatstate_notifications is true)", mock.initConverse((done, _converse) => {
                         // TODO: not yet testing show_desktop_notifications setting
                         // TODO: not yet testing show_desktop_notifications setting
                         _converse.show_chatstate_notifications = true;
                         _converse.show_chatstate_notifications = true;
 
 
                         test_utils.createContacts(_converse, 'current');
                         test_utils.createContacts(_converse, 'current');
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                         spyOn(_converse, 'showChatStateNotification');
                         spyOn(_converse, 'showChatStateNotification');
-                        var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
+                        const jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
                         _converse.roster.get(jid).presence.set('show', 'busy'); // This will emit 'contactStatusChanged'
                         _converse.roster.get(jid).presence.set('show', 'busy'); // This will emit 'contactStatusChanged'
                         expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                         expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                         expect(_converse.showChatStateNotification).toHaveBeenCalled();
                         expect(_converse.showChatStateNotification).toHaveBeenCalled();
+                        done()
                     }));
                     }));
                 });
                 });
             });
             });
 
 
             describe("When a new contact request is received", function () {
             describe("When a new contact request is received", function () {
-                it("an HTML5 Notification is received", mock.initConverse(function (_converse) {
+                it("an HTML5 Notification is received", mock.initConverse((done, _converse) => {
                     spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                     spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                     spyOn(_converse, 'showContactRequestNotification');
                     spyOn(_converse, 'showContactRequestNotification');
                     _converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
                     _converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
                     expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                     expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                     expect(_converse.showContactRequestNotification).toHaveBeenCalled();
                     expect(_converse.showContactRequestNotification).toHaveBeenCalled();
+                    done();
                 }));
                 }));
             });
             });
         });
         });
@@ -164,9 +167,9 @@
             describe("A notification sound", function () {
             describe("A notification sound", function () {
 
 
                 it("is played when the current user is mentioned in a groupchat",
                 it("is played when the current user is mentioned in a groupchat",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         null, ['rosterGroupsFetched'], {},
-                        async function (done, _converse) {
+                        async (done, _converse) => {
 
 
                     test_utils.createContacts(_converse, 'current');
                     test_utils.createContacts(_converse, 'current');
                     await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
                     await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');

+ 12 - 12
spec/omemo.js

@@ -76,7 +76,7 @@
     describe("The OMEMO module", function() {
     describe("The OMEMO module", function() {
 
 
         it("adds methods for encrypting and decrypting messages via AES GCM",
         it("adds methods for encrypting and decrypting messages via AES GCM",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -93,7 +93,7 @@
 
 
 
 
         it("enables encrypted messages to be sent and received",
         it("enables encrypted messages to be sent and received",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -233,7 +233,7 @@
         }));
         }));
 
 
         it("enables encrypted groupchat messages to be sent and received",
         it("enables encrypted groupchat messages to be sent and received",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -377,7 +377,7 @@
         }));
         }));
 
 
         it("gracefully handles auth errors when trying to send encrypted groupchat messages",
         it("gracefully handles auth errors when trying to send encrypted groupchat messages",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -506,7 +506,7 @@
         }));
         }));
 
 
         it("can receive a PreKeySignalMessage",
         it("can receive a PreKeySignalMessage",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -607,7 +607,7 @@
 
 
 
 
         it("updates device lists based on PEP messages",
         it("updates device lists based on PEP messages",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {'allow_non_roster_messaging': true},
                 null, ['rosterGroupsFetched'], {'allow_non_roster_messaging': true},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -771,7 +771,7 @@
 
 
 
 
         it("updates device bundles based on PEP messages",
         it("updates device bundles based on PEP messages",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -921,7 +921,7 @@
         }));
         }));
 
 
         it("publishes a bundle with which an encrypted session can be created",
         it("publishes a bundle with which an encrypted session can be created",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1000,7 +1000,7 @@
 
 
 
 
         it("adds a toolbar button for starting an encrypted chat session",
         it("adds a toolbar button for starting an encrypted chat session",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1165,7 +1165,7 @@
         }));
         }));
 
 
         it("adds a toolbar button for starting an encrypted groupchat session",
         it("adds a toolbar button for starting an encrypted groupchat session",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1347,7 +1347,7 @@
 
 
 
 
         it("shows OMEMO device fingerprints in the user details modal",
         it("shows OMEMO device fingerprints in the user details modal",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -1447,7 +1447,7 @@
     describe("A chatbox with an active OMEMO session", function() {
     describe("A chatbox with an active OMEMO session", function() {
 
 
         it("will not show the spoiler toolbar button",
         it("will not show the spoiler toolbar button",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
             // TODO
             // TODO

+ 6 - 5
spec/ping.js

@@ -7,7 +7,7 @@
         describe("Ping and pong handlers", function () {
         describe("Ping and pong handlers", function () {
 
 
             it("are registered when _converse.js is connected",
             it("are registered when _converse.js is connected",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -20,7 +20,7 @@
             }));
             }));
 
 
             it("are registered when _converse.js reconnected",
             it("are registered when _converse.js reconnected",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -35,9 +35,9 @@
 
 
         describe("An IQ stanza", function () {
         describe("An IQ stanza", function () {
 
 
-            it("is sent out when _converse.js pings a server", mock.initConverse(function (_converse) {
-                var sent_stanza, IQ_id;
-                var sendIQ = _converse.connection.sendIQ;
+            it("is sent out when _converse.js pings a server", mock.initConverse((done, _converse) => {
+                let sent_stanza, IQ_id;
+                const sendIQ = _converse.connection.sendIQ;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_stanza = iq;
                     sent_stanza = iq;
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
@@ -47,6 +47,7 @@
                     `<iq id="${IQ_id}" to="localhost" type="get" xmlns="jabber:client">`+
                     `<iq id="${IQ_id}" to="localhost" type="get" xmlns="jabber:client">`+
                         `<ping xmlns="urn:xmpp:ping"/>`+
                         `<ping xmlns="urn:xmpp:ping"/>`+
                     `</iq>`);
                     `</iq>`);
+                done();
             }));
             }));
         });
         });
     });
     });

+ 84 - 89
spec/presence.js

@@ -3,46 +3,45 @@
 (function (root, factory) {
 (function (root, factory) {
     define([
     define([
         "jasmine",
         "jasmine",
-        "jquery",
         "mock",
         "mock",
         "test-utils",
         "test-utils",
     ], factory);
     ], factory);
-} (this, function (jasmine, $, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     "use strict";
-    var Strophe = converse.env.Strophe;
-    var $iq = converse.env.$iq;
-    var $pres = converse.env.$pres;
-    var _ = converse.env._;
-    var u = converse.env.utils;
+    const Strophe = converse.env.Strophe;
+    const $iq = converse.env.$iq;
+    const $pres = converse.env.$pres;
+    const _ = converse.env._;
+    const u = converse.env.utils;
     // See: https://xmpp.org/rfcs/rfc3921.html
     // See: https://xmpp.org/rfcs/rfc3921.html
 
 
     describe("A sent presence stanza", function () {
     describe("A sent presence stanza", function () {
 
 
         it("includes a entity capabilities node",
         it("includes a entity capabilities node",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
-                function (done, _converse) {
+                (done, _converse) => {
 
 
-                _converse.api.disco.own.identities.clear();
-                _converse.api.disco.own.features.clear();
+            _converse.api.disco.own.identities.clear();
+            _converse.api.disco.own.features.clear();
 
 
-                _converse.api.disco.own.identities.add("client", "pc", "Exodus 0.9.1");
-                _converse.api.disco.own.features.add("http://jabber.org/protocol/caps");
-                _converse.api.disco.own.features.add("http://jabber.org/protocol/disco#info");
-                _converse.api.disco.own.features.add("http://jabber.org/protocol/disco#items");
-                _converse.api.disco.own.features.add("http://jabber.org/protocol/muc");
+            _converse.api.disco.own.identities.add("client", "pc", "Exodus 0.9.1");
+            _converse.api.disco.own.features.add("http://jabber.org/protocol/caps");
+            _converse.api.disco.own.features.add("http://jabber.org/protocol/disco#info");
+            _converse.api.disco.own.features.add("http://jabber.org/protocol/disco#items");
+            _converse.api.disco.own.features.add("http://jabber.org/protocol/muc");
 
 
-                const presence = _converse.xmppstatus.constructPresence();
-                expect(presence.toLocaleString()).toBe(
-                    `<presence xmlns="jabber:client">`+
-                        `<priority>0</priority>`+
-                        `<c hash="sha-1" node="https://conversejs.org" ver="QgayPKawpkPSDYmwT/WM94uAlu0=" xmlns="http://jabber.org/protocol/caps"/>`+
-                    `</presence>`)
-                done();
+            const presence = _converse.xmppstatus.constructPresence();
+            expect(presence.toLocaleString()).toBe(
+                `<presence xmlns="jabber:client">`+
+                    `<priority>0</priority>`+
+                    `<c hash="sha-1" node="https://conversejs.org" ver="QgayPKawpkPSDYmwT/WM94uAlu0=" xmlns="http://jabber.org/protocol/caps"/>`+
+                `</presence>`)
+            done();
         }));
         }));
 
 
-        it("has a given priority", mock.initConverse(function (_converse) {
-            var pres = _converse.xmppstatus.constructPresence('online', 'Hello world');
+        it("has a given priority", mock.initConverse((done, _converse) => {
+            let pres = _converse.xmppstatus.constructPresence('online', 'Hello world');
             expect(pres.toLocaleString()).toBe(
             expect(pres.toLocaleString()).toBe(
                 `<presence xmlns="jabber:client">`+
                 `<presence xmlns="jabber:client">`+
                     `<status>Hello world</status>`+
                     `<status>Hello world</status>`+
@@ -71,81 +70,77 @@
                     `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
                     `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
                 `</presence>`
                 `</presence>`
             );
             );
+            done();
         }));
         }));
 
 
         it("includes the saved status message",
         it("includes the saved status message",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
-                function (done, _converse) {
+                async (done, _converse) => {
 
 
             test_utils.openControlBox();
             test_utils.openControlBox();
-            var view = _converse.xmppstatusview;
+            const view = _converse.xmppstatusview;
             spyOn(view.model, 'sendPresence').and.callThrough();
             spyOn(view.model, 'sendPresence').and.callThrough();
             spyOn(_converse.connection, 'send').and.callThrough();
             spyOn(_converse.connection, 'send').and.callThrough();
 
 
-            var cbview = _converse.chatboxviews.get('controlbox');
+            const cbview = _converse.chatboxviews.get('controlbox');
             cbview.el.querySelector('.change-status').click()
             cbview.el.querySelector('.change-status').click()
-            var modal = _converse.xmppstatusview.status_modal;
-            test_utils.waitUntil(function () {
-                return u.isVisible(modal.el);
-            }, 1000).then(function () {
-                var msg = 'My custom status';
-                modal.el.querySelector('input[name="status_message"]').value = msg;
-                modal.el.querySelector('[type="submit"]').click();
-                expect(view.model.sendPresence).toHaveBeenCalled();
-                expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
-                    .toBe(`<presence xmlns="jabber:client">`+
-                          `<status>My custom status</status>`+
-                          `<priority>0</priority>`+
-                          `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
-                          `</presence>`)
+            const modal = _converse.xmppstatusview.status_modal;
+            await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
+            const msg = 'My custom status';
+            modal.el.querySelector('input[name="status_message"]').value = msg;
+            modal.el.querySelector('[type="submit"]').click();
+            expect(view.model.sendPresence).toHaveBeenCalled();
+            expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
+                .toBe(`<presence xmlns="jabber:client">`+
+                        `<status>My custom status</status>`+
+                        `<priority>0</priority>`+
+                        `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
+                        `</presence>`)
 
 
-                return test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "true");
-            }).then(function () {
-                cbview.el.querySelector('.change-status').click()
-                return test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
-            }).then(function () {
-                modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
-                modal.el.querySelector('[type="submit"]').click();
-                expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
-                    .toBe(`<presence xmlns="jabber:client"><show>dnd</show><status>My custom status</status><priority>0</priority>`+
-                          `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
-                          `</presence>`)
-                done();
-            });
+            await test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "true");
+            cbview.el.querySelector('.change-status').click()
+            await test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
+            modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
+            modal.el.querySelector('[type="submit"]').click();
+            expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
+                .toBe(`<presence xmlns="jabber:client"><show>dnd</show><status>My custom status</status><priority>0</priority>`+
+                        `<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
+                        `</presence>`)
+            done();
         }));
         }));
     });
     });
 
 
     describe("A received presence stanza", function () {
     describe("A received presence stanza", function () {
 
 
         it("has its priority taken into account",
         it("has its priority taken into account",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
-                function (done, _converse) {
+                (done, _converse) => {
 
 
             test_utils.openControlBox();
             test_utils.openControlBox();
             test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
             test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
             const contact_jid = mock.cur_names[8].replace(/ /g,'.').toLowerCase() + '@localhost';
             const contact_jid = mock.cur_names[8].replace(/ /g,'.').toLowerCase() + '@localhost';
             const contact = _converse.roster.get(contact_jid);
             const contact = _converse.roster.get(contact_jid);
-            let stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          from="'+contact_jid+'/priority-1-resource">'+
-            '    <priority>1</priority>'+
-            '    <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" ext="voice-v1 camera-v1 video-v1"'+
-            '       ver="AcN1/PEN8nq7AHD+9jpxMV4U6YM=" node="http://pidgin.im/"/>'+
-            '    <x xmlns="vcard-temp:x:update">'+
-            '        <photo>ce51d94f7f22b87a21274abb93710b9eb7cc1c65</photo>'+
-            '    </x>'+
-            '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T20:26:05Z" from="'+contact_jid+'/priority-1-resource"/>'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            let stanza = u.toStanza(`
+                <presence xmlns="jabber:client"
+                        to="dummy@localhost/converse.js-21770972"
+                        from="${contact_jid}/priority-1-resource">
+                    <priority>1</priority>
+                    <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" ext="voice-v1 camera-v1 video-v1"
+                        ver="AcN1/PEN8nq7AHD+9jpxMV4U6YM=" node="http://pidgin.im/"/>
+                    <x xmlns="vcard-temp:x:update">
+                        <photo>ce51d94f7f22b87a21274abb93710b9eb7cc1c65</photo>
+                    </x>
+                    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T20:26:05Z" from="${contact_jid}/priority-1-resource"/>
+                </presence>`);
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(contact.presence.get('show')).toBe('online');
             expect(contact.presence.get('show')).toBe('online');
             expect(contact.presence.resources.length).toBe(1);
             expect(contact.presence.resources.length).toBe(1);
             expect(contact.presence.resources.get('priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('priority-1-resource').get('show')).toBe('online');
             expect(contact.presence.resources.get('priority-1-resource').get('show')).toBe('online');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-0-resource">'+
             '          from="'+contact_jid+'/priority-0-resource">'+
@@ -156,7 +151,7 @@
             '       node="http://www.igniterealtime.org/projects/smack/"/>'+
             '       node="http://www.igniterealtime.org/projects/smack/"/>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T17:02:24Z" from="'+contact_jid+'/priority-0-resource"/>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T17:02:24Z" from="'+contact_jid+'/priority-0-resource"/>'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(contact.presence.get('show')).toBe('online');
             expect(contact.presence.get('show')).toBe('online');
 
 
             expect(contact.presence.resources.length).toBe(2);
             expect(contact.presence.resources.length).toBe(2);
@@ -165,14 +160,14 @@
             expect(contact.presence.resources.get('priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('priority-1-resource').get('show')).toBe('online');
             expect(contact.presence.resources.get('priority-1-resource').get('show')).toBe('online');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '    <priority>2</priority>'+
             '    <priority>2</priority>'+
             '    <show>dnd</show>'+
             '    <show>dnd</show>'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(contact.presence.get('show')).toBe('dnd');
             expect(contact.presence.get('show')).toBe('dnd');
             expect(contact.presence.resources.length).toBe(3);
             expect(contact.presence.resources.length).toBe(3);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
@@ -182,14 +177,14 @@
             expect(contact.presence.resources.get('priority-2-resource').get('priority')).toBe(2);
             expect(contact.presence.resources.get('priority-2-resource').get('priority')).toBe(2);
             expect(contact.presence.resources.get('priority-2-resource').get('show')).toBe('dnd');
             expect(contact.presence.resources.get('priority-2-resource').get('show')).toBe('dnd');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '    <priority>3</priority>'+
             '    <priority>3</priority>'+
             '    <show>away</show>'+
             '    <show>away</show>'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('away');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('away');
             expect(contact.presence.resources.length).toBe(4);
             expect(contact.presence.resources.length).toBe(4);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
@@ -201,7 +196,7 @@
             expect(contact.presence.resources.get('priority-3-resource').get('priority')).toBe(3);
             expect(contact.presence.resources.get('priority-3-resource').get('priority')).toBe(3);
             expect(contact.presence.resources.get('priority-3-resource').get('show')).toBe('away');
             expect(contact.presence.resources.get('priority-3-resource').get('show')).toBe('away');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
@@ -209,7 +204,7 @@
             '    <show>dnd</show>'+
             '    <show>dnd</show>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T15:02:24Z" from="'+contact_jid+'/older-priority-1-resource"/>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T15:02:24Z" from="'+contact_jid+'/older-priority-1-resource"/>'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('away');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('away');
             expect(contact.presence.resources.length).toBe(5);
             expect(contact.presence.resources.length).toBe(5);
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
@@ -223,13 +218,13 @@
             expect(contact.presence.resources.get('priority-3-resource').get('priority')).toBe(3);
             expect(contact.presence.resources.get('priority-3-resource').get('priority')).toBe(3);
             expect(contact.presence.resources.get('priority-3-resource').get('show')).toBe('away');
             expect(contact.presence.resources.get('priority-3-resource').get('show')).toBe('away');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('dnd');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('dnd');
             expect(contact.presence.resources.length).toBe(4);
             expect(contact.presence.resources.length).toBe(4);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
@@ -241,13 +236,13 @@
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('online');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('online');
             expect(contact.presence.resources.length).toBe(3);
             expect(contact.presence.resources.length).toBe(3);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
@@ -257,13 +252,13 @@
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-1-resource">'+
             '          from="'+contact_jid+'/priority-1-resource">'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('dnd');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('dnd');
             expect(contact.presence.resources.length).toBe(2);
             expect(contact.presence.resources.length).toBe(2);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
@@ -271,25 +266,25 @@
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('priority')).toBe(1);
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
             expect(contact.presence.resources.get('older-priority-1-resource').get('show')).toBe('dnd');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('xa');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('xa');
             expect(contact.presence.resources.length).toBe(1);
             expect(contact.presence.resources.length).toBe(1);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('priority')).toBe(0);
             expect(contact.presence.resources.get('priority-0-resource').get('show')).toBe('xa');
             expect(contact.presence.resources.get('priority-0-resource').get('show')).toBe('xa');
 
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-0-resource">'+
             '          from="'+contact_jid+'/priority-0-resource">'+
             '</presence>');
             '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('offline');
             expect(_converse.roster.get(contact_jid).presence.get('show')).toBe('offline');
             expect(contact.presence.resources.length).toBe(0);
             expect(contact.presence.resources.length).toBe(0);
             done();
             done();

+ 2 - 2
spec/profiling.js

@@ -7,7 +7,7 @@
 
 
     describe("Profiling", function() {
     describe("Profiling", function() {
         xit("adds hundreds of contacts to the roster",
         xit("adds hundreds of contacts to the roster",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -51,7 +51,7 @@
         }));
         }));
 
 
         xit("adds hundreds of contacts to the roster, with roster groups",
         xit("adds hundreds of contacts to the roster, with roster groups",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
             
             

+ 4 - 4
spec/protocol.js

@@ -49,7 +49,7 @@
              * stanza of type "result".
              * stanza of type "result".
              */
              */
             it("Subscribe to contact, contact accepts and subscribes back",
             it("Subscribe to contact, contact accepts and subscribes back",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'],
                     null, ['rosterGroupsFetched'],
                     { roster_groups: false },
                     { roster_groups: false },
                     async function (done, _converse) {
                     async function (done, _converse) {
@@ -366,7 +366,7 @@
             }));
             }));
 
 
             it("Alternate Flow: Contact Declines Subscription Request",
             it("Alternate Flow: Contact Declines Subscription Request",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -453,7 +453,7 @@
             }));
             }));
 
 
             it("Unsubscribe to a contact when subscription is mutual",
             it("Unsubscribe to a contact when subscription is mutual",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'],
                     null, ['rosterGroupsFetched'],
                     { roster_groups: false },
                     { roster_groups: false },
                     async function (done, _converse) {
                     async function (done, _converse) {
@@ -512,7 +512,7 @@
                 done();
                 done();
             }));
             }));
 
 
-            it("Receiving a subscription request", mock.initConverseWithPromises(
+            it("Receiving a subscription request", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 

+ 4 - 4
spec/push.js

@@ -10,7 +10,7 @@
     describe("XEP-0357 Push Notifications", function () {
     describe("XEP-0357 Push Notifications", function () {
 
 
         it("can be enabled",
         it("can be enabled",
-            mock.initConverseWithPromises(null,
+            mock.initConverse(null,
                 ['rosterGroupsFetched'], {
                 ['rosterGroupsFetched'], {
                     'push_app_servers': [{
                     'push_app_servers': [{
                         'jid': 'push-5@client.example',
                         'jid': 'push-5@client.example',
@@ -49,7 +49,7 @@
         }));
         }));
 
 
         it("can be enabled for a MUC domain",
         it("can be enabled for a MUC domain",
-            mock.initConverseWithPromises(null,
+            mock.initConverse(null,
                 ['rosterGroupsFetched'], {
                 ['rosterGroupsFetched'], {
                     'enable_muc_push': true,
                     'enable_muc_push': true,
                     'push_app_servers': [{
                     'push_app_servers': [{
@@ -89,7 +89,7 @@
         }));
         }));
 
 
         it("can be disabled",
         it("can be disabled",
-            mock.initConverseWithPromises(null,
+            mock.initConverse(null,
                 ['rosterGroupsFetched'], {
                 ['rosterGroupsFetched'], {
                     'push_app_servers': [{
                     'push_app_servers': [{
                         'jid': 'push-5@client.example',
                         'jid': 'push-5@client.example',
@@ -126,7 +126,7 @@
 
 
 
 
         it("can require a secret token to be included",
         it("can require a secret token to be included",
-            mock.initConverseWithPromises(null,
+            mock.initConverse(null,
                 ['rosterGroupsFetched'], {
                 ['rosterGroupsFetched'], {
                     'push_app_servers': [{
                     'push_app_servers': [{
                         'jid': 'push-5@client.example',
                         'jid': 'push-5@client.example',

+ 6 - 6
spec/register.js

@@ -9,7 +9,7 @@
     describe("The Registration Panel", function () {
     describe("The Registration Panel", function () {
 
 
         it("is not available unless allow_registration=true",
         it("is not available unless allow_registration=true",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: false },
                   allow_registration: false },
@@ -23,7 +23,7 @@
         }));
         }));
 
 
         it("can be opened by clicking on the registration tab",
         it("can be opened by clicking on the registration tab",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: true },
                   allow_registration: true },
@@ -44,7 +44,7 @@
         }));
         }));
 
 
         it("allows the user to choose an XMPP provider's domain",
         it("allows the user to choose an XMPP provider's domain",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: true },
                   allow_registration: true },
@@ -80,7 +80,7 @@
         }));
         }));
 
 
         it("will render a registration form as received from the XMPP provider",
         it("will render a registration form as received from the XMPP provider",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: true },
                   allow_registration: true },
@@ -136,7 +136,7 @@
         }));
         }));
 
 
         it("will set form_type to legacy and submit it as legacy",
         it("will set form_type to legacy and submit it as legacy",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: true },
                   allow_registration: true },
@@ -193,7 +193,7 @@
         }));
         }));
 
 
         it("will set form_type to xform and submit it as xform",
         it("will set form_type to xform and submit it as xform",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                 { auto_login: false,
                   allow_registration: true },
                   allow_registration: true },

+ 2 - 2
spec/room_registration.js

@@ -14,7 +14,7 @@
         describe("The /register commmand", function () {
         describe("The /register commmand", function () {
 
 
             it("allows you to register your nickname in a room",
             it("allows you to register your nickname in a room",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -78,7 +78,7 @@
         describe("The auto_register_muc_nickname option", function () {
         describe("The auto_register_muc_nickname option", function () {
 
 
             it("allows you to automatically register your nickname when joining a room",
             it("allows you to automatically register your nickname when joining a room",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
                     function (done, _converse) {
                     function (done, _converse) {
 
 

+ 9 - 8
spec/roomslist.js

@@ -7,7 +7,7 @@
 
 
     describe("A list of open groupchats", function () {
     describe("A list of open groupchats", function () {
 
 
-        it("is shown in controlbox", mock.initConverseWithPromises(
+        it("is shown in controlbox", mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'],
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'],
                 { allow_bookmarks: false // Makes testing easier, otherwise we
                 { allow_bookmarks: false // Makes testing easier, otherwise we
                                         // have to mock stanza traffic.
                                         // have to mock stanza traffic.
@@ -47,7 +47,7 @@
         ));
         ));
 
 
         it("uses bookmarks to determine groupchat names",
         it("uses bookmarks to determine groupchat names",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 ['send'], ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
                 ['send'], ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -113,7 +113,7 @@
 
 
     describe("A groupchat shown in the groupchats list", function () {
     describe("A groupchat shown in the groupchats list", function () {
 
 
-        it("is highlighted if its currently open", mock.initConverseWithPromises(
+        it("is highlighted if its currently open", mock.initConverse(
             null, ['rosterGroupsFetched', 'chatBoxesFetched'],
             null, ['rosterGroupsFetched', 'chatBoxesFetched'],
             { whitelisted_plugins: ['converse-roomslist'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we
               allow_bookmarks: false // Makes testing easier, otherwise we
@@ -142,7 +142,7 @@
             done();
             done();
         }));
         }));
 
 
-        it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
+        it("has an info icon which opens a details modal when clicked", mock.initConverse(
             null, ['rosterGroupsFetched', 'chatBoxesFetched'],
             null, ['rosterGroupsFetched', 'chatBoxesFetched'],
             { whitelisted_plugins: ['converse-roomslist'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we
               allow_bookmarks: false // Makes testing easier, otherwise we
@@ -249,7 +249,7 @@
             done();
             done();
         }));
         }));
 
 
-        it("can be closed", mock.initConverseWithPromises(
+        it("can be closed", mock.initConverse(
             null, ['rosterGroupsFetched'],
             null, ['rosterGroupsFetched'],
             { whitelisted_plugins: ['converse-roomslist'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
               allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
@@ -272,10 +272,11 @@
             done();
             done();
         }));
         }));
 
 
-        it("shows unread messages directed at the user", mock.initConverseWithAsync(
-            { whitelisted_plugins: ['converse-roomslist'],
+        it("shows unread messages directed at the user", mock.initConverse(
+                null, null,
+                { whitelisted_plugins: ['converse-roomslist'],
                 allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
                 allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
-            }, async function (done, _converse) {
+                }, async (done, _converse) => {
 
 
             test_utils.openControlBox();
             test_utils.openControlBox();
             const room_jid = 'kitchen@conference.shakespeare.lit';
             const room_jid = 'kitchen@conference.shakespeare.lit';

+ 44 - 45
spec/roster.js

@@ -31,7 +31,7 @@
     describe("The Contacts Roster", function () {
     describe("The Contacts Roster", function () {
 
 
         it("supports roster versioning",
         it("supports roster versioning",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -90,7 +90,7 @@
         describe("The live filter", function () {
         describe("The live filter", function () {
 
 
             it("will only appear when roster contacts flow over the visible area",
             it("will only appear when roster contacts flow over the visible area",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -136,7 +136,7 @@
             }));
             }));
 
 
             it("can be used to filter the contacts shown",
             it("can be used to filter the contacts shown",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -202,7 +202,7 @@
             }));
             }));
 
 
             it("will also filter out contacts added afterwards",
             it("will also filter out contacts added afterwards",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -252,7 +252,7 @@
             }));
             }));
 
 
             it("can be used to filter the groups shown",
             it("can be used to filter the groups shown",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -308,7 +308,7 @@
             }));
             }));
 
 
             it("has a button with which its contents can be cleared",
             it("has a button with which its contents can be cleared",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -333,7 +333,7 @@
             }));
             }));
 
 
             it("can be used to filter contacts by their chat state",
             it("can be used to filter contacts by their chat state",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -374,7 +374,7 @@
         describe("A Roster Group", function () {
         describe("A Roster Group", function () {
 
 
             it("can be used to organize existing contacts",
             it("can be used to organize existing contacts",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -412,7 +412,7 @@
             }));
             }));
 
 
             it("gets created when a contact's \"groups\" attribute changes",
             it("gets created when a contact's \"groups\" attribute changes",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -457,7 +457,7 @@
             }));
             }));
 
 
             it("can share contacts with other roster groups", 
             it("can share contacts with other roster groups", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -490,7 +490,7 @@
             }));
             }));
 
 
             it("remembers whether it is closed or opened",
             it("remembers whether it is closed or opened",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -535,7 +535,7 @@
             }
             }
 
 
             it("can be collapsed under their own header", 
             it("can be collapsed under their own header", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -549,7 +549,7 @@
             }));
             }));
 
 
             it("can be added to the roster",
             it("can be added to the roster",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -566,7 +566,7 @@
             }));
             }));
 
 
             it("are shown in the roster when show_only_online_users", 
             it("are shown in the roster when show_only_online_users", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -583,7 +583,7 @@
             }));
             }));
 
 
             it("are shown in the roster when hide_offline_users", 
             it("are shown in the roster when hide_offline_users", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -603,7 +603,7 @@
             }));
             }));
 
 
             it("can be removed by the user", 
             it("can be removed by the user", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -643,7 +643,7 @@
             }));
             }));
 
 
             it("do not have a header if there aren't any", 
             it("do not have a header if there aren't any", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -659,9 +659,9 @@
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback) {
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback) {
                     if (typeof callback === "function") { return callback(); }
                     if (typeof callback === "function") { return callback(); }
                 });
                 });
-                await test_utils.waitUntil(function () {
-                    var $pending_contacts = $(_converse.rosterview.get('Pending contacts').el);
-                    return $pending_contacts.is(':visible') && $pending_contacts.find('li:visible').length;
+                await test_utils.waitUntil(() => {
+                    const el = _converse.rosterview.get('Pending contacts').el;
+                    return u.isVisible(el) && _.filter(el.querySelectorAll('li'), li => u.isVisible(li)).length;
                 }, 700)
                 }, 700)
                             
                             
                 $(_converse.rosterview.el).find(".pending-contact-name:contains('"+name+"')")
                 $(_converse.rosterview.el).find(".pending-contact-name:contains('"+name+"')")
@@ -674,7 +674,7 @@
             }));
             }));
 
 
             it("is shown when a new private message is received",
             it("is shown when a new private message is received",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -694,7 +694,7 @@
             }));
             }));
 
 
             it("can be added to the roster and they will be sorted alphabetically",
             it("can be added to the roster and they will be sorted alphabetically",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -725,13 +725,12 @@
         });
         });
 
 
         describe("Existing Contacts", function () {
         describe("Existing Contacts", function () {
-            var _addContacts = function (_converse) {
-                test_utils.createContacts(_converse, 'current')
-                    .openControlBox()
-            };
+            function _addContacts (_converse) {
+                test_utils.createContacts(_converse, 'current').openControlBox()
+            }
 
 
             it("can be collapsed under their own header", 
             it("can be collapsed under their own header", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -747,7 +746,7 @@
             }));
             }));
 
 
             it("will be hidden when appearing under a collapsed group", 
             it("will be hidden when appearing under a collapsed group", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -774,7 +773,7 @@
             }));
             }));
 
 
             it("can be added to the roster and they will be sorted alphabetically", 
             it("can be added to the roster and they will be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -804,7 +803,7 @@
             }));
             }));
 
 
             it("can be removed by the user", 
             it("can be removed by the user", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -836,7 +835,7 @@
             }));
             }));
 
 
             it("do not have a header if there aren't any", 
             it("do not have a header if there aren't any", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -866,7 +865,7 @@
             }));
             }));
 
 
             it("can change their status to online and be sorted alphabetically", 
             it("can change their status to online and be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -891,7 +890,7 @@
             }));
             }));
 
 
             it("can change their status to busy and be sorted alphabetically", 
             it("can change their status to busy and be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -918,7 +917,7 @@
             }));
             }));
 
 
             it("can change their status to away and be sorted alphabetically", 
             it("can change their status to away and be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -945,7 +944,7 @@
             }));
             }));
 
 
             it("can change their status to xa and be sorted alphabetically", 
             it("can change their status to xa and be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -972,7 +971,7 @@
             }));
             }));
 
 
             it("can change their status to unavailable and be sorted alphabetically", 
             it("can change their status to unavailable and be sorted alphabetically", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1000,7 +999,7 @@
             }));
             }));
 
 
             it("are ordered according to status: online, busy, away, xa, unavailable, offline", 
             it("are ordered according to status: online, busy, away, xa, unavailable, offline", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1101,7 +1100,7 @@
         describe("Requesting Contacts", function () {
         describe("Requesting Contacts", function () {
 
 
             it("can be added to the roster and they will be sorted alphabetically",
             it("can be added to the roster and they will be sorted alphabetically",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1137,7 +1136,7 @@
             }));
             }));
 
 
             it("do not have a header if there aren't any", 
             it("do not have a header if there aren't any", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1164,7 +1163,7 @@
             }));
             }));
 
 
             it("can be collapsed under their own header", 
             it("can be collapsed under their own header", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1180,7 +1179,7 @@
             }));
             }));
 
 
             it("can have their requests accepted by the user", 
             it("can have their requests accepted by the user", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
@@ -1203,7 +1202,7 @@
             }));
             }));
 
 
             it("can have their requests denied by the user", 
             it("can have their requests denied by the user", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1227,7 +1226,7 @@
                 });
                 });
             }));
             }));
 
 
-            it("are persisted even if other contacts' change their presence ", mock.initConverseWithPromises(
+            it("are persisted even if other contacts' change their presence ", mock.initConverse(
                 null, ['rosterGroupsFetched'], {}, function (done, _converse) {
                 null, ['rosterGroupsFetched'], {}, function (done, _converse) {
 
 
                 /* This is a regression test.
                 /* This is a regression test.
@@ -1275,7 +1274,7 @@
         describe("All Contacts", function () {
         describe("All Contacts", function () {
 
 
             it("are saved to, and can be retrieved from browserStorage",
             it("are saved to, and can be retrieved from browserStorage",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 
@@ -1303,7 +1302,7 @@
             }));
             }));
 
 
             it("will show fullname and jid properties on tooltip", 
             it("will show fullname and jid properties on tooltip", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 

+ 8 - 8
spec/spoilers.js

@@ -10,9 +10,9 @@
     describe("A spoiler message", function () {
     describe("A spoiler message", function () {
 
 
         it("can be received with a hint",
         it("can be received with a hint",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
             test_utils.createContacts(_converse, 'current');
             test_utils.createContacts(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -47,9 +47,9 @@
         }));
         }));
 
 
         it("can be received without a hint",
         it("can be received without a hint",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
             test_utils.createContacts(_converse, 'current');
             test_utils.createContacts(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -80,9 +80,9 @@
         }));
         }));
 
 
         it("can be sent without a hint",
         it("can be sent without a hint",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
             test_utils.createContacts(_converse, 'current', 1);
             test_utils.createContacts(_converse, 'current', 1);
             _converse.emit('rosterContactsFetched');
             _converse.emit('rosterContactsFetched');
@@ -155,9 +155,9 @@
         }));
         }));
 
 
         it("can be sent with a hint",
         it("can be sent with a hint",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
 
             test_utils.createContacts(_converse, 'current', 1);
             test_utils.createContacts(_converse, 'current', 1);
             _converse.emit('rosterContactsFetched');
             _converse.emit('rosterContactsFetched');

+ 1 - 1
spec/transcripts.js

@@ -50,7 +50,7 @@
     return describe("Transcripts of chat logs", function () {
     return describe("Transcripts of chat logs", function () {
 
 
         it("can be used to replay conversations",
         it("can be used to replay conversations",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
                     function (done, _converse) {
 
 

+ 7 - 7
spec/user-details-modal.js

@@ -6,16 +6,16 @@
         ], factory);
         ], factory);
 } (this, function (jasmine, mock, test_utils) {
 } (this, function (jasmine, mock, test_utils) {
     "use strict";
     "use strict";
-    var _ = converse.env._;
-    var $iq = converse.env.$iq;
-    var $msg = converse.env.$msg;
-    var Strophe = converse.env.Strophe;
-    var u = converse.env.utils;
+    const _ = converse.env._;
+    const $iq = converse.env.$iq;
+    const $msg = converse.env.$msg;
+    const Strophe = converse.env.Strophe;
+    const u = converse.env.utils;
 
 
     return describe("The User Details Modal", function () {
     return describe("The User Details Modal", function () {
 
 
         it("can be used to remove a contact",
         it("can be used to remove a contact",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 
@@ -49,7 +49,7 @@
         }));
         }));
 
 
         it("shows an alert when an error happened while removing the contact",
         it("shows an alert when an error happened while removing the contact",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
                 async function (done, _converse) {
 
 

+ 12 - 11
spec/xmppstatus.js

@@ -1,21 +1,22 @@
 (function (root, factory) {
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "test-utils"], factory);
-} (this, function ($, jasmine, mock, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
 
 
-    return describe("The XMPPStatus model", function() {
+    return describe("The XMPPStatus model", function () {
 
 
-        it("won't send <show>online</show> when setting a custom status message", mock.initConverse(function (_converse) {
+        it("won't send <show>online</show> when setting a custom status message", mock.initConverse((done, _converse) => {
             _converse.xmppstatus.save({'status': 'online'});
             _converse.xmppstatus.save({'status': 'online'});
             spyOn(_converse.connection, 'send');
             spyOn(_converse.connection, 'send');
             _converse.api.user.status.message.set("I'm also happy!");
             _converse.api.user.status.message.set("I'm also happy!");
             expect(_converse.connection.send).toHaveBeenCalled();
             expect(_converse.connection.send).toHaveBeenCalled();
-            var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
-            expect($stanza.children().length).toBe(3);
-            expect($stanza.children('status').length).toBe(1);
-            expect($stanza.children('status').text()).toBe("I'm also happy!");
-            expect($stanza.children('show').length).toBe(0);
-            expect($stanza.children('priority').length).toBe(1);
-            expect($stanza.children('priority').text()).toBe('0');
+            const stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
+            expect(stanza.childNodes.length).toBe(3);
+            expect(stanza.querySelectorAll('status').length).toBe(1);
+            expect(stanza.querySelector('status').textContent).toBe("I'm also happy!");
+            expect(stanza.querySelectorAll('show').length).toBe(0);
+            expect(stanza.querySelectorAll('priority').length).toBe(1);
+            expect(stanza.querySelector('priority').textContent).toBe('0');
+            done();
         }));
         }));
     });
     });
 }));
 }));

+ 10 - 13
src/headless/converse-core.js

@@ -463,7 +463,7 @@ function cleanup () {
 }
 }
 
 
 
 
-_converse.initialize = function (settings, callback) {
+_converse.initialize = async function (settings, callback) {
     settings = !_.isUndefined(settings) ? settings : {};
     settings = !_.isUndefined(settings) ? settings : {};
     const init_promise = u.getResolveablePromise();
     const init_promise = u.getResolveablePromise();
     _.each(PROMISES, addPromise);
     _.each(PROMISES, addPromise);
@@ -1212,21 +1212,18 @@ _converse.initialize = function (settings, callback) {
         this.connection = settings.connection;
         this.connection = settings.connection;
     }
     }
 
 
-    if (!_.isUndefined(_converse.connection) &&
-            _converse.connection.service === 'jasmine tests') {
+    if (_.get(_converse.connection, 'service') === 'jasmine tests') {
         finishInitialization();
         finishInitialization();
         return _converse;
         return _converse;
-    } else if (_.isUndefined(i18n)) {
-        finishInitialization();
-    } else {
-        i18n.fetchTranslations(
-            _converse.locale,
-            _converse.locales,
-            u.interpolate(_converse.locales_url, {'locale': _converse.locale}))
-        .catch(e => _converse.log(e.message, Strophe.LogLevel.FATAL))
-        .finally(finishInitialization)
-        .catch(e => _converse.log(e.message, Strophe.LogLevel.FATAL));
+    } else if (!_.isUndefined(i18n)) {
+        const url = u.interpolate(_converse.locales_url, {'locale': _converse.locale});
+        try {
+            await i18n.fetchTranslations(_converse.locale, _converse.locales, url);
+        } catch (e) {
+            _converse.log(e.message, Strophe.LogLevel.FATAL);
+        }
     }
     }
+    finishInitialization();
     return init_promise;
     return init_promise;
 };
 };
 
 

+ 4 - 0
src/headless/utils/core.js

@@ -16,6 +16,10 @@ import sizzle from "sizzle";
 
 
 const u = {};
 const u = {};
 
 
+u.toStanza = function (string) {
+    return Strophe.xmlHtmlNode(string).firstElementChild;
+}
+
 u.getLongestSubstring = function (string, candidates) {
 u.getLongestSubstring = function (string, candidates) {
     function reducer (accumulator, current_value) {
     function reducer (accumulator, current_value) {
         if (string.startsWith(current_value)) {
         if (string.startsWith(current_value)) {

+ 28 - 48
tests/mock.js

@@ -1,12 +1,12 @@
 (function (root, factory) {
 (function (root, factory) {
     define("mock", [], factory);
     define("mock", [], factory);
 }(this, function () {
 }(this, function () {
-    var _ = converse.env._;
-    var Promise = converse.env.Promise;
-    var Strophe = converse.env.Strophe;
-    var moment = converse.env.moment;
-    var $iq = converse.env.$iq;
-    var u = converse.env.utils;
+    const _ = converse.env._;
+    const Promise = converse.env.Promise;
+    const Strophe = converse.env.Strophe;
+    const moment = converse.env.moment;
+    const $iq = converse.env.$iq;
+    const u = converse.env.utils;
 
 
     window.libsignal = {
     window.libsignal = {
         'SignalProtocolAddress': function (name, device_id) {
         'SignalProtocolAddress': function (name, device_id) {
@@ -19,7 +19,7 @@
             this.encrypt = () => Promise.resolve({
             this.encrypt = () => Promise.resolve({
                 'type': 1,
                 'type': 1,
                 'body': 'c1ph3R73X7',
                 'body': 'c1ph3R73X7',
-                'registrationId': '1337' 
+                'registrationId': '1337'
             });
             });
             this.decryptPreKeyWhisperMessage = (key_and_tag) => {
             this.decryptPreKeyWhisperMessage = (key_and_tag) => {
                 return Promise.resolve(key_and_tag);
                 return Promise.resolve(key_and_tag);
@@ -66,7 +66,7 @@
         }
         }
     };
     };
 
 
-    var mock = {};
+    const mock = {};
     mock.view_mode = 'overlayed';
     mock.view_mode = 'overlayed';
 
 
     // Names from http://www.fakenamegenerator.com/
     // Names from http://www.fakenamegenerator.com/
@@ -158,7 +158,7 @@
         };
         };
     }();
     }();
 
 
-    function initConverse (settings, spies, promises) {
+    async function initConverse (settings, spies, promises) {
         window.localStorage.clear();
         window.localStorage.clear();
         window.sessionStorage.clear();
         window.sessionStorage.clear();
         const el = document.querySelector('#conversejs');
         const el = document.querySelector('#conversejs');
@@ -173,7 +173,7 @@
             });
             });
         }
         }
 
 
-        const _converse = converse.initialize(_.extend({
+        const _converse = await converse.initialize(_.extend({
             'i18n': 'en',
             'i18n': 'en',
             'auto_subscribe': false,
             'auto_subscribe': false,
             'play_sounds': false,
             'play_sounds': false,
@@ -196,19 +196,19 @@
                 } else if (!model.get('vcard_updated') || force) {
                 } else if (!model.get('vcard_updated') || force) {
                     jid = model.get('jid') || model.get('muc_jid');
                     jid = model.get('jid') || model.get('muc_jid');
                 }
                 }
-                var fullname;
+                let fullname;
                 if (!jid || jid == 'dummy@localhost') {
                 if (!jid || jid == 'dummy@localhost') {
                     jid = 'dummy@localhost';
                     jid = 'dummy@localhost';
                     fullname = 'Max Mustermann' ;
                     fullname = 'Max Mustermann' ;
                 } else {
                 } else {
-                    var name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
-                    var last = name.length-1;
+                    const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
+                    const last = name.length-1;
                     name[0] =  name[0].charAt(0).toUpperCase()+name[0].slice(1);
                     name[0] =  name[0].charAt(0).toUpperCase()+name[0].slice(1);
                     name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
                     name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
                     fullname = name.join(' ');
                     fullname = name.join(' ');
                 }
                 }
-                var vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
-                var result = {
+                const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
+                const result = {
                     'vcard': vcard,
                     'vcard': vcard,
                     'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
                     'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
                     'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
                     'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
@@ -230,41 +230,21 @@
         return _converse;
         return _converse;
     }
     }
 
 
-    mock.initConverseWithPromises = function (spies, promise_names, settings, func) {
-        return function (done) {
-            const _converse = initConverse(settings, spies);
-            const promises = _.map(promise_names, _converse.api.waitUntil);
-            Promise.all(promises)
-                .then(_.partial(func, done, _converse))
-                .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+    mock.initConverse = function (spies, promise_names=null, settings=null, func) {
+        if (_.isFunction(spies)) {
+            func = spies;
+            spies = null;
+            promise_names = null
+            settings = null;
         }
         }
-    };
-
-    mock.initConverseWithConnectionSpies = function (spies, settings, func) {
-        return function (done) {
-            return func(done, initConverse(settings, spies));
-        };
-    };
-
-    mock.initConverseWithAsync = function (settings, func) {
-        if (_.isFunction(settings)) {
-            var _func = settings;
-            settings = func;
-            func = _func;
-        }
-        return function (done) {
-            return func(done, initConverse(settings));
-        };
-    };
-    mock.initConverse = function (settings, func) {
-        if (_.isFunction(settings)) {
-            var _func = settings;
-            settings = func;
-            func = _func;
+        return done => {
+            initConverse(settings, spies).then(_converse => {
+                const promises = _.map(promise_names, _converse.api.waitUntil);
+                Promise.all(promises)
+                    .then(_.partial(func, done, _converse))
+                    .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+            });
         }
         }
-        return function () {
-            return func(initConverse(settings));
-        };
     };
     };
     return mock;
     return mock;
 }));
 }));