Browse Source

MUC: Fix error message logging

JC Brand 4 years ago
parent
commit
ea6e370347
14 changed files with 213 additions and 537 deletions
  1. 8 11
      spec/chatbox.js
  2. 6 18
      spec/corrections.js
  3. 5 12
      spec/markers.js
  4. 2 6
      spec/me-messages.js
  5. 9 27
      spec/mentions.js
  6. 43 74
      spec/messages.js
  7. 2 4
      spec/muc-mentions.js
  8. 90 269
      spec/muc.js
  9. 14 42
      spec/muc_messages.js
  10. 5 7
      spec/rai.js
  11. 4 4
      spec/receipts.js
  12. 15 55
      spec/retractions.js
  13. 6 6
      spec/styling.js
  14. 4 2
      src/headless/plugins/muc/muc.js

+ 8 - 11
spec/chatbox.js

@@ -139,13 +139,14 @@ describe("Chatboxes", function () {
         }));
 
         it("is focused if its already open and you click on its corresponding roster item",
-                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'auto_focus': true}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
             await mock.openControlBox(_converse);
             expect(_converse.chatboxes.length).toEqual(1);
 
             const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
+            spyOn(_converse.ChatBoxView.prototype, 'focus').and.callThrough();
             const view = await mock.openChatBoxFor(_converse, contact_jid);
             const rosterview = document.querySelector('converse-roster');
             const el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', rosterview.el).pop();
@@ -153,11 +154,8 @@ describe("Chatboxes", function () {
             const textarea = view.querySelector('.chat-textarea');
             await u.waitUntil(() => u.isVisible(textarea));
             textarea.blur();
-            spyOn(view.model, 'maybeShow').and.callThrough();
-            spyOn(view, 'focus').and.callThrough();
             el.click();
-            await u.waitUntil(() => view.model.maybeShow.calls.count(), 1000);
-            expect(view.model.maybeShow).toHaveBeenCalled();
+            await u.waitUntil(() => view.focus.calls.count(), 1000);
             expect(view.focus).toHaveBeenCalled();
             expect(_converse.chatboxes.length).toEqual(2);
             done();
@@ -219,16 +217,15 @@ describe("Chatboxes", function () {
         it("will be removed from browserStorage when closed",
                 mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
-            spyOn(_converse.minimize, 'trimChats');
             await mock.waitForRoster(_converse, 'current');
             await mock.openControlBox(_converse);
+            spyOn(_converse.minimize, 'trimChats');
             const rosterview = document.querySelector('converse-roster');
             await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length);
             spyOn(_converse.api, "trigger").and.callThrough();
-
+            const promise = new Promise(resolve => _converse.api.listen.once('controlBoxClosed', resolve));
             mock.closeControlBox();
-            await new Promise(resolve => _converse.api.listen.once('chatBoxClosed', resolve));
-            expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
+            await promise;
             expect(_converse.chatboxes.length).toEqual(1);
             expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
             mock.openChatBoxes(_converse, 6);
@@ -1056,9 +1053,9 @@ describe("Chatboxes", function () {
             await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 1);
             expect(sent_stanzas[0].querySelector('received')).toBeDefined();
             _converse.saveWindowState({'type': 'focus'});
-            expect(chatbox.get('num_unread')).toBe(0);
             await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 2);
             expect(sent_stanzas[1].querySelector('displayed')).toBeDefined();
+            expect(chatbox.get('num_unread')).toBe(0);
             done();
         }));
 
@@ -1191,7 +1188,7 @@ describe("Chatboxes", function () {
             expect(select_msgs_indicator().textContent).toBe('1');
             view.viewUnreadMessages();
             rosterview.render();
-            expect(select_msgs_indicator()).toBeUndefined();
+            await u.waitUntil(() => select_msgs_indicator() === undefined);
             done();
         }));
 

+ 6 - 18
spec/corrections.js

