Bläddra i källkod

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 år sedan
förälder
incheckning
9f5031c278

+ 16 - 7
dist/converse.js

@@ -62984,7 +62984,7 @@ function cleanup() {
   initClientConfig();
 }
 
-_converse.initialize = function (settings, callback) {
+_converse.initialize = async function (settings, callback) {
   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();
 
@@ -63821,17 +63821,22 @@ _converse.initialize = function (settings, callback) {
     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();
     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
-    })).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;
 };
 /**
@@ -69717,6 +69722,10 @@ __webpack_require__.r(__webpack_exports__);
 
 const u = {};
 
+u.toStanza = function (string) {
+  return strophe_js__WEBPACK_IMPORTED_MODULE_2__["Strophe"].xmlHtmlNode(string).firstElementChild;
+};
+
 u.getLongestSubstring = function (string, candidates) {
   function reducer(accumulator, current_value) {
     if (string.startsWith(current_value)) {

+ 2 - 2
spec/autocomplete.js

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

+ 10 - 10
spec/bookmarks.js

@@ -19,7 +19,7 @@
 
     describe("A chat room", function () {
 
-        it("can be bookmarked", mock.initConverseWithPromises(
+        it("can be bookmarked", mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             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'], {},
             async function (done, _converse) {
 
@@ -173,7 +173,7 @@
 
         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'], {},
                 async function (done, _converse) {
 
@@ -194,7 +194,7 @@
                 done();
             }));
 
-            it("can be unbookmarked", mock.initConverseWithPromises(
+            it("can be unbookmarked", mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -270,7 +270,7 @@
 
         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'], {},
                 async function (done, _converse) {
 
@@ -303,7 +303,7 @@
 
     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'], {},
             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'], {},
             async function (done, _converse) {
 
@@ -452,7 +452,7 @@
 
         describe("The rooms panel", function () {
 
-            it("shows a list of bookmarks", mock.initConverseWithPromises(
+            it("shows a list of bookmarks", mock.initConverse(
                 ['send'], ['rosterGroupsFetched'], {},
                 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'], {},
                 async function (done, _converse) {
 
@@ -606,7 +606,7 @@
 
     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'],
             { hide_open_bookmarks: true },
             async function (done, _converse) {

+ 61 - 61
spec/chatbox.js

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

+ 8 - 8
spec/controlbox.js

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

+ 54 - 38
spec/converse.js

@@ -12,7 +12,7 @@
         
         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 connection = _converse.connection;
                 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."));
                 _converse.bosh_service_url = url;
                 _converse.connection = connection;
+                done();
             }));
 
             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;
                     _converse.keepalive = true;
                     _converse.authentication = "prebind";
@@ -37,10 +38,11 @@
                     _converse.authentication= authentication;
                     _converse.jid = jid;
                     _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;
                     _converse.keepalive = false;
                     _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."));
                     _converse.bosh_service_url = undefined;
                     _converse.jid = jid;
+                    done();
                 }));
             });
         });
@@ -55,16 +58,14 @@
         describe("A chat state indication", function () {
 
             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();
-                var sent_stanza;
+                let sent_stanza;
                 spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
                     sent_stanza = stanza;
                 });
-                var i = 0;
+                let i = 0;
                 _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
 
@@ -88,8 +89,8 @@
 
         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
                 _converse.idle_seconds = 0;
                 _converse.auto_changed_status = false;
@@ -156,6 +157,7 @@
                 _converse.onUserActivity();
                 expect(_converse.api.user.status.get()).toBe('dnd');
                 expect(_converse.auto_changed_status).toBe(false);
+                done();
             }));
         });
 
@@ -163,14 +165,15 @@
 
             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');
                     expect(_converse.api.user.status.get()).toBe('online');
                     _converse.xmppstatus.set('status', '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');
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     _converse.api.user.status.set('dnd');
@@ -182,34 +185,38 @@
                     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')
                     );
+                    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");
                     expect(_converse.xmppstatus.get('status')).toBe('away');
                     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);
                     expect(_converse.api.user.status.message.get()).toBe(undefined);
                     _converse.xmppstatus.set('status_message', "I'm in a meeting");
                     expect(_converse.api.user.status.message.get()).toBe("I'm in a meeting");
+                    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.api.user.status.message.set("I'm in a meeting");
                     expect(_converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
+                    done();
                 }));
             });
         });
 
         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');
-                var old_connection = _converse.connection;
+                const old_connection = _converse.connection;
                 _converse.connection._proto.rid = '1234';
                 _converse.expose_rid_and_sid = false;
                 expect(_converse.api.tokens.get('rid')).toBe(null);
@@ -219,11 +226,12 @@
                 expect(_converse.api.tokens.get('rid')).toBe(null);
                 // Restore the 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');
-                var old_connection = _converse.connection;
+                const old_connection = _converse.connection;
                 _converse.connection._proto.sid = '1234';
                 _converse.expose_rid_and_sid = false;
                 expect(_converse.api.tokens.get('sid')).toBe(null);
@@ -233,47 +241,50 @@
                 expect(_converse.api.tokens.get('sid')).toBe(null);
                 // Restore the connection
                 _converse.connection = old_connection;
+                done();
             }));
         });
 
         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
                 test_utils.createContacts(_converse, 'current');
                 expect(_converse.api.contacts.get('non-existing@jabber.org')).toBeFalsy();
                 // Check when a single jid is given
-                var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-                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('jid')).toBe(jid);
                 // 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(list[0].get('fullname')).toBe(mock.cur_names[0]);
                 expect(list[1].get('fullname')).toBe(mock.cur_names[1]);
                 // Check that all JIDs are returned if you call without any parameters
                 list = _converse.api.contacts.get();
                 expect(list.length).toBe(mock.cur_names.length);
+                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');
-                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.bind(_converse.api, "invalid jid")).toThrow(error);
                 spyOn(_converse.roster, 'addAndSubscribe');
                 _converse.api.contacts.add("newcontact@example.org");
                 expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
+                done();
             }));
         });
 
         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'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
                 test_utils.openControlBox();
                 test_utils.createContacts(_converse, 'current', 2);
@@ -308,9 +319,9 @@
                 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'], {},
-                async function (done, _converse) {
+                async (done, _converse) => {
 
                 test_utils.openControlBox();
                 test_utils.createContacts(_converse, 'current', 2);
@@ -341,8 +352,8 @@
 
         describe("The \"settings\" API", function() {
             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(_converse.api.settings.get("play_sounds")).toBe(true);
@@ -354,11 +365,12 @@
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
                 _converse.api.settings.set("non_existing", true);
                 expect(typeof _converse.api.settings.get("non_existing")).toBe("undefined");
+                done();
             }));
         });
 
         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"]);
                 // Cheating a little bit. We clear the plugins to test more easily.
                 const _old_plugins = _converse.pluggable.plugins;
@@ -368,13 +380,17 @@
                 converse.plugins.add('plugin2', {});
                 expect(_.keys(_converse.pluggable.plugins)).toEqual(['plugin1', 'plugin2']);
                 _converse.pluggable.plugins = _old_plugins;
+                done();
             }));
 
             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', {});
-                    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);
+                    done();
                 }));
             });
         });

+ 2 - 2
spec/disco.js

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

+ 6 - 3
spec/eventemitter.js

@@ -4,7 +4,7 @@
 
     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 () {};
             spyOn(this, 'callback');
             _converse.on('connected', this.callback);
@@ -14,9 +14,10 @@
             expect(this.callback.calls.count(), 2);
             _converse.emit('connected');
             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 () {};
             spyOn(this, 'callback');
             _converse.once('connected', this.callback);
@@ -26,9 +27,10 @@
             expect(this.callback.calls.count(), 1);
             _converse.emit('connected');
             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.anotherCallback = function () {};
             this.neverCalled = function () {};
@@ -56,6 +58,7 @@
             expect(this.callback.calls.count(), 1);
             expect(this.anotherCallback.calls.count(), 3);
             expect(this.neverCalled).not.toHaveBeenCalled();
+            done();
         }));
     });
 }));

+ 5 - 3
spec/headline.js

@@ -13,7 +13,7 @@
 
     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:
              *
              *  <message xmlns="jabber:client"
@@ -37,9 +37,10 @@
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
             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) {
 
             /* <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",
-            mock.initConverse(function (_converse) {
+            mock.initConverse((done, _converse) => {
 
             _converse.allow_non_roster_messaging = false;
             sinon.spy(utils, 'isHeadlineMessage');
@@ -101,6 +102,7 @@
             expect(utils.isHeadlineMessage.called).toBeTruthy();
             expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
             utils.isHeadlineMessage.restore(); // unwraps
+            done();
         }));
     });
 }));

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

@@ -5,19 +5,19 @@
         "test-utils"], factory);
 } (this, function (jasmine, mock, test_utils) {
     "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("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.waitUntil(() => _.filter(
                     IQ_stanzas,
@@ -41,8 +41,7 @@
                     return iq.nodeTree.querySelector(
                         '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({
                     'type': 'result',
                     'from': 'localhost',
@@ -173,43 +172,37 @@
         describe("When not supported", 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';
                     test_utils.createContacts(_converse, 'current');
                     test_utils.openChatBoxFor(_converse, contact_jid);
 
-                    test_utils.waitUntilDiscoConfirmed(
+                    await test_utils.waitUntilDiscoConfirmed(
                         _converse, _converse.domain,
                         [{'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'], {},
-                        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 () {
 
-                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,
                         [{'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'], {},
-                        function (done, _converse) {
+                        async (done, _converse) => {
 
-                    test_utils.waitUntilDiscoConfirmed(
+                    await test_utils.waitUntilDiscoConfirmed(
                         _converse, _converse.domain,
                         [{'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 () {
 
-                    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';
-
                         await test_utils.waitUntilDiscoConfirmed(
                             _converse, _converse.domain,
                             [{'category': 'server', 'type':'IM'}],
@@ -298,7 +277,7 @@
                         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);
-                        var iq = IQ_stanzas.pop();
+                        const iq = IQ_stanzas.pop();
                         expect(iq.toLocaleString()).toBe(
                             `<iq from="dummy@localhost/resource" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
@@ -312,21 +291,21 @@
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                             `</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 () {
                             const message = view.model.messages.at(0);
@@ -375,8 +354,7 @@
                         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';
                         await test_utils.waitUntilDiscoConfirmed(
@@ -401,7 +379,7 @@
                         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);
-                        var iq = IQ_stanzas.pop();
+                        const iq = IQ_stanzas.pop();
                         expect(iq.toLocaleString()).toBe(
                             `<iq from="dummy@localhost/resource" `+
                                 `id="${iq.nodeTree.getAttribute("id")}" `+
@@ -415,21 +393,20 @@
                                 `xmlns="urn:xmpp:http:upload:0"/>`+
                             `</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 () {
                             const message = view.model.messages.at(0);
@@ -478,7 +455,7 @@
                         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_ids =  _converse.connection.IQ_ids;
                         const send_backup = XMLHttpRequest.prototype.send;
@@ -602,7 +579,7 @@
 
             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'], {},
                     async function (done, _converse) {
 
@@ -646,19 +623,19 @@
 
                     const base_url = 'https://conversejs.org';
                     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 () {
                         const message = view.model.messages.at(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 () {
 
         it("contains a checkbox to indicate whether the computer is trusted or not",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                   allow_registration: false },
@@ -43,7 +43,7 @@
         }));
 
         it("checkbox can be set to false by default",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['connectionInitialized', 'chatBoxesInitialized'],
                 { auto_login: false,
                   trusted: false,

+ 38 - 38
spec/mam.js

@@ -8,6 +8,7 @@
     const $iq = converse.env.$iq;
     const $msg = converse.env.$msg;
     const moment = converse.env.moment;
+    const u = converse.env.utils;
     // See: https://xmpp.org/rfcs/rfc3921.html
 
     describe("Message Archive Management", function () {
@@ -16,18 +17,17 @@
         describe("Archived Messages", function () {
 
            it("aren't shown as duplicates by comparing their stanza-id attribute", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     async function (done, _converse) {
 
                 await test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand');
                 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)">
                         <body>negan</body>
                         <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));
                 await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
                 // 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
                 // in "real-world" situations.
-                stanza = Strophe.xmlHtmlNode(
+                stanza = u.toStanza(
                     `<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">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -48,7 +48,7 @@
                                 </message>
                             </forwarded>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
 
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 view.model.onMessage(stanza);
@@ -58,13 +58,13 @@
             }));
 
            it("aren't shown as duplicates by comparing their queryid attribute", 
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     async function (done, _converse) {
 
                 await test_utils.openAndEnterChatRoom(_converse, 'discuss', 'conference.conversejs.org', 'dummy');
                 const view = _converse.chatboxviews.get('discuss@conference.conversejs.org');
-                let stanza = Strophe.xmlHtmlNode(
+                let stanza = u.toStanza(
                     `<message xmlns="jabber:client"
                               to="discuss@conference.conversejs.org"
                               type="groupchat" xml:lang="en"
@@ -74,11 +74,11 @@
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="prezel@blubber.im" role="participant"/>
                         </x>
-                    </message>`).firstElementChild;
+                    </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 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">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -91,7 +91,7 @@
                                 </message>
                             </forwarded>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
 
                 spyOn(view.model, 'isDuplicate').and.callThrough();
                 view.model.onMessage(stanza);
@@ -99,7 +99,7 @@
                 expect(view.model.isDuplicate.calls.count()).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">
                         <result xmlns="urn:xmpp:mam:2" queryid="06fea9ca-97c9-48c4-8583-009ff54ea2e8" id="7a9fde91-4387-4bf8-b5d3-978dab8f6bf3">
                             <forwarded xmlns="urn:xmpp:forward:0">
@@ -112,7 +112,7 @@
                                 </message>
                             </forwarded>
                         </result>
-                    </message>`).firstElementChild;
+                    </message>`);
                 view.model.onMessage(stanza);
                 expect(view.model.isDuplicate.calls.count()).toBe(2);
                 expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
@@ -123,12 +123,12 @@
         describe("The archive.query API", function () {
 
            it("can be used to query for all archived messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['discoInitialized'], {},
                     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) {
                     sent_stanza = iq;
                     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.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(
                     `<iq id="${IQ_id}" type="set" xmlns="jabber:client"><query queryid="${queryid}" xmlns="urn:xmpp:mam:2"/></iq>`);
                 done();
             }));
 
            it("can be used to query for all messages to/from a particular JID",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -177,7 +177,7 @@
             }));
 
            it("can be used to query for archived messages from a chat room",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -211,7 +211,7 @@
            }));
 
             it("checks whether returned MAM messages from a MUC room are from the right JID",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -219,16 +219,16 @@
                 if (!entity.features.findWhere({'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;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_stanza = iq;
                     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);
-                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'>
                  *     <result xmlns='urn:xmpp:mam:2' queryid='g27' id='34482-21985-73620'>
@@ -249,7 +249,7 @@
                  *     </result>
                  * </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('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
@@ -283,13 +283,13 @@
 
                 await test_utils.waitUntil(() => callback.calls.count());
                 expect(callback).toHaveBeenCalled();
-                var args = callback.calls.argsFor(0);
+                const args = callback.calls.argsFor(0);
                 expect(args[0].length).toBe(0);
                 done();
            }));
 
            it("can be used to query for all messages in a certain timespan",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -332,7 +332,7 @@
            }));
 
            it("throws a TypeError if an invalid date is provided",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -347,7 +347,7 @@
            }));
 
            it("can be used to query for all messages after a certain time",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -385,7 +385,7 @@
            }));
 
            it("can be used to query for a limited set of results",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -423,7 +423,7 @@
            }));
 
            it("can be used to page through results",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -465,7 +465,7 @@
            }));
 
            it("accepts \"before\" with an empty string as value to reverse the order",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -499,7 +499,7 @@
            }));
 
            it("accepts a Strophe.RSM object for the query options",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -546,7 +546,7 @@
            }));
 
            it("accepts a callback function, which it passes the messages and a Strophe.RSM object",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -579,7 +579,7 @@
                  *  </result>
                  *  </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('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .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;");
                 _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('forwarded', {'xmlns':'urn:xmpp:forward:0'})
                                     .c('delay', {'xmlns':'urn:xmpp:delay', 'stamp':'2010-07-10T23:08:25Z'}).up()
@@ -624,7 +624,7 @@
 
                 await test_utils.waitUntil(() => callback.calls.count());
                 expect(callback).toHaveBeenCalled();
-                var args = callback.calls.argsFor(0);
+                const args = callback.calls.argsFor(0);
                 expect(args[0].length).toBe(2);
                 expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML);
                 expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML);
@@ -640,7 +640,7 @@
         describe("The default preference", function () {
 
             it("is set once server support for MAM has been confirmed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, [], {},
                     async function (done, _converse) {
 
@@ -654,7 +654,7 @@
                 spyOn(_converse, 'onMAMPreferences').and.callThrough();
                 _converse.message_archiving = 'never';
 
-                var feature = new Backbone.Model({
+                const feature = new Backbone.Model({
                     'var': Strophe.NS.MAM
                 });
                 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 () {
 
         it("can be sent as a correction by clicking the pencil icon",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -119,7 +119,7 @@
 
 
         it("can be sent as a correction by using the up arrow",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -276,7 +276,7 @@
 
 
         it("can be received out of order, and will still be displayed in the right order",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -461,7 +461,7 @@
         }));
 
         it("is ignored if it's a malformed headline message",
-        mock.initConverseWithPromises(
+        mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
 
@@ -497,7 +497,7 @@
 
 
         it("can be a carbon message, as defined in XEP-0280",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 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",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 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",
-        mock.initConverseWithPromises(
+        mock.initConverse(
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
 
@@ -640,7 +640,7 @@
         }));
 
         it("received for a minimized chat box will increment a counter on its header",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 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",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -797,7 +797,7 @@
         }));
 
         it("can be sent from a chatbox, and will appear inside it",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -820,7 +820,7 @@
         }));
 
         it("is sanitized to prevent Javascript injection attacks",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -841,7 +841,7 @@
         }));
 
         it("can contain hyperlinks, which will be clickable",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -864,7 +864,7 @@
         }));
 
         it("will have properly escaped URLs",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -908,7 +908,7 @@
         }));
 
         it("will render newlines",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -916,31 +916,31 @@
             _converse.emit('rosterContactsFetched');
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             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));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             const chat_content = view.el.querySelector('.chat-content');
             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));
             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?');
-            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));
             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?');
@@ -948,7 +948,7 @@
         }));
 
         it("will render images from their URLs",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -997,7 +997,7 @@
         }));
 
         it("will render the message time as configured",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1025,7 +1025,7 @@
         }));
 
         it("will be correctly identified and rendered as a followup message",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -1191,7 +1191,7 @@
         }));
 
         it("received may emit a message delivery receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
@@ -1215,7 +1215,7 @@
         }));
 
         it("carbon received does not emit a message delivery receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
@@ -1246,7 +1246,7 @@
         }));
 
         it("forwarded does not emit a message delivery receipt if it's mine",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
             test_utils.createContacts(_converse, 'current', 1);
@@ -1276,7 +1276,7 @@
         }));
 
         it("delivery can be acknowledged by a receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -1336,7 +1336,7 @@
         describe("when received from someone else", function () {
 
             it("will open a chatbox and be displayed inside it",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1382,7 +1382,7 @@
             }));
 
             it("can be replaced with a correction",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1445,7 +1445,7 @@
             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",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
 
@@ -1502,7 +1502,7 @@
             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",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
 
@@ -1562,7 +1562,7 @@
             describe("and for which then an error message is received from the server", function () {
 
                 it("will have the error message displayed after itself",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
@@ -1707,7 +1707,7 @@
                 }));
 
                 it("will not show to the user an error message for a CSI message",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1853,7 +1853,7 @@
         describe("which contains an OOB URL", function () {
 
             it("will render audio from oob mp3 URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1864,13 +1864,13 @@
                 const view = _converse.chatboxviews.get(contact_jid);
                 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 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>');
 
                 // 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
@@ -1904,7 +1904,7 @@
             }));
 
             it("will render video from oob mp4 URLs",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1915,13 +1915,13 @@
                 const view = _converse.chatboxviews.get(contact_jid);
                 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));
                 await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg video').length, 2000)
                 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>');
 
                 // 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1963,13 +1963,13 @@
                 await test_utils.openChatBoxFor(_converse, contact_jid);
                 const view = _converse.chatboxviews.get(contact_jid);
                 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1996,13 +1996,13 @@
                 spyOn(view.model, 'sendMessage').and.callThrough();
                 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));
                 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 () {
 
         it("is sent when a markable message is received",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2031,14 +2031,14 @@
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
             const msgid = u.getUniqueId();
-            const stanza = Strophe.xmlHtmlNode(`
+            const stanza = u.toStanza(`
                 <message from='${contact_jid}'
                     id='${msgid}'
                     type="chat"
                     to='${_converse.jid}'>
                   <body>My lord, dispatch; read o'er these articles.</body>
                   <markable xmlns='urn:xmpp:chat-markers:0'/>
-                </message>`).firstElementChild;
+                </message>`);
 
             const sent_stanzas = [];
             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",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2064,7 +2064,7 @@
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = await _converse.api.chatviews.get(contact_jid);
 
-            let stanza = Strophe.xmlHtmlNode(`
+            let stanza = u.toStanza(`
                 <message xmlns="jabber:client"
                          to="${_converse.bare_jid}"
                          type="chat"
@@ -2074,13 +2074,13 @@
                     <markable xmlns="urn:xmpp:chat-markers:0"/>
                     <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}"/>
-                </message>`).firstElementChild;
+                </message>`);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             expect(view.el.querySelectorAll('.chat-msg').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}">
                     <sent xmlns="urn:xmpp:carbons:2">
                         <forwarded xmlns="urn:xmpp:forward:0">
@@ -2091,7 +2091,7 @@
                             </message>
                         </forwarded>
                     </sent>
-                </message>`).firstElementChild;
+                </message>`);
             spyOn(_converse, 'emit').and.callThrough();
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
             await test_utils.waitUntil(() => _converse.emit.calls.count() === 1);
@@ -2105,7 +2105,7 @@
     describe("A Groupchat Message", function () {
 
         it("is specially marked when you are mentioned in it",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -2129,7 +2129,7 @@
 
 
         it("keeps track whether you are the sender or not",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2148,7 +2148,7 @@
         }));
 
         it("can be replaced with a correction",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2214,7 +2214,7 @@
         }));
 
         it("can be sent as a correction by using the up arrow",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2317,7 +2317,7 @@
         }));
 
         it("delivery can be acknowledged by a receipt",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
@@ -2350,7 +2350,7 @@
         describe("when received", function () {
 
             it("highlights all users mentioned via XEP-0372 references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2393,7 +2393,7 @@
         describe("in which someone is mentioned", function () {
 
             it("gets parsed for mentions which get turned into references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2454,7 +2454,7 @@
             }));
 
             it("can get corrected and given new references",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2528,7 +2528,7 @@
             }));
 
             it("includes XEP-0372 references to that person",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                         function (done, _converse) {
 

+ 4 - 4
spec/minchats.js

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

+ 150 - 153
spec/muc.js

@@ -17,7 +17,7 @@
         describe("The \"rooms\" API", function () {
 
             it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -53,7 +53,7 @@
             }));
 
             it("has a method 'get' which returns a wrapped groupchat (if it exists)",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -99,7 +99,7 @@
             }));
 
             it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -207,39 +207,39 @@
                     `<iq id="${IQ_id}" to="room@conference.example.org" type="get" xmlns="jabber:client">`+
                     `<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();
-                _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);
                 var sent_stanza = sent_IQ_els.pop();
                 while (sent_stanza.getAttribute('type') !== 'set') {
@@ -260,7 +260,7 @@
         describe("An instant groupchat", function () {
 
             it("will be created when muc_instant_rooms is set to true",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -391,7 +391,7 @@
         describe("A Groupchat", function () {
 
             it("is opened when an xmpp: URI is clicked inside another groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -420,7 +420,7 @@
             }));
 
             it("shows a notification if its not anonymous",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -478,7 +478,7 @@
 
 
             it("shows join/leave messages when users enter or exit a groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -753,7 +753,7 @@
             }));
 
             it("combines subsequent join/leave messages when users enter or exit a groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -764,99 +764,99 @@
                 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");
 
-                let presence = Strophe.xmlHtmlNode(
+                let presence = u.toStanza(
                     `<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"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/jcbrand">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="owner" jid="jc@opkode.com/converse.js-30645022" role="moderator"/>
                             <status code="110"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<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">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-39320524" role="none"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" from="coven@chat.shakespeare.lit/Dele Olajide">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<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"/>
                         <x xmlns="vcard-temp:x:update"/>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fuvuv">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fuvuv@blabber.im/Pix-Art Messenger.8zoB" role="none"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 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");
 
-                presence = Strophe.xmlHtmlNode(
+                presence = u.toStanza(
                     `<presence xmlns="jabber:client" to="dummy@localhost/resource" type="unavailable" from="coven@chat.shakespeare.lit/fabio">
                         <status>Disconnected: Replaced by new connection</status>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `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">
                         <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">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(5);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
@@ -866,46 +866,45 @@
                 // who were already in the room when we joined.
                 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">
                         <status>Disconnected: closed</status>
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="none"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(1);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `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">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" jid="deleo@traderlynk.4ng.net/converse.js-74567907" role="none"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `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">
                         <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">
                             <item affiliation="none" jid="fabio@montefuscolo.com.br/Conversations.ZvLu" role="participant"/>
                         </x>
-                    </presence>`).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect(sizzle('div.chat-info', chat_content).length).toBe(2);
                 expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe(
                     `fabio has left and re-entered the groupchat`);
-
                 done();
             }));
 
             it("role-change messages that follow a MUC leave are left out",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -936,16 +935,15 @@
                 await view.model.onMessage(msg);
                 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">
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" role="none"/>
                         </x>
-                    </presence>`
-                ).firstElementChild;
+                    </presence>`);
                 _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">
                         <c xmlns="http://jabber.org/protocol/caps" node="http://conversations.im" ver="ISg6+9AoK1/cwhbNEDviSvjdPzI=" hash="sha-1"/>
                         <x xmlns="vcard-temp:x:update">
@@ -954,8 +952,7 @@
                         <x xmlns="http://jabber.org/protocol/muc#user">
                             <item affiliation="none" role="visitor"/>
                         </x>
-                    </presence>`
-                ).firstElementChild;
+                    </presence>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
                 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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1052,14 +1049,14 @@
 
                 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
@@ -1087,14 +1084,14 @@
 
                 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));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
 
@@ -1131,7 +1128,7 @@
 
 
             it("supports the /me command",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1171,7 +1168,7 @@
             }));
 
             it("can be configured if you're its owner",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1389,7 +1386,7 @@
             }));
 
             it("shows all members even if they're not currently present in the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1443,7 +1440,7 @@
             }));
 
             it("shows users currently present in the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1497,7 +1494,7 @@
             }));
 
             it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks",
-                mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {},
+                mock.initConverse(null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
                 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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     async function (done, _converse) {
 
@@ -1591,7 +1588,7 @@
             }));
 
             it("properly handles notification that a room has been destroyed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1622,7 +1619,7 @@
             }));
 
             it("will use the user's reserved nickname, if it exists",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1719,7 +1716,7 @@
             }));
 
             it("allows the user to invite their roster contacts to enter the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -1778,7 +1775,7 @@
             }));
 
             it("can be joined automatically, based upon a received invite",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1798,10 +1795,10 @@
                 expect(_converse.chatboxes.models.length).toBe(1);
                 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);
                 expect(window.confirm).toHaveBeenCalledWith(
                     name + ' has invited you to join a groupchat: '+ room_jid +
@@ -1813,7 +1810,7 @@
             }));
 
             it("shows received groupchat messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1846,7 +1843,7 @@
             }));
 
             it("shows sent groupchat messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1931,18 +1928,18 @@
             }));
 
             it("shows the room topic in the header",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
                 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';
-                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));
                 const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
                 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(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">
                          <subject>This is a message subject</subject>
                          <body>This is a message</body>
-                     </message>`).firstChild;
+                     </message>`);
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
                 await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                 chat_content = view.el.querySelector('.chat-content');
@@ -1969,7 +1966,7 @@
             }));
 
             it("escapes the subject before rendering it, to avoid JS-injection attacks",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -1988,7 +1985,7 @@
             }));
 
             it("informs users if their nicknames has been changed.",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2094,7 +2091,7 @@
             }));
 
             it("queries for the groupchat information before attempting to join the user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -2168,7 +2165,7 @@
             }));
 
             it("updates the shown features when the groupchat configuration has changed",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'view_mode': 'fullscreen'},
                     async function (done, _converse) {
 
@@ -2212,7 +2209,7 @@
                         `iq[to="${jid}"] query[xmlns="${Strophe.NS.MUC_OWNER}"]`
                     )).pop());
 
-                const response = Strophe.xmlHtmlNode(
+                const response_el = u.toStanza(
                    `<iq xmlns="jabber:client"
                          type="result"
                          to="dummy@localhost/pda"
@@ -2277,7 +2274,6 @@
                      </x>
                      </query>
                      </iq>`);
-                const response_el = response.firstElementChild;
                 _converse.connection._dataRecv(test_utils.createRequest(response_el));
                 const el = await test_utils.waitUntil(() => document.querySelector('.chatroom-form legend'));
                 expect(el.textContent).toBe("Configuration for room@conference.example.org");
@@ -2357,7 +2353,7 @@
             }));
 
             it("indicates when a room is no longer anonymous",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2406,7 +2402,7 @@
             }));
 
             it("informs users if they have been kicked out of the groupchat",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2459,7 +2455,7 @@
 
 
             it("can be saved to, and retrieved from, browserStorage",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -2491,7 +2487,7 @@
             }));
 
             it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -2522,7 +2518,7 @@
             }));
 
             it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -2544,7 +2540,7 @@
         describe("Each chat groupchat can take special commands", function () {
 
             it("takes /help to show the available commands",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2582,7 +2578,7 @@
             }));
 
             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']},
                     async function (done, _converse) {
 
@@ -2618,7 +2614,7 @@
             }));
 
             it("takes /member to make an occupant a member",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2767,7 +2763,7 @@
             }));
 
             it("takes /topic to set the groupchat topic",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2819,7 +2815,7 @@
             }));
 
             it("takes /clear to clear messages",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2838,7 +2834,7 @@
             }));
 
             it("takes /owner to make a user an owner",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -2926,7 +2922,7 @@
             }));
 
             it("takes /ban to ban a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3006,7 +3002,7 @@
             }));
 
             it("takes /kick to kick a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3095,7 +3091,7 @@
 
 
             it("takes /op and /deop to make a user a moderator or not",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3237,7 +3233,7 @@
             }));
 
             it("takes /mute and /voice to mute and unmute a user",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3380,7 +3376,7 @@
             }));
 
             it("takes /destroy to destroy a muc",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3431,7 +3427,7 @@
         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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
                     async function (done, _converse) {
 
@@ -3442,7 +3438,7 @@
             }));
 
             it("will show an error message if the groupchat requires a password",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3502,7 +3498,7 @@
             }));
 
             it("will show an error message if the user has been banned",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     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",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3662,7 +3658,7 @@
             }));
 
             it("will show an error message if the groupchat doesn't yet exist",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3686,7 +3682,7 @@
             }));
 
             it("will show an error message if the groupchat has reached its maximum number of participants",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3713,7 +3709,7 @@
         describe("Someone being invited to a groupchat", function () {
 
             it("will first be added to the member list if the groupchat is members only",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -3879,7 +3875,7 @@
         describe("The affiliations delta", function () {
 
             it("can be computed in various ways",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
@@ -3944,7 +3940,7 @@
         describe("The \"Groupchats\" section", function () {
 
             it("contains a link to a modal through which a new chatroom can be created",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -3956,6 +3952,7 @@
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.add_room_modal;
                 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());
                 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';
@@ -3966,7 +3963,7 @@
             }));
 
             it("contains a link to a modal which can list groupchats publically available on the server",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
@@ -4028,7 +4025,7 @@
             }));
 
             it("shows the number of unread mentions received",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {'allow_bookmarks': false},
                     async function (done, _converse) {
                 // XXX: we set `allow_bookmarks` to false, so that the groupchats
@@ -4083,7 +4080,7 @@
                 describe("A composing notification", function () {
 
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
 
@@ -4239,7 +4236,7 @@
 
                 describe("A paused notification", function () {
                     it("will be shown if received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 

+ 16 - 13
spec/notification.js

@@ -14,9 +14,9 @@
                 describe("an HTML5 Notification", function () {
 
                     it("is shown when a new private message is received",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
                         // TODO: not yet testing show_desktop_notifications setting
                         test_utils.createContacts(_converse, 'current');
@@ -42,9 +42,9 @@
                     }));
 
                     it("is shown when you are mentioned in a groupchat",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
                         await test_utils.createContacts(_converse, 'current');
                         await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
@@ -83,9 +83,9 @@
                     }));
 
                     it("is shown for headline messages",
-                        mock.initConverseWithPromises(
+                        mock.initConverse(
                             null, ['rosterGroupsFetched'], {},
-                            async function (done, _converse) {
+                            async (done, _converse) => {
 
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
@@ -112,11 +112,11 @@
                         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;
                         spyOn(_converse, 'showMessageNotification').and.callThrough();
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
-                        var stanza = $msg({
+                        const stanza = $msg({
                                 'type': 'headline',
                                 'from': 'someone@notify.example.com',
                                 'to': 'dummy@localhost',
@@ -132,30 +132,33 @@
                                 'someone@notify.example.com')
                             ).toBeFalsy();
                         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
                         _converse.show_chatstate_notifications = true;
 
                         test_utils.createContacts(_converse, 'current');
                         spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
                         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'
                         expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                         expect(_converse.showChatStateNotification).toHaveBeenCalled();
+                        done()
                     }));
                 });
             });
 
             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, 'showContactRequestNotification');
                     _converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
                     expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
                     expect(_converse.showContactRequestNotification).toHaveBeenCalled();
+                    done();
                 }));
             });
         });
@@ -164,9 +167,9 @@
             describe("A notification sound", function () {
 
                 it("is played when the current user is mentioned in a groupchat",
-                    mock.initConverseWithPromises(
+                    mock.initConverse(
                         null, ['rosterGroupsFetched'], {},
-                        async function (done, _converse) {
+                        async (done, _converse) => {
 
                     test_utils.createContacts(_converse, 'current');
                     await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');

+ 12 - 12
spec/omemo.js

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

+ 6 - 5
spec/ping.js

@@ -7,7 +7,7 @@
         describe("Ping and pong handlers", function () {
 
             it("are registered when _converse.js is connected",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
 
@@ -20,7 +20,7 @@
             }));
 
             it("are registered when _converse.js reconnected",
-                mock.initConverseWithPromises(
+                mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
 
@@ -35,9 +35,9 @@
 
         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) {
                     sent_stanza = iq;
                     IQ_id = sendIQ.bind(this)(iq, callback, errback);
@@ -47,6 +47,7 @@
                     `<iq id="${IQ_id}" to="localhost" type="get" xmlns="jabber:client">`+
                         `<ping xmlns="urn:xmpp:ping"/>`+
                     `</iq>`);
+                done();
             }));
         });
     });

+ 84 - 89
spec/presence.js

@@ -3,46 +3,45 @@
 (function (root, factory) {
     define([
         "jasmine",
-        "jquery",
         "mock",
         "test-utils",
     ], factory);
-} (this, function (jasmine, $, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "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
 
     describe("A sent presence stanza", function () {
 
         it("includes a entity capabilities node",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 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(
                 `<presence xmlns="jabber:client">`+
                     `<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"/>`+
                 `</presence>`
             );
+            done();
         }));
 
         it("includes the saved status message",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
-                function (done, _converse) {
+                async (done, _converse) => {
 
             test_utils.openControlBox();
-            var view = _converse.xmppstatusview;
+            const view = _converse.xmppstatusview;
             spyOn(view.model, 'sendPresence').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()
-            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 () {
 
         it("has its priority taken into account",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
-                function (done, _converse) {
+                (done, _converse) => {
 
             test_utils.openControlBox();
             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 = _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.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('show')).toBe('online');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-0-resource">'+
@@ -156,7 +151,7 @@
             '       node="http://www.igniterealtime.org/projects/smack/"/>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T17:02:24Z" from="'+contact_jid+'/priority-0-resource"/>'+
             '</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.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('show')).toBe('online');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '    <priority>2</priority>'+
             '    <show>dnd</show>'+
             '</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.resources.length).toBe(3);
             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('show')).toBe('dnd');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '    <priority>3</priority>'+
             '    <show>away</show>'+
             '</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(contact.presence.resources.length).toBe(4);
             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('show')).toBe('away');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
@@ -209,7 +204,7 @@
             '    <show>dnd</show>'+
             '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T15:02:24Z" from="'+contact_jid+'/older-priority-1-resource"/>'+
             '</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(contact.presence.resources.length).toBe(5);
             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('show')).toBe('away');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-3-resource">'+
             '</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(contact.presence.resources.length).toBe(4);
             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('show')).toBe('dnd');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-2-resource">'+
             '</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(contact.presence.resources.length).toBe(3);
             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('show')).toBe('dnd');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-1-resource">'+
             '</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(contact.presence.resources.length).toBe(2);
             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('show')).toBe('dnd');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/older-priority-1-resource">'+
             '</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(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('show')).toBe('xa');
 
-            stanza = $(
+            stanza = u.toStanza(
             '<presence xmlns="jabber:client"'+
             '          to="dummy@localhost/converse.js-21770972"'+
             '          type="unavailable"'+
             '          from="'+contact_jid+'/priority-0-resource">'+
             '</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(contact.presence.resources.length).toBe(0);
             done();

+ 2 - 2
spec/profiling.js

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

+ 4 - 4
spec/protocol.js

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

+ 4 - 4
spec/push.js

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

+ 6 - 6
spec/register.js

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

+ 2 - 2
spec/room_registration.js

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

+ 9 - 8
spec/roomslist.js

@@ -7,7 +7,7 @@
 
     describe("A list of open groupchats", function () {
 
-        it("is shown in controlbox", mock.initConverseWithPromises(
+        it("is shown in controlbox", mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'],
                 { allow_bookmarks: false // Makes testing easier, otherwise we
                                         // have to mock stanza traffic.
@@ -47,7 +47,7 @@
         ));
 
         it("uses bookmarks to determine groupchat names",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 ['send'], ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
                 async function (done, _converse) {
 
@@ -113,7 +113,7 @@
 
     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'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we
@@ -142,7 +142,7 @@
             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'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we
@@ -249,7 +249,7 @@
             done();
         }));
 
-        it("can be closed", mock.initConverseWithPromises(
+        it("can be closed", mock.initConverse(
             null, ['rosterGroupsFetched'],
             { whitelisted_plugins: ['converse-roomslist'],
               allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
@@ -272,10 +272,11 @@
             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.
-            }, async function (done, _converse) {
+                }, async (done, _converse) => {
 
             test_utils.openControlBox();
             const room_jid = 'kitchen@conference.shakespeare.lit';

+ 44 - 45
spec/roster.js

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

+ 8 - 8
spec/spoilers.js

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

+ 1 - 1
spec/transcripts.js

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

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

@@ -6,16 +6,16 @@
         ], factory);
 } (this, function (jasmine, mock, test_utils) {
     "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 () {
 
         it("can be used to remove a contact",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
@@ -49,7 +49,7 @@
         }));
 
         it("shows an alert when an error happened while removing the contact",
-            mock.initConverseWithPromises(
+            mock.initConverse(
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 

+ 12 - 11
spec/xmppstatus.js

@@ -1,21 +1,22 @@
 (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'});
             spyOn(_converse.connection, 'send');
             _converse.api.user.status.message.set("I'm also happy!");
             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 : {};
     const init_promise = u.getResolveablePromise();
     _.each(PROMISES, addPromise);
@@ -1212,21 +1212,18 @@ _converse.initialize = function (settings, callback) {
         this.connection = settings.connection;
     }
 
-    if (!_.isUndefined(_converse.connection) &&
-            _converse.connection.service === 'jasmine tests') {
+    if (_.get(_converse.connection, 'service') === 'jasmine tests') {
         finishInitialization();
         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;
 };
 

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

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

+ 28 - 48
tests/mock.js

@@ -1,12 +1,12 @@
 (function (root, factory) {
     define("mock", [], factory);
 }(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 = {
         'SignalProtocolAddress': function (name, device_id) {
@@ -19,7 +19,7 @@
             this.encrypt = () => Promise.resolve({
                 'type': 1,
                 'body': 'c1ph3R73X7',
-                'registrationId': '1337' 
+                'registrationId': '1337'
             });
             this.decryptPreKeyWhisperMessage = (key_and_tag) => {
                 return Promise.resolve(key_and_tag);
@@ -66,7 +66,7 @@
         }
     };
 
-    var mock = {};
+    const mock = {};
     mock.view_mode = 'overlayed';
 
     // 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.sessionStorage.clear();
         const el = document.querySelector('#conversejs');
@@ -173,7 +173,7 @@
             });
         }
 
-        const _converse = converse.initialize(_.extend({
+        const _converse = await converse.initialize(_.extend({
             'i18n': 'en',
             'auto_subscribe': false,
             'play_sounds': false,
@@ -196,19 +196,19 @@
                 } else if (!model.get('vcard_updated') || force) {
                     jid = model.get('jid') || model.get('muc_jid');
                 }
-                var fullname;
+                let fullname;
                 if (!jid || jid == 'dummy@localhost') {
                     jid = 'dummy@localhost';
                     fullname = 'Max Mustermann' ;
                 } 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[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
                     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,
                     'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
                     'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
@@ -230,41 +230,21 @@
         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;
 }));