@@ -6,9 +6,7 @@ const u = converse.env.utils;
 describe("A Chat Message", function () {
 
     it("can be sent as a correction by using the up arrow",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
         await mock.openControlBox(_converse);
@@ -164,9 +162,7 @@ describe("A Chat Message", function () {
 
 
     it("can be sent as a correction by clicking the pencil icon",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
         await mock.openControlBox(_converse);
@@ -291,9 +287,7 @@ describe("A Chat Message", function () {
     describe("when received from someone else", function () {
 
         it("can be replaced with a correction",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1);
             await mock.openControlBox(_converse);
@@ -356,9 +350,7 @@ describe("A Chat Message", function () {
 describe("A Groupchat Message", function () {
 
     it("can be replaced with a correction",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -425,9 +417,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("keeps the same position in history after a correction",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -521,9 +511,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("can be sent as a correction by using the up arrow",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');

+ 5 - 12
spec/markers.js

@@ -8,9 +8,7 @@ const u = converse.env.utils;
 describe("A XEP-0333 Chat Marker", function () {
 
     it("is sent when a markable message is received from a roster contact",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@@ -39,9 +37,7 @@ describe("A XEP-0333 Chat Marker", function () {
     }));
 
     it("is not sent when a markable message is received from someone not on the roster",
-        mock.initConverse(
-            ['rosterContactsFetched'], {'allow_non_roster_messaging': true},
-            async function (done, _converse) {
+            mock.initConverse([], {'allow_non_roster_messaging': true}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 0);
         const contact_jid = 'someone@montague.lit';
@@ -74,9 +70,7 @@ describe("A XEP-0333 Chat Marker", function () {
     }));
 
     it("is ignored if it's a carbon copy of one that I sent from a different client",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+        mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
         await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
@@ -123,9 +117,7 @@ describe("A XEP-0333 Chat Marker", function () {
 
 
     it("may be returned for a MUC message",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         const muc_jid = 'lounge@montague.lit';
@@ -176,6 +168,7 @@ describe("A XEP-0333 Chat Marker", function () {
             <message xml:lang="en" to="romeo@montague.lit/orchard"
                      from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
                 <body>'tis I!</body>
+                <stanza-id xmlns='urn:xmpp:sid:0' id='stanza-id-1' by='${muc_jid}'/>
                 <markable xmlns="urn:xmpp:chat-markers:0"/>
             </message>`);
         _converse.connection._dataRecv(mock.createRequest(stanza));

+ 2 - 6
spec/me-messages.js

@@ -4,11 +4,7 @@ const { u, sizzle, $msg } = converse.env;
 
 describe("A Groupchat Message", function () {
 
-    it("supports the /me command",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
-
+    it("supports the /me command", mock.initConverse([], {}, async function (done, _converse) {
         await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
         await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
         await mock.waitForRoster(_converse, 'current');
@@ -61,7 +57,7 @@ describe("A Groupchat Message", function () {
 
 describe("A Message", function () {
 
-    it("supports the /me command", mock.initConverse(['rosterContactsFetched'], {}, async function (done, _converse) {
+    it("supports the /me command", mock.initConverse([], {}, async function (done, _converse) {
         await mock.waitForRoster(_converse, 'current');
         await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
         await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));

+ 9 - 27
spec/mentions.js

@@ -7,9 +7,7 @@ const u = converse.env.utils;
 describe("An incoming groupchat message", function () {
 
     it("is specially marked when you are mentioned in it",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -31,9 +29,7 @@ describe("An incoming groupchat message", function () {
 
 
     it("highlights all users mentioned via XEP-0372 references",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@@ -87,9 +83,7 @@ describe("An incoming groupchat message", function () {
     }));
 
     it("highlights all users mentioned via XEP-0372 references in a quoted message",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@@ -133,9 +127,7 @@ describe("A sent groupchat message", function () {
     describe("in which someone is mentioned", function () {
 
         it("gets parsed for mentions which get turned into references",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
 
@@ -265,9 +257,7 @@ describe("A sent groupchat message", function () {
         }));
 
         it("gets parsed for mentions as indicated with an @ preceded by a space or at the start of the text",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@@ -299,9 +289,7 @@ describe("A sent groupchat message", function () {
         }));
 
         it("properly encodes the URIs in sent out references",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@@ -343,9 +331,7 @@ describe("A sent groupchat message", function () {
         }));
 
         it("can get corrected and given new references",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
 
@@ -442,9 +428,7 @@ describe("A sent groupchat message", function () {
         }));
 
         it("includes a XEP-0372 references to that person",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -493,9 +477,7 @@ describe("A sent groupchat message", function () {
     });
 
     it("highlights all users mentioned via XEP-0372 references in a quoted message",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const members = [{'jid': 'gibson@gibson.net', 'nick': 'gibson', 'affiliation': 'member'}];
         const muc_jid = 'lounge@montague.lit';

+ 43 - 74
spec/messages.js

@@ -7,7 +7,7 @@ const u = converse.env.utils;
 describe("A Chat Message", function () {
 
     it("will be demarcated if it's the first newly received message",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
@@ -35,7 +35,7 @@ describe("A Chat Message", function () {
 
     it("is rejected if it's an unencapsulated forwarded message",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 2);
@@ -79,15 +79,14 @@ describe("A Chat Message", function () {
     }));
 
     it("can be received out of order, and will still be displayed in the right order",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
 
         const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
-        await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length)
+        const rosterview = document.querySelector('converse-roster');
+        await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length)
         _converse.filter_by_resource = true;
 
         let msg = $msg({
@@ -244,9 +243,7 @@ describe("A Chat Message", function () {
     }));
 
     it("is ignored if it's a malformed headline message",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
@@ -273,9 +270,7 @@ describe("A Chat Message", function () {
 
 
     it("can be a carbon message, as defined in XEP-0280",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const include_nick = false;
         await mock.waitForRoster(_converse, 'current', 2, include_nick);
@@ -324,9 +319,7 @@ describe("A Chat Message", function () {
     }));
 
     it("can be a carbon message that this user sent from a different client, as defined in XEP-0280",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
         await mock.waitForRoster(_converse, 'current');
@@ -371,9 +364,7 @@ describe("A Chat Message", function () {
     }));
 
     it("will be discarded if it's a malicious message meant to look like a carbon copy",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
@@ -417,9 +408,7 @@ describe("A Chat Message", function () {
     }));
 
     it("will indicate when it has a time difference of more than a day between it and its predecessor",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         const include_nick = false;
         await mock.waitForRoster(_converse, 'current', 2, include_nick);
@@ -428,7 +417,8 @@ describe("A Chat Message", function () {
         const contact_name = mock.cur_names[1];
         const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
 
-        await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length);
+        const rosterview = document.querySelector('converse-roster');
+        await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length);
         await mock.openChatBoxFor(_converse, contact_jid);
 
         const one_day_ago = dayjs().subtract(1, 'day');
@@ -509,9 +499,7 @@ describe("A Chat Message", function () {
     }));
 
     it("is sanitized to prevent Javascript injection attacks",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
@@ -529,9 +517,7 @@ describe("A Chat Message", function () {
     }));
 
     it("can contain hyperlinks, which will be clickable",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
@@ -551,9 +537,7 @@ describe("A Chat Message", function () {
     }));
 
     it("will remove url query parameters from hyperlinks as set",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'],
-            {'filter_url_query_params': ['utm_medium', 'utm_content', 's']},
+            mock.initConverse(['chatBoxesFetched'], {'filter_url_query_params': ['utm_medium', 'utm_content', 's']},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -582,11 +566,7 @@ describe("A Chat Message", function () {
         done();
     }));
 
-    it("will render newlines",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
-
+    it("will render newlines", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
         await mock.waitForRoster(_converse, 'current');
         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
         const view = await mock.openChatBoxFor(_converse, contact_jid);
@@ -633,11 +613,7 @@ describe("A Chat Message", function () {
         done();
     }));
 
-    it("will render images from their URLs",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
-
+    it("will render images from their URLs", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
         await mock.waitForRoster(_converse, 'current');
         const base_url = 'https://conversejs.org';
         let message = base_url+"/logo/conversejs-filled.svg";
@@ -687,7 +663,7 @@ describe("A Chat Message", function () {
 
     it("will render images from approved URLs only",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {'show_images_inline': ['conversejs.org']},
+            ['chatBoxesFetched'], {'show_images_inline': ['conversejs.org']},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -711,7 +687,7 @@ describe("A Chat Message", function () {
 
     it("will fall back to rendering images as URLs",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -755,7 +731,7 @@ describe("A Chat Message", function () {
 
     it("will render the message time as configured",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -781,7 +757,7 @@ describe("A Chat Message", function () {
 
     it("will be correctly identified and rendered as a followup message",
         mock.initConverse(
-            ['rosterContactsFetched'], {'debounced_content_rendering': false},
+            [], {'debounced_content_rendering': false},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -790,7 +766,8 @@ describe("A Chat Message", function () {
         const base_time = new Date();
         const ONE_MINUTE_LATER = 60000;
 
-        await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300);
+        const rosterview = document.querySelector('converse-roster');
+        await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
         const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
         _converse.filter_by_resource = true;
 
@@ -943,7 +920,7 @@ describe("A Chat Message", function () {
 
         it("will appear inside the chatbox it was sent from",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
@@ -965,7 +942,7 @@ describe("A Chat Message", function () {
 
         it("will be trimmed of leading and trailing whitespace",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1);
@@ -985,14 +962,13 @@ describe("A Chat Message", function () {
     describe("when received from someone else", function () {
 
         it("will open a chatbox and be displayed inside it",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const include_nick = false;
             await mock.waitForRoster(_converse, 'current', 1, include_nick);
             await mock.openControlBox(_converse);
-            await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300);
+            const rosterview = document.querySelector('converse-roster');
+            await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
             spyOn(_converse.api, "trigger").and.callThrough();
             const message = 'This is a received message';
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@@ -1031,12 +1007,11 @@ describe("A Chat Message", function () {
         }));
 
         it("will be trimmed of leading and trailing whitespace",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1, false);
-            await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300);
+            const rosterview = document.querySelector('converse-roster');
+            await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
             const message = '\n\n        This is a received message         \n\n';
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
             await _converse.handleMessageStanza(
@@ -1062,8 +1037,7 @@ describe("A Chat Message", function () {
         describe("when a chatbox is opened for someone who is not in the roster", function () {
 
             it("the VCard for that user is fetched and the chatbox updated with the results",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {'allow_non_roster_messaging': true},
+                mock.initConverse([], {'allow_non_roster_messaging': true},
                     async function (done, _converse) {
 
                 await mock.waitForRoster(_converse, 'current', 0);
@@ -1117,7 +1091,7 @@ describe("A Chat Message", function () {
 
             it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
                 mock.initConverse(
-                    ['rosterContactsFetched'], {'allow_non_roster_messaging': false},
+                    [], {'allow_non_roster_messaging': false},
                     async function (done, _converse) {
 
                 await mock.waitForRoster(_converse, 'current', 0);
@@ -1172,9 +1146,7 @@ describe("A Chat Message", function () {
         describe("and for which then an error message is received from the server", function () {
 
             it("will have the error message displayed after itself",
-                mock.initConverse(
-                    ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                    async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
                 await mock.waitForRoster(_converse, 'current', 1);
 
@@ -1298,7 +1270,7 @@ describe("A Chat Message", function () {
 
             it("will not show to the user an error message for a CSI message",
                 mock.initConverse(
-                    ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                    ['chatBoxesFetched'], {},
                     async function (done, _converse) {
 
                 // See #1317
@@ -1338,9 +1310,7 @@ describe("A Chat Message", function () {
 
 
         it("will cause the chat area to be scrolled down only if it was at the bottom originally",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@@ -1375,12 +1345,11 @@ describe("A Chat Message", function () {
         }));
 
         it("is ignored if it's intended for a different resource and filter_by_resource is set to true",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
-            await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length)
+            const rosterview = document.querySelector('converse-roster');
+            await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length)
             // Send a message from a different resource
             spyOn(converse.env.log, 'error');
             spyOn(_converse.api.chatboxes, 'create').and.callThrough();
@@ -1426,7 +1395,7 @@ describe("A Chat Message", function () {
 
         it("will render audio from oob mp3 URLs",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1);
@@ -1476,7 +1445,7 @@ describe("A Chat Message", function () {
 
         it("will render video from oob mp4 URLs",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1);
@@ -1522,7 +1491,7 @@ describe("A Chat Message", function () {
 
         it("will render download links for files from oob URLs",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 1);
@@ -1551,7 +1520,7 @@ describe("A Chat Message", function () {
 
         it("will render images from oob URLs",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             const base_url = 'https://conversejs.org';

+ 2 - 4
spec/muc-mentions.js

@@ -8,8 +8,7 @@ const u = converse.env.utils;
 describe("MUC Mention Notfications", function () {
 
     it("may be received from a MUC in which the user is not currently present",
-        mock.initConverse(
-            ['rosterContactsFetched'], {
+        mock.initConverse([], {
                 'allow_bookmarks': false, // Hack to get the rooms list to render
                 'muc_subscribe_to_rai': true,
                 'view_mode': 'fullscreen'},
@@ -31,8 +30,7 @@ describe("MUC Mention Notfications", function () {
         expect(view.model.get('hidden')).toBe(true);
         await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
 
-        const lview = _converse.rooms_list_view
-        const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
+        const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
         expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
 
         const base_time = new Date();

+ 90 - 269
spec/muc.js

@@ -13,10 +13,8 @@ describe("Groupchats", function () {
 
     describe("The \"rooms\" API", function () {
 
-        it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+        fit("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
 
@@ -25,14 +23,15 @@ describe("Groupchats", function () {
 
             _converse.connection.IQ_stanzas = [];
             await mock.openAndEnterChatRoom(_converse, 'news@montague.lit', 'romeo');
-            expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit').el)).toBeTruthy();
-            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
-            expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy();
+
+            expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
 
             await _converse.api.roomviews.close('lounge@montague.lit');
             expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
-            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
-            expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
 
             await _converse.api.roomviews.close(['leisure@montague.lit', 'news@montague.lit']);
             expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
@@ -40,8 +39,8 @@ describe("Groupchats", function () {
             expect(_converse.chatboxviews.get('news@montague.lit')).toBeUndefined();
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             await mock.openAndEnterChatRoom(_converse, 'leisure@montague.lit', 'romeo');
-            expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit').el)).toBeTruthy();
-            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
+            expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
             await _converse.api.roomviews.close();
             expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
             expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
@@ -49,9 +48,7 @@ describe("Groupchats", function () {
         }));
 
         it("has a method 'get' which returns a wrapped groupchat (if it exists)",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
             await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group .group-toggle').length, 300);
@@ -95,9 +92,7 @@ describe("Groupchats", function () {
         }));
 
         it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             // Mock 'getDiscoInfo', otherwise the room won't be
             // displayed as it waits first for the features to be returned
@@ -265,9 +260,7 @@ describe("Groupchats", function () {
     describe("An instant groupchat", function () {
 
         it("will be created when muc_instant_rooms is set to true",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             let IQ_stanzas = _converse.connection.IQ_stanzas;
             const muc_jid = 'lounge@montague.lit';
@@ -402,8 +395,7 @@ describe("Groupchats", function () {
 
 
         it("maintains its state across reloads",
-            mock.initConverse(
-                ['rosterContactsFetched'], {
+            mock.initConverse([], {
                     'clear_messages_on_reconnection': true,
                     'enable_smacks': false
                 }, async function (done, _converse) {
@@ -510,9 +502,7 @@ describe("Groupchats", function () {
         describe("upon being entered", function () {
 
             it("will fetch the member list if muc_fetch_members is true",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {'muc_fetch_members': true},
-                    async function (done, _converse) {
+                    mock.initConverse([], {'muc_fetch_members': true}, async function (done, _converse) {
 
                 let sent_IQs = _converse.connection.IQ_stanzas;
                 const muc_jid = 'lounge@montague.lit';
@@ -571,9 +561,7 @@ describe("Groupchats", function () {
             describe("when fetching the member lists", function () {
 
                 it("gracefully handles being forbidden from fetching the lists for certain affiliations",
-                    mock.initConverse(
-                        ['rosterContactsFetched'], {'muc_fetch_members': true},
-                        async function (done, _converse) {
+                        mock.initConverse([], {'muc_fetch_members': true}, async function (done, _converse) {
 
                     const sent_IQs = _converse.connection.IQ_stanzas;
                     const muc_jid = 'lounge@montague.lit';
@@ -653,11 +641,7 @@ describe("Groupchats", function () {
 
         describe("topic", function () {
 
-            it("is shown the header",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
-
+            it("is shown the header", mock.initConverse([], {}, async function (done, _converse) {
                 await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
                 const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
                 let stanza = u.toStanza(`
@@ -687,11 +671,7 @@ describe("Groupchats", function () {
                 done();
             }));
 
-            it("can be toggled by the user",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
-
+            it("can be toggled by the user", mock.initConverse([], {}, async function (done, _converse) {
                 await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
                 const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
                 let stanza = u.toStanza(`
@@ -729,11 +709,7 @@ describe("Groupchats", function () {
                 done();
             }));
 
-            it("will always be shown when it's new",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
-
+            it("will always be shown when it's new", mock.initConverse([], {}, async function (done, _converse) {
                 await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
                 const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
                 let stanza = u.toStanza(`
@@ -768,11 +744,7 @@ describe("Groupchats", function () {
             }));
 
 
-            it("causes an info message to be shown when received in real-time",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
-
+            it("causes an info message to be shown when received in real-time", mock.initConverse([], {}, async function (done, _converse) {
                 spyOn(_converse.ChatRoom.prototype, 'handleSubjectChange').and.callThrough();
                 await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'romeo');
                 const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
@@ -832,9 +804,7 @@ describe("Groupchats", function () {
         });
 
         it("restores cached messages when it reconnects and clear_messages_on_reconnection and muc_clear_messages_on_leave are false",
-            mock.initConverse(
-                ['rosterContactsFetched'],
-                {
+            mock.initConverse([], {
                     'clear_messages_on_reconnection': false,
                     'muc_clear_messages_on_leave': false
                 },
@@ -865,9 +835,7 @@ describe("Groupchats", function () {
 
 
         it("clears cached messages when it reconnects and clear_messages_on_reconnection is true",
-            mock.initConverse(
-                ['rosterContactsFetched'], {'clear_messages_on_reconnection': true},
-                async function (done, _converse) {
+                mock.initConverse([], {'clear_messages_on_reconnection': true}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid , 'romeo');
@@ -892,9 +860,7 @@ describe("Groupchats", function () {
         }));
 
         it("is opened when an xmpp: URI is clicked inside another groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current');
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@@ -921,9 +887,7 @@ describe("Groupchats", function () {
         }));
 
         it("shows a notification if it's not anonymous",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'coven@chat.shakespeare.lit';
             const nick = 'romeo';
@@ -968,9 +932,7 @@ describe("Groupchats", function () {
 
 
         it("shows join/leave messages when users enter or exit a groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'muc_fetch_members': false},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'muc_fetch_members': false}, async function (done, _converse) {
 
             const muc_jid = 'coven@chat.shakespeare.lit';
             const nick = 'some1';
@@ -1240,9 +1202,7 @@ describe("Groupchats", function () {
         }));
 
         it("combines subsequent join/leave messages when users enter or exit a groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo')
             const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
@@ -1378,9 +1338,7 @@ describe("Groupchats", function () {
         }));
 
         it("doesn't show the disconnection messages when join_leave_events is not in muc_show_info_messages setting",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'muc_show_info_messages': []},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'muc_show_info_messages': []}, async function (done, _converse) {
 
             spyOn(_converse.ChatRoom.prototype, 'onOccupantAdded').and.callThrough();
             spyOn(_converse.ChatRoom.prototype, 'onOccupantRemoved').and.callThrough();
@@ -1419,9 +1377,7 @@ describe("Groupchats", function () {
         }));
 
         it("role-change messages that follow a MUC leave are left out",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             // See https://github.com/conversejs/converse.js/issues/1259
 
@@ -1475,11 +1431,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("can be configured if you're its owner",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
-
+        it("can be configured if you're its owner", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             let sent_IQ, IQ_id;
             const sendIQ = _converse.connection.sendIQ;
             spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@@ -1687,12 +1639,9 @@ describe("Groupchats", function () {
         }));
 
         it("shows all members even if they're not currently present in the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit'
-
             const members = [{
                 'nick': 'juliet',
                 'jid': 'juliet@capulet.lit',
@@ -1770,9 +1719,7 @@ describe("Groupchats", function () {
         }));
 
         it("shows users currently present in the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             var view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -1824,9 +1771,7 @@ describe("Groupchats", function () {
         }));
 
         it("indicates moderators and visitors by means of a special css class and tooltip",
-            mock.initConverse(
-                ['rosterContactsFetched'], {'view_mode': 'fullscreen'},
-                async function (done, _converse) {
+                mock.initConverse([], {'view_mode': 'fullscreen'}, async function (done, _converse) {
 
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -1890,9 +1835,7 @@ describe("Groupchats", function () {
         }));
 
         it("properly handles notification that a room has been destroyed",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.openChatRoomViaModal(_converse, 'problematic@muc.montague.lit', 'romeo')
             const presence = $pres().attrs({
@@ -1920,9 +1863,7 @@ describe("Groupchats", function () {
         }));
 
         it("will use the user's reserved nickname, if it exists",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const IQ_stanzas = _converse.connection.IQ_stanzas;
             const muc_jid = 'lounge@montague.lit';
@@ -2013,9 +1954,7 @@ describe("Groupchats", function () {
         }));
 
         it("allows the user to invite their roster contacts to enter the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'view_mode': 'fullscreen'}, async function (done, _converse) {
 
             // We need roster contacts, so that we have someone to invite
             await mock.waitForRoster(_converse, 'current');
@@ -2092,9 +2031,7 @@ describe("Groupchats", function () {
         }));
 
         it("can be joined automatically, based upon a received invite",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current'); // We need roster contacts, who can invite us
             const name = mock.cur_names[0];
@@ -2128,9 +2065,7 @@ describe("Groupchats", function () {
         }));
 
         it("shows received groupchat messages",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const text = 'This is a received message';
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@@ -2159,11 +2094,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("shows sent groupchat messages",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("shows sent groupchat messages", mock.initConverse([], {}, async function (done, _converse) {
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             spyOn(_converse.api, "trigger").and.callThrough();
             const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -2206,9 +2137,7 @@ describe("Groupchats", function () {
         }));
 
         it("will cause the chat area to be scrolled down only if it was at the bottom already",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const message = 'This message is received while the chat area is scrolled up';
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@@ -2248,9 +2177,7 @@ describe("Groupchats", function () {
         }));
 
         it("reconnects when no-acceptable error is returned when sending a message",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'coven@chat.shakespeare.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -2303,9 +2230,7 @@ describe("Groupchats", function () {
 
 
         it("informs users if the room configuration has changed",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'coven@chat.shakespeare.lit';
             await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo');
@@ -2330,9 +2255,7 @@ describe("Groupchats", function () {
 
 
         it("informs users if their nicknames have been changed.",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             /* The service then sends two presence stanzas to the full JID
              * of each occupant (including the occupant who is changing his
@@ -2435,9 +2358,7 @@ describe("Groupchats", function () {
         }));
 
         it("queries for the groupchat information before attempting to join the user",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const nick = "some1";
             const IQ_stanzas = _converse.connection.IQ_stanzas;
@@ -2511,9 +2432,7 @@ describe("Groupchats", function () {
         }));
 
         it("updates the shown features when the groupchat configuration has changed",
-            mock.initConverse(
-                ['rosterContactsFetched'], {'view_mode': 'fullscreen'},
-                async function (done, _converse) {
+                mock.initConverse([], {'view_mode': 'fullscreen'}, async function (done, _converse) {
 
             let features = [
                 'http://jabber.org/protocol/muc',
@@ -2717,9 +2636,7 @@ describe("Groupchats", function () {
         }));
 
         it("indicates when a room is no longer anonymous",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             let IQ_id;
             const sendIQ = _converse.connection.sendIQ;
@@ -2766,9 +2683,7 @@ describe("Groupchats", function () {
         }));
 
         it("informs users if they have been kicked out of the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             /*  <presence
              *      from='harfleur@chat.shakespeare.lit/pistol'
@@ -2823,9 +2738,7 @@ describe("Groupchats", function () {
         }));
 
         it("informs users if they have exited the groupchat due to a technical reason",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             /*  <presence
              *      from='harfleur@chat.shakespeare.lit/pistol'
@@ -2875,9 +2788,7 @@ describe("Groupchats", function () {
 
 
         it("can be saved to, and retrieved from, browserStorage",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
             // We instantiate a new ChatBoxes collection, which by default
@@ -2909,9 +2820,7 @@ describe("Groupchats", function () {
         }));
 
         it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
             const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -2930,9 +2839,7 @@ describe("Groupchats", function () {
         }));
 
         it("informs users of role and affiliation changes",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -3001,9 +2908,7 @@ describe("Groupchats", function () {
         }));
 
         it("notifies users of role and affiliation changes for members not currently in the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -3048,9 +2953,7 @@ describe("Groupchats", function () {
     describe("Each chat groupchat can take special commands", function () {
 
         it("takes /help to show the available commands",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             spyOn(window, 'confirm').and.callFake(() => true);
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@@ -3147,9 +3050,7 @@ describe("Groupchats", function () {
         }));
 
         it("takes /help to show the available commands and commands can be disabled by config",
-            mock.initConverse(
-                ['rosterContactsFetched'], {muc_disable_slash_commands: ['mute', 'voice']},
-                async function (done, _converse) {
+                mock.initConverse([], {muc_disable_slash_commands: ['mute', 'voice']}, async function (done, _converse) {
 
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -3185,9 +3086,7 @@ describe("Groupchats", function () {
         }));
 
         it("takes /member to make an occupant a member",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             let iq_stanza;
             await mock.openAndEnterChatRoom(_converse, 'lounge@muc.montague.lit', 'romeo');
@@ -3329,11 +3228,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("takes /topic to set the groupchat topic",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("takes /topic to set the groupchat topic", mock.initConverse([], {}, async function (done, _converse) {
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             const view = _converse.chatboxviews.get('lounge@montague.lit');
             spyOn(view, 'clearMessages');
@@ -3393,11 +3288,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("takes /clear to clear messages",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("takes /clear to clear messages", mock.initConverse([], {}, async function (done, _converse) {
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
             const view = _converse.chatboxviews.get('lounge@montague.lit');
             spyOn(view, 'clearMessages');
@@ -3412,11 +3303,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("takes /owner to make a user an owner",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("takes /owner to make a user an owner", mock.initConverse([], {}, async function (done, _converse) {
             let sent_IQ, IQ_id;
             const sendIQ = _converse.connection.sendIQ;
             spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@@ -3504,11 +3391,7 @@ describe("Groupchats", function () {
             done();
         }));
 
-        it("takes /ban to ban a user",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("takes /ban to ban a user", mock.initConverse([], {}, async function (done, _converse) {
             let sent_IQ, IQ_id;
             const sendIQ = _converse.connection.sendIQ;
             spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@@ -3604,11 +3487,7 @@ describe("Groupchats", function () {
         }));
 
 
-        it("takes a /kick command to kick a user",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("takes a /kick command to kick a user", mock.initConverse([], {}, async function (done, _converse) {
             let sent_IQ, IQ_id;
             const sendIQ = _converse.connection.sendIQ;
             spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@@ -3697,9 +3576,7 @@ describe("Groupchats", function () {
 
 
         it("takes /op and /deop to make a user a moderator or not",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -3838,9 +3715,7 @@ describe("Groupchats", function () {
         }));
 
         it("takes /mute and /voice to mute and unmute a user",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -3976,9 +3851,7 @@ describe("Groupchats", function () {
         }));
 
         it("takes /destroy to destroy a muc",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const new_muc_jid = 'foyer@montague.lit';
@@ -4071,8 +3944,7 @@ describe("Groupchats", function () {
     describe("When attempting to enter a groupchat", function () {
 
         it("will use the nickname set in the global settings if the user doesn't have a VCard nickname",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
+                mock.initConverse(['chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
                 async function (done, _converse) {
 
             await mock.openChatRoomViaModal(_converse, 'roomy@muc.montague.lit');
@@ -4082,9 +3954,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the groupchat requires a password",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'protected';
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4118,9 +3988,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the groupchat is members-only and the user not included",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'members-only@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4167,9 +4035,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the user has been banned",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'off-limits@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4212,9 +4078,7 @@ describe("Groupchats", function () {
         }));
 
         it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'conflicted@muc.montague.lit';
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4257,9 +4121,7 @@ describe("Groupchats", function () {
 
 
         it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'conflicting@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4317,9 +4179,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the user is not allowed to have created the groupchat",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'impermissable@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo')
@@ -4357,9 +4217,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the user's nickname doesn't conform to groupchat policy",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'conformist@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4398,9 +4256,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the groupchat doesn't yet exist",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'nonexistent@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@@ -4439,9 +4295,7 @@ describe("Groupchats", function () {
         }));
 
         it("will show an error message if the groupchat has reached its maximum number of participants",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'maxed-out@muc.montague.lit'
             await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo')
@@ -4483,9 +4337,7 @@ describe("Groupchats", function () {
     describe("Someone being invited to a groupchat", function () {
 
         it("will first be added to the member list if the groupchat is members only",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.waitForRoster(_converse, 'current', 0);
             spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
@@ -4630,11 +4482,7 @@ describe("Groupchats", function () {
 
     describe("The affiliations delta", function () {
 
-        it("can be computed in various ways",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                async function (done, _converse) {
-
+        it("can be computed in various ways", mock.initConverse([], {}, async function (done, _converse) {
             await mock.openChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo');
             var exclude_existing = false;
             var remove_absentees = false;
@@ -4698,9 +4546,7 @@ describe("Groupchats", function () {
     describe("The \"Groupchats\" Add modal", function () {
 
         it("can be opened from a link in the \"Groupchats\" section of the controlbox",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             await mock.waitForRoster(_converse, 'current', 0);
@@ -4740,9 +4586,7 @@ describe("Groupchats", function () {
         }));
 
         it("doesn't show the nickname field if locked_muc_nickname is true",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'locked_muc_nickname': true, 'muc_nickname_from_jid': true},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'locked_muc_nickname': true, 'muc_nickname_from_jid': true}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             await mock.waitForRoster(_converse, 'current', 0);
@@ -4763,9 +4607,7 @@ describe("Groupchats", function () {
         }));
 
         it("uses the JID node if muc_nickname_from_jid is set to true",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'muc_nickname_from_jid': true},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'muc_nickname_from_jid': true}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             await mock.waitForRoster(_converse, 'current', 0);
@@ -4782,9 +4624,7 @@ describe("Groupchats", function () {
         }));
 
         it("uses the nickname passed in to converse.initialize",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'nickname': 'st.nick'},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'nickname': 'st.nick'}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             await mock.waitForRoster(_converse, 'current', 0);
@@ -4801,9 +4641,7 @@ describe("Groupchats", function () {
         }));
 
         it("doesn't require the domain when muc_domain is set",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org'},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'muc_domain': 'muc.example.org'}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list');
@@ -4841,8 +4679,7 @@ describe("Groupchats", function () {
         }));
 
         it("only uses the muc_domain is locked_muc_domain is true",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org', 'locked_muc_domain': true},
+                mock.initConverse(['chatBoxesFetched'], {'muc_domain': 'muc.example.org', 'locked_muc_domain': true},
                 async function (done, _converse) {
 
             await mock.openControlBox(_converse);
@@ -4883,9 +4720,7 @@ describe("Groupchats", function () {
     describe("The \"Groupchats\" List modal", function () {
 
         it("can be opened from a link in the \"Groupchats\" section of the controlbox",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             await mock.openControlBox(_converse);
             const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list');
@@ -4960,7 +4795,7 @@ describe("Groupchats", function () {
 
         it("is pre-filled with the muc_domain",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'],
+                ['chatBoxesFetched'],
                 {'muc_domain': 'muc.example.org'},
                 async function (done, _converse) {
 
@@ -4977,7 +4812,7 @@ describe("Groupchats", function () {
 
         it("doesn't let you set the MUC domain if it's locked",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'],
+                ['chatBoxesFetched'],
                 {'muc_domain': 'chat.shakespeare.lit', 'locked_muc_domain': true},
                 async function (done, _converse) {
 
@@ -5028,7 +4863,7 @@ describe("Groupchats", function () {
 
         it("shows the number of unread mentions received",
             mock.initConverse(
-                ['rosterContactsFetched'], {'allow_bookmarks': false},
+                [], {'allow_bookmarks': false},
                 async function (done, _converse) {
 
             await mock.openControlBox(_converse);
@@ -5078,7 +4913,7 @@ describe("Groupchats", function () {
 
         it("is is not sent out to a MUC if the user is a visitor in a moderated room",
             mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
+                ['chatBoxesFetched'], {},
                 async function (done, _converse) {
 
             spyOn(_converse.ChatRoom.prototype, 'sendChatState').and.callThrough();
@@ -5130,11 +4965,7 @@ describe("Groupchats", function () {
 
         describe("A composing notification", function () {
 
-            it("will be shown if received",
-                mock.initConverse(
-                    ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
-
+            it("will be shown if received", mock.initConverse([], {}, async function (done, _converse) {
                 const muc_jid = 'coven@chat.shakespeare.lit';
                 const members = [
                     {'affiliation': 'member', 'nick': 'majortom', 'jid': 'majortom@example.org'},
@@ -5255,11 +5086,7 @@ describe("Groupchats", function () {
 
         describe("A paused notification", function () {
 
-            it("will be shown if received",
-                mock.initConverse(
-                    ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                    async function (done, _converse) {
-
+            it("will be shown if received", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
                 const muc_jid = 'coven@chat.shakespeare.lit';
                 await mock.openAndEnterChatRoom(_converse, muc_jid, 'some1');
                 const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
@@ -5359,9 +5186,7 @@ describe("Groupchats", function () {
     describe("A muted user", function () {
 
         it("will receive a user-friendly error message when trying to send a message",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'trollbox@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'troll');
@@ -5409,9 +5234,7 @@ describe("Groupchats", function () {
         }));
 
         it("will see an explanatory message instead of a textarea",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const features = [
                 'http://jabber.org/protocol/muc',
@@ -5487,9 +5310,7 @@ describe("Groupchats", function () {
     describe("when muc_send_probes is true", function () {
 
         it("sends presence probes when muc_send_probes is true",
-            mock.initConverse(
-                ['rosterContactsFetched'], {'muc_send_probes': true},
-                async function (done, _converse) {
+                mock.initConverse([], {'muc_send_probes': true}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');

+ 14 - 42
spec/muc_messages.js

@@ -12,9 +12,7 @@ describe("A Groupchat Message", function () {
     describe("which is succeeded by an error message", function () {
 
         it("will have the error displayed below it",
-            mock.initConverse(
-                ['rosterContactsFetched'], {},
-                    async function (done, _converse) {
+                mock.initConverse([], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -57,9 +55,7 @@ describe("A Groupchat Message", function () {
     describe("an info message", function () {
 
         it("is not rendered as a followup message",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -95,9 +91,7 @@ describe("A Groupchat Message", function () {
         }));
 
         it("is not shown if its a duplicate",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -130,9 +124,7 @@ describe("A Groupchat Message", function () {
 
 
     it("is rejected if it's an unencapsulated forwarded message",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -165,9 +157,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("can contain a chat state notification and will still be shown",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -190,9 +180,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("can not be expected to have a unique id attribute",
-        mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -221,9 +209,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("is ignored if it has the same archive-id of an already received one",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'room@muc.example.com';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -270,9 +256,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("is ignored if it has the same stanza-id of an already received one",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'room@muc.example.com';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -318,9 +302,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("will be discarded if it's a malicious message meant to look like a carbon copy",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         await mock.openControlBox(_converse);
@@ -377,9 +359,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("keeps track of the sender's role and affiliation",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -505,9 +485,7 @@ describe("A Groupchat Message", function () {
 
 
     it("keeps track whether you are the sender or not",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -525,9 +503,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("will be shown as received upon MUC reflection",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         const muc_jid = 'lounge@montague.lit';
@@ -568,9 +544,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("gets updated with its stanza-id upon MUC reflection",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         const muc_jid = 'room@muc.example.com';
         await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -603,9 +577,7 @@ describe("A Groupchat Message", function () {
     }));
 
     it("can cause a delivery receipt to be returned",
-        mock.initConverse(
-            ['rosterContactsFetched'], {},
-            async function (done, _converse) {
+            mock.initConverse([], {}, async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
         const muc_jid = 'lounge@montague.lit';

+ 5 - 7
spec/rai.js

@@ -9,7 +9,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
 
     it("will be activated for a MUC that becomes hidden",
         mock.initConverse(
-            ['rosterContactsFetched'], {
+            [], {
                 'allow_bookmarks': false, // Hack to get the rooms list to render
                 'muc_subscribe_to_rai': true,
                 'view_mode': 'fullscreen'},
@@ -96,8 +96,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
         await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
         expect(view.model.get('has_activity')).toBe(false);
 
-        const lview = _converse.rooms_list_view
-        const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
+        const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
         expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
 
         const activity_stanza = u.toStanza(`
@@ -116,7 +115,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
 
     it("will be activated for a MUC that starts out hidden",
         mock.initConverse(
-            ['rosterContactsFetched'], {
+            [], {
                 'allow_bookmarks': false, // Hack to get the rooms list to render
                 'muc_subscribe_to_rai': true,
                 'view_mode': 'fullscreen'},
@@ -160,8 +159,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
         await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
         expect(view.model.get('has_activity')).toBe(false);
 
-        const lview = _converse.rooms_list_view
-        const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
+        const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
         expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
 
         const activity_stanza = u.toStanza(`
@@ -181,7 +179,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
 
     it("may not be activated due to server resource constraints",
         mock.initConverse(
-            ['rosterContactsFetched'], {
+            [], {
                 'allow_bookmarks': false, // Hack to get the rooms list to render
                 'muc_subscribe_to_rai': true,
                 'view_mode': 'fullscreen'},

+ 4 - 4
spec/receipts.js

@@ -8,7 +8,7 @@ describe("A delivery receipt", function () {
 
     it("is emitted for a received message which requests it",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current');
@@ -34,7 +34,7 @@ describe("A delivery receipt", function () {
 
     it("is not emitted for a carbon message",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
@@ -64,7 +64,7 @@ describe("A delivery receipt", function () {
 
     it("is not emitted for an archived message",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
@@ -101,7 +101,7 @@ describe("A delivery receipt", function () {
 
     it("can be received for a sent message",
         mock.initConverse(
-            ['rosterContactsFetched', 'chatBoxesFetched'], {},
+            ['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);

+ 15 - 55
spec/retractions.js

@@ -37,9 +37,7 @@ describe("Message Retractions", function () {
     describe("A groupchat message retraction", function () {
 
         it("is not applied if it's not from the right author",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@@ -81,9 +79,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can be received before the message it pertains to",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const date = (new Date()).toISOString();
             const muc_jid = 'lounge@montague.lit';
@@ -137,9 +133,7 @@ describe("Message Retractions", function () {
     describe("A groupchat message moderator retraction", function () {
 
         it("can be received before the message it pertains to",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const date = (new Date()).toISOString();
             const muc_jid = 'lounge@montague.lit';
@@ -198,9 +192,7 @@ describe("Message Retractions", function () {
     describe("A message retraction", function () {
 
         it("can be received before the message it pertains to",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const date = (new Date()).toISOString();
             await mock.waitForRoster(_converse, 'current', 1);
@@ -255,11 +247,7 @@ describe("Message Retractions", function () {
 
     describe("A Received Chat Message", function () {
 
-        it("can be followed up by a retraction",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
-
+        it("can be followed up by a retraction", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             await mock.waitForRoster(_converse, 'current', 1);
             await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@@ -325,11 +313,7 @@ describe("Message Retractions", function () {
 
     describe("A Sent Chat Message", function () {
 
-        it("can be retracted by its author",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
-
+        it("can be retracted by its author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             await mock.waitForRoster(_converse, 'current', 1);
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
             const view = await mock.openChatBoxFor(_converse, contact_jid);
@@ -375,11 +359,7 @@ describe("Message Retractions", function () {
 
     describe("A Received Groupchat Message", function () {
 
-        it("can be followed up by a retraction by the author",
-                mock.initConverse(
-                    ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                    async function (done, _converse) {
-
+        it("can be followed up by a retraction by the author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@@ -420,9 +400,7 @@ describe("Message Retractions", function () {
 
 
         it("can be retracted by a moderator, with the IQ response received before the retraction message",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@@ -506,9 +484,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can not be retracted if the MUC doesn't support message moderation",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@@ -532,9 +508,7 @@ describe("Message Retractions", function () {
 
 
         it("can be retracted by a moderator, with the retraction message received before the IQ response",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@@ -602,11 +576,7 @@ describe("Message Retractions", function () {
 
     describe("A Sent Groupchat Message", function () {
 
-        it("can be retracted by its author",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
-
+        it("can be retracted by its author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@@ -661,9 +631,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can be retracted by its author, causing an error message in response",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@@ -710,9 +678,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can be retracted by its author, causing a timeout error in response",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
 
             _converse.STANZA_TIMEOUT = 1;
 
@@ -746,11 +712,7 @@ describe("Message Retractions", function () {
         }));
 
 
-        it("can be retracted by a moderator",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {},
-                async function (done, _converse) {
-
+        it("can be retracted by a moderator", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@@ -799,9 +761,7 @@ describe("Message Retractions", function () {
         }));
 
         it("can be retracted by the sender if they're a moderator",
-            mock.initConverse(
-                ['rosterContactsFetched', 'chatBoxesFetched'], {'allow_message_retraction': 'moderator'},
-                async function (done, _converse) {
+                mock.initConverse(['chatBoxesFetched'], {'allow_message_retraction': 'moderator'}, async function (done, _converse) {
 
             const muc_jid = 'lounge@montague.lit';
             const features = [...mock.default_muc_features, Strophe.NS.MODERATE];

+ 6 - 6
spec/styling.js

@@ -5,7 +5,7 @@ const { u, Promise, $msg } = converse.env;
 describe("An incoming chat Message", function () {
 
     it("can have styling disabled via an \"unstyled\" element",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         const include_nick = false;
@@ -37,7 +37,7 @@ describe("An incoming chat Message", function () {
 
 
     it("can have styling disabled via the allow_message_styling setting",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {'allow_message_styling': false},
+        mock.initConverse(['chatBoxesFetched'], {'allow_message_styling': false},
             async function (done, _converse) {
 
         const include_nick = false;
@@ -67,7 +67,7 @@ describe("An incoming chat Message", function () {
     }));
 
     it("can be styled with span XEP-0393 message styling hints",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         let msg_text, msg, msg_el;
@@ -192,7 +192,7 @@ describe("An incoming chat Message", function () {
     }));
 
     it("can be styled with block XEP-0393 message styling hints",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         let msg_text, msg, msg_el;
@@ -240,7 +240,7 @@ describe("An incoming chat Message", function () {
     }));
 
     it("can be styled with quote XEP-0393 message styling hints",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         let msg_text, msg, msg_el;
@@ -392,7 +392,7 @@ describe("An incoming chat Message", function () {
 describe("A outgoing groupchat Message", function () {
 
     it("can be styled with span XEP-0393 message styling hints that contain mentions",
-        mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {},
+        mock.initConverse(['chatBoxesFetched'], {},
             async function (done, _converse) {
 
         const muc_jid = 'lounge@montague.lit';

+ 4 - 2
src/headless/plugins/muc/muc.js

@@ -189,9 +189,10 @@ const ChatRoomMixin = {
             return;
         }
         if (msg?.get('is_markable') || force) {
-            const id = msg.get(`stanza_id ${this.get('jid')}`);
+            const key = `stanza_id ${this.get('jid')}`;
+            const id = msg.get(key);
             if (!id) {
-                log.error(`Can't send marker for message without stanza ID: ${msg}`);
+                log.error(`Can't send marker for message without stanza ID: ${key}`);
                 return;
             }
             const from_jid = Strophe.getBareJidFromJid(msg.get('from'));
@@ -1923,6 +1924,7 @@ const ChatRoomMixin = {
         } else if (attrs.is_valid_receipt_request || attrs.is_marker || this.ignorableCSN(attrs)) {
             return;
         }
+
         if (
             (await this.handleRetraction(attrs)) ||
             (await this.handleModeration(attrs)) ||