Jelajahi Sumber

Two changes, see below

* Add new test helper to create contacts via IQ exchange
* Use roster nickname to set message fullname
JC Brand 6 tahun lalu
induk
melakukan
59c43a23f0
6 mengubah file dengan 193 tambahan dan 237 penghapusan
  1. 11 9
      dist/converse.js
  2. 82 137
      spec/chatbox.js
  3. 47 69
      spec/messages.js
  4. 7 13
      spec/spoilers.js
  5. 9 7
      src/headless/converse-chatboxes.js
  6. 37 2
      tests/utils.js

+ 11 - 9
dist/converse.js

@@ -61589,11 +61589,12 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         return {
           'bookmarked': false,
           'chat_state': undefined,
+          'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode),
+          'message_type': 'chat',
+          'nickname': undefined,
           'num_unread': 0,
           'type': _converse.PRIVATE_CHAT_TYPE,
-          'message_type': 'chat',
-          'url': '',
-          'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode)
+          'url': ''
         };
       },
 
@@ -61643,7 +61644,8 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
           // and we listen for change:chat_state, so shouldn't set it to ACTIVE here.
           'box_id': b64_sha1(this.get('jid')),
           'time_opened': this.get('time_opened') || moment().valueOf(),
-          'user_id': Strophe.getNodeFromJid(this.get('jid'))
+          'user_id': Strophe.getNodeFromJid(this.get('jid')),
+          'nickname': _.get(_converse.api.contacts.get(this.get('jid')), 'attributes.nickname')
         });
       },
 
@@ -62126,7 +62128,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
             attrs.fullname = _converse.xmppstatus.get('fullname');
           } else {
             attrs.sender = 'them';
-            attrs.fullname = this.get('fullname');
+            attrs.fullname = this.get('fullname') || this.get('fullname');
           }
         }
 
@@ -62362,10 +62364,10 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
 
 
         const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}"]`, stanza).length > 0,
-              chatbox_attrs = {
-          'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname')
-        },
-              chatbox = this.getChatBox(contact_jid, chatbox_attrs, has_body);
+              roster_nick = _.get(_converse.api.contacts.get(contact_jid), 'attributes.nickname'),
+              chatbox = this.getChatBox(contact_jid, {
+          'nickname': roster_nick
+        }, has_body);
 
         if (chatbox && !chatbox.findDuplicateFromOriginID(stanza) && !(await chatbox.hasDuplicateArchiveID(original_stanza)) && !(await chatbox.hasDuplicateStanzaID(stanza)) && !chatbox.handleMessageCorrection(stanza) && !chatbox.handleReceipt(stanza, from_jid, is_carbon, is_me) && !chatbox.handleChatMarker(stanza, from_jid, is_carbon, is_roster_contact)) {
           const attrs = await chatbox.getMessageAttributesFromStanza(stanza, original_stanza);

+ 82 - 137
spec/chatbox.js

@@ -23,8 +23,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 test_utils.openControlBox();
 
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -56,7 +55,7 @@
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
+                await test_utils.waitForRoster(_converse, 'current');
                 await test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']);
                 await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
                 await test_utils.openControlBox();
@@ -103,8 +102,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 // openControlBox was called earlier, so the controlbox is
@@ -165,7 +163,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const stanza = u.toStanza(`
                     <message from="${sender_jid}"
@@ -190,9 +188,7 @@
                 spyOn(trimmed_chatboxes, 'addChat').and.callThrough();
                 spyOn(trimmed_chatboxes, 'removeChat').and.callThrough();
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
-
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 let jid, chatboxview;
@@ -241,19 +237,17 @@
             it("can be opened in minimized mode initially",
                 mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
-                    function (done, _converse) {
-
-                test_utils.createContacts(_converse, 'current');
+                    async function (done, _converse) {
 
-                var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-                var chat = _converse.api.chats.create(sender_jid, {
+                await test_utils.waitForRoster(_converse, 'current');
+                const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+                const chat = _converse.api.chats.create(sender_jid, {
                     minimized: true
                 });
-
-                var chatBoxView = _converse.chatboxviews.get(sender_jid);
+                const chatBoxView = _converse.chatboxviews.get(sender_jid);
                 expect(u.isVisible(chatBoxView.el)).toBeFalsy();
 
-                var minimized_chat = _converse.minimized_chats.get(sender_jid);
+                const minimized_chat = _converse.minimized_chats.get(sender_jid);
                 expect(minimized_chat).toBeTruthy();
                 expect($(minimized_chat.el).is(':visible')).toBeTruthy();
                 done();
@@ -261,30 +255,26 @@
 
 
             it("is focused if its already open and you click on its corresponding roster item",
-                mock.initConverse(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
+                mock.initConverse(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
+                    async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
-                let el, jid;
                 // openControlBox was called earlier, so the controlbox is
                 // visible, but no other chat boxes have been created.
                 expect(_converse.chatboxes.length).toEqual(1);
 
-                test_utils.openChatBoxFor(_converse, contact_jid)
-                .then((view) => {
-                    el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', _converse.rosterview.el).pop();
-                    jid = el.textContent.replace(/ /g,'.').toLowerCase() + '@localhost';
-                    spyOn(_converse, 'emit');
-                    el.click();
-                    return test_utils.waitUntil(() => _converse.emit.calls.count(), 500);
-                }).then(() => {
-                    expect(_converse.chatboxes.length).toEqual(2);
-                    expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
-                    done();
-                });
+                const view = await test_utils.openChatBoxFor(_converse, contact_jid);
+                const el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', _converse.rosterview.el).pop();
+                const jid = el.textContent.replace(/ /g,'.').toLowerCase() + '@localhost';
+                spyOn(_converse, 'emit');
+                el.click();
+                await test_utils.waitUntil(() => _converse.emit.calls.count(), 500);
+                expect(_converse.chatboxes.length).toEqual(2);
+                expect(_converse.emit).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
+                done();
             }));
 
             it("can be saved to, and retrieved from, browserStorage",
@@ -292,8 +282,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched',], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 spyOn(_converse, 'emit');
@@ -329,8 +318,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -365,9 +353,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
-
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -407,8 +393,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
                 spyOn(_converse, 'emit');
@@ -449,10 +434,8 @@
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current', 3);
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current', 3);
                     test_utils.openControlBox();
-
                     const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
                     await test_utils.openChatBoxFor(_converse, contact_jid);
                     const chatbox = _converse.chatboxes.get(contact_jid);
@@ -470,8 +453,7 @@
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current');
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current');
                     test_utils.openControlBox();
 
                     const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -501,8 +483,7 @@
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current');
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current');
                     test_utils.openControlBox();
 
                     let toolbar, call_button;
@@ -537,7 +518,7 @@
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current');
+                    await test_utils.waitForRoster(_converse, 'current');
                     test_utils.openControlBox();
 
                     const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -569,8 +550,7 @@
                         null, ['rosterGroupsFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current');
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current');
                     test_utils.openControlBox();
 
                     spyOn(_converse, 'emit');
@@ -595,8 +575,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                         test_utils.openControlBox();
                         test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
@@ -618,8 +597,7 @@
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current', 1);
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current', 1);
                         test_utils.openControlBox();
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
@@ -653,8 +631,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         test_utils.openControlBox();
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
@@ -691,8 +668,7 @@
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         test_utils.openControlBox();
 
                         // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
@@ -740,8 +716,7 @@
                         let contact, sent_stanza, IQ_id, stanza;
                         await test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']);
                         await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         // Send a message from a different resource
                         spyOn(_converse, 'log');
                         const recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -784,8 +759,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                         test_utils.openControlBox();
                         await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
@@ -839,8 +813,7 @@
                                 null, ['rosterGroupsFetched'], {},
                                 async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current', 2);
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         test_utils.openControlBox();
                         await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
                         // TODO: only show paused state if the previous state was composing
@@ -871,8 +844,7 @@
                         let contact, sent_stanza, IQ_id, stanza;
                         await test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']);
                         await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
-                        test_utils.createContacts(_converse, 'current', 6);
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         // Send a message from a different resource
                         spyOn(_converse, 'log');
                         const recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -919,9 +891,7 @@
                         _converse.TIMEOUTS.PAUSED = 200;
                         _converse.TIMEOUTS.INACTIVE = 200;
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
-
+                        await test_utils.waitForRoster(_converse, 'current');
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                         test_utils.openControlBox();
                         await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 1000);
@@ -967,8 +937,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current', 1);
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         test_utils.openControlBox();
 
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -989,8 +958,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                         test_utils.openControlBox();
                         await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
@@ -1014,8 +982,7 @@
                             null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current');
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current');
                         test_utils.openControlBox();
                         const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
                         // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
@@ -1057,8 +1024,7 @@
                             null, ['rosterGroupsFetched'], {},
                             async function (done, _converse) {
 
-                        test_utils.createContacts(_converse, 'current', 3);
-                        _converse.emit('rosterContactsFetched');
+                        await test_utils.waitForRoster(_converse, 'current', 3);
                         test_utils.openControlBox();
 
                         spyOn(_converse, 'emit');
@@ -1089,8 +1055,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
@@ -1133,8 +1098,7 @@
                     async function (done, _converse) {
 
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 expect(_converse.msg_counter).toBe(0);
@@ -1170,9 +1134,9 @@
             it("is cleared when the window is focused",
                 mock.initConverse(
                     null, ['rosterGroupsFetched'], {},
-                    function (done, _converse) {
+                    async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
                 _converse.windowState = 'hidden';
                 spyOn(_converse, 'clearMsgCounter').and.callThrough();
@@ -1187,7 +1151,7 @@
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 expect(_converse.msg_counter).toBe(0);
@@ -1213,8 +1177,7 @@
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 // initial state
                 expect(_converse.msg_counter).toBe(0);
                 const message = 'This message will always increment the message counter from zero',
@@ -1264,9 +1227,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
-
+                await test_utils.waitForRoster(_converse, 'current');
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
                       msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
 
@@ -1283,8 +1244,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
 
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
                       msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be read');
@@ -1300,8 +1260,7 @@
                 mock.initConverse(null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
 
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const msgFactory = function () {
@@ -1321,8 +1280,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
                 await test_utils.openChatBoxFor(_converse, sender_jid);
@@ -1340,8 +1298,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
                 await test_utils.openChatBoxFor(_converse, sender_jid);
@@ -1360,8 +1317,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
                 await test_utils.openChatBoxFor(_converse, sender_jid);
@@ -1384,9 +1340,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
-
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 let msg, indicator_el;
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
@@ -1396,10 +1350,9 @@
                 msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
                 await _converse.chatboxes.onMessage(msg);
                 await test_utils.waitUntil(() => chatbox.messages.length);
-                const selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
+                const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
                 indicator_el = sizzle(selector, _converse.rosterview.el).pop();
                 expect(indicator_el.textContent).toBe('1');
-
                 msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread too');
                 await _converse.chatboxes.onMessage(msg);
                 await test_utils.waitUntil(() => chatbox.messages.length > 1);
@@ -1413,8 +1366,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
                 let indicator_el, msg;
@@ -1427,7 +1379,7 @@
                 msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
                 await _converse.chatboxes.onMessage(msg);
                 await test_utils.waitUntil(() => chatbox.messages.length);
-                const selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
+                const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
                 indicator_el = sizzle(selector, _converse.rosterview.el).pop();
                 expect(indicator_el.textContent).toBe('1');
 
@@ -1444,25 +1396,24 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
                 await test_utils.openChatBoxFor(_converse, sender_jid);
                 const chatbox = _converse.chatboxes.get(sender_jid);
                 const view = _converse.chatboxviews.get(sender_jid);
-                const msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
-                const select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
+                const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
+                const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
                 view.minimize();
                 _converse.chatboxes.onMessage(msgFactory());
                 await test_utils.waitUntil(() => chatbox.messages.length);
-                expect(select_msgs_indicator().text()).toBe('1');
+                expect(select_msgs_indicator().textContent).toBe('1');
                 _converse.chatboxes.onMessage(msgFactory());
                 await test_utils.waitUntil(() => chatbox.messages.length > 1);
-                expect(select_msgs_indicator().text()).toBe('2');
+                expect(select_msgs_indicator().textContent).toBe('2');
                 view.maximize();
-                expect(select_msgs_indicator().length).toBe(0);
+                expect(select_msgs_indicator()).toBeUndefined();
                 done();
             }));
 
@@ -1471,23 +1422,22 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
                 await test_utils.openChatBoxFor(_converse, sender_jid);
                 const chatbox = _converse.chatboxes.get(sender_jid);
                 const view = _converse.chatboxviews.get(sender_jid);
                 const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
-                const msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
-                const select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
+                const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
+                const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
                 chatbox.save('scrolled', true);
                 _converse.chatboxes.onMessage(msgFactory());
                 await test_utils.waitUntil(() => view.model.messages.length);
-                expect(select_msgs_indicator().text()).toBe('1');
+                expect(select_msgs_indicator().textContent).toBe('1');
                 view.viewUnreadMessages();
                 _converse.rosterview.render();
-                expect(select_msgs_indicator().length).toBe(0);
+                expect(select_msgs_indicator()).toBeUndefined();
                 done();
             }));
 
@@ -1496,24 +1446,22 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
                 await test_utils.openChatBoxFor(_converse, sender_jid);
                 const chatbox = _converse.chatboxes.get(sender_jid);
                 const view = _converse.chatboxviews.get(sender_jid);
-                const msgFactory = function () {
-                    return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
-                };
-                var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
-                const select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
+                const msg = 'This message will be received as unread, but eventually will be read';
+                const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, msg);
+                const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
+                const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
                 chatbox.save('scrolled', true);
                 _converse.chatboxes.onMessage(msgFactory());
                 await test_utils.waitUntil(() => view.model.messages.length);
-                expect(select_msgs_indicator().text()).toBe('1');
+                expect(select_msgs_indicator().textContent).toBe('1');
                 await test_utils.openChatBoxFor(_converse, sender_jid);
-                expect(select_msgs_indicator().text()).toBe('1');
+                expect(select_msgs_indicator().textContent).toBe('1');
                 done();
             }));
         });
@@ -1525,8 +1473,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.openChatBoxFor(_converse, sender_jid);
                 const msgFactory = function () {
@@ -1554,8 +1501,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 const view = await test_utils.openChatBoxFor(_converse, sender_jid)
                 const msgFactory = function () {
@@ -1580,8 +1526,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
 
                 const base_url = document.URL.split(window.location.pathname)[0],
                       message = "geo:37.786971,-122.399677",

+ 47 - 69
spec/messages.js

@@ -18,8 +18,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current', 1);
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid);
@@ -123,8 +122,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current', 1);
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid)
@@ -280,7 +278,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
 
             let message, msg;
@@ -466,7 +464,7 @@
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
 
             /* Ideally we wouldn't have to filter out headline
@@ -502,7 +500,8 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            const include_nick = false;
+            await test_utils.waitForRoster(_converse, 'current', 2, include_nick);
             test_utils.openControlBox();
 
             // Send a message from a different resource
@@ -523,6 +522,7 @@
                         'to': _converse.bare_jid+'/another-resource',
                         'type': 'chat'
                 }).c('body').t(msgtext).tree();
+
             await _converse.chatboxes.onMessage(msg);
             await test_utils.waitUntil(() => (_converse.api.chats.get().length > 1))
             const chatbox = _converse.chatboxes.get(sender_jid);
@@ -534,7 +534,8 @@
             expect(chatbox.messages.length).toEqual(1);
             const msg_obj = chatbox.messages.models[0];
             expect(msg_obj.get('message')).toEqual(msgtext);
-            expect(msg_obj.get('fullname')).toEqual(mock.cur_names[1]);
+            expect(msg_obj.get('fullname')).toBeUndefined();
+            expect(msg_obj.get('nickname')).toBeUndefined();
             expect(msg_obj.get('sender')).toEqual('them');
             expect(msg_obj.get('is_delayed')).toEqual(false);
             // Now check that the message appears inside the chatbox in the DOM
@@ -553,8 +554,7 @@
                 async function (done, _converse) {
 
             await test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp']);
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
 
             // Send a message from a different resource
@@ -601,7 +601,7 @@
             null, ['rosterGroupsFetched'], {},
             async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
             /* <message from="mallory@evil.example" to="b@xmpp.example">
              *    <received xmlns='urn:xmpp:carbons:2'>
@@ -651,8 +651,7 @@
             if (_converse.view_mode === 'fullscreen') {
                 return done();
             }
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             const contact_name = mock.cur_names[0];
             const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@localhost';
             test_utils.openControlBox();
@@ -711,8 +710,8 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            const include_nick = false;
+            await test_utils.waitForRoster(_converse, 'current', 2, include_nick);
             test_utils.openControlBox();
             spyOn(_converse, 'emit');
             const contact_name = mock.cur_names[1];
@@ -742,7 +741,8 @@
             expect(chatbox.messages.length).toEqual(1);
             let msg_obj = chatbox.messages.models[0];
             expect(msg_obj.get('message')).toEqual(message);
-            expect(msg_obj.get('fullname')).toEqual(contact_name);
+            expect(msg_obj.get('fullname')).toBeUndefined();
+            expect(msg_obj.get('nickname')).toBeUndefined();
             expect(msg_obj.get('sender')).toEqual('them');
             expect(msg_obj.get('is_delayed')).toEqual(true);
             await test_utils.waitUntil(() => chatbox.vcard.get('fullname') === 'Candice van der Knijff')
@@ -788,7 +788,7 @@
             expect(chatbox.messages.length).toEqual(2);
             msg_obj = chatbox.messages.models[1];
             expect(msg_obj.get('message')).toEqual(message);
-            expect(msg_obj.get('fullname')).toEqual(contact_name);
+            expect(msg_obj.get('fullname')).toBeUndefined();
             expect(msg_obj.get('sender')).toEqual('them');
             expect(msg_obj.get('is_delayed')).toEqual(false);
             const msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
@@ -805,8 +805,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
             spyOn(_converse, 'emit');
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -828,8 +827,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid)
@@ -849,8 +847,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid)
@@ -872,8 +869,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
 
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -916,8 +912,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const view = await test_utils.openChatBoxFor(_converse, contact_jid);
             let stanza = u.toStanza(`
@@ -956,8 +951,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             let base_url = 'https://conversejs.org';
             let message = base_url+"/logo/conversejs-filled.svg";
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -1005,9 +999,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
-
+            await test_utils.waitForRoster(_converse, 'current');
             _converse.time_format = 'hh:mm';
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid)
@@ -1033,8 +1025,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             test_utils.openControlBox();
 
             let message, msg;
@@ -1200,8 +1191,8 @@
             mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+
+            await test_utils.waitForRoster(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const msg_id = u.getUniqueId();
             const sent_stanzas = [];
@@ -1227,7 +1218,7 @@
             mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
-            test_utils.createContacts(_converse, 'current', 1);
+            await test_utils.waitForRoster(_converse, 'current', 1);
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const msg_id = u.getUniqueId();
             const sent_stanzas = [];
@@ -1258,7 +1249,7 @@
             mock.initConverse(
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
-            test_utils.createContacts(_converse, 'current', 1);
+            await test_utils.waitForRoster(_converse, 'current', 1);
             const recipient_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             const msg_id = u.getUniqueId();
             const sent_stanzas = [];
@@ -1289,8 +1280,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current', 1);
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = _converse.chatboxviews.get(contact_jid);
@@ -1349,8 +1339,8 @@
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                const include_nick = false;
+                await test_utils.waitForRoster(_converse, 'current', 1, include_nick);
                 test_utils.openControlBox();
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
                 spyOn(_converse, 'emit').and.callThrough();
@@ -1378,7 +1368,7 @@
                 expect(chatbox.messages.length).toEqual(1);
                 const msg_obj = chatbox.messages.models[0];
                 expect(msg_obj.get('message')).toEqual(message);
-                expect(msg_obj.get('fullname')).toEqual(mock.cur_names[0]);
+                expect(msg_obj.get('fullname')).toBeUndefined();
                 expect(msg_obj.get('sender')).toEqual('them');
                 expect(msg_obj.get('is_delayed')).toEqual(false);
                 // Now check that the message appears inside the chatbox in the DOM
@@ -1395,8 +1385,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 test_utils.openControlBox();
                 const message = 'This is a received message';
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -1578,8 +1567,7 @@
                         null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                         async function (done, _converse) {
 
-                    test_utils.createContacts(_converse, 'current');
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current', 1);
                     test_utils.openControlBox();
 
                     // TODO: what could still be done for error
@@ -1725,8 +1713,7 @@
 
                     // See #1317
                     // https://github.com/conversejs/converse.js/issues/1317
-                    test_utils.createContacts(_converse, 'current');
-                    _converse.emit('rosterContactsFetched');
+                    await test_utils.waitForRoster(_converse, 'current');
                     test_utils.openControlBox();
 
                     const contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -1763,8 +1750,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current');
                 test_utils.openControlBox();
 
                 const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -1817,9 +1803,7 @@
                     null, ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                test_utils.openControlBox();
-
+                await test_utils.waitForRoster(_converse, 'current');
                 await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
                 // Send a message from a different resource
                 spyOn(_converse, 'log');
@@ -1869,8 +1853,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.openChatBoxFor(_converse, contact_jid);
                 const view = _converse.api.chatviews.get(contact_jid);
@@ -1920,8 +1903,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.openChatBoxFor(_converse, contact_jid)
                 const view = _converse.api.chatviews.get(contact_jid);
@@ -1969,8 +1951,7 @@
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     async function (done, _converse) {
 
-                test_utils.createContacts(_converse, 'current', 1);
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.openChatBoxFor(_converse, contact_jid);
                 const view = _converse.api.chatviews.get(contact_jid);
@@ -2000,8 +1981,7 @@
                     async function (done, _converse) {
 
                 const base_url = 'https://conversejs.org';
-                test_utils.createContacts(_converse, 'current');
-                _converse.emit('rosterContactsFetched');
+                await test_utils.waitForRoster(_converse, 'current', 1);
                 const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                 await test_utils.openChatBoxFor(_converse, contact_jid)
                 const view = _converse.api.chatviews.get(contact_jid);
@@ -2038,8 +2018,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current', 1);
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             await test_utils.openChatBoxFor(_converse, contact_jid);
             const view = _converse.api.chatviews.get(contact_jid);
@@ -2108,7 +2087,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current', 1);
+            await test_utils.waitForRoster(_converse, 'current', 1);
             await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
 
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
@@ -2258,7 +2237,6 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
             await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
             const view = _converse.api.chatviews.get('lounge@localhost');
             const msg = $msg({
@@ -2446,7 +2424,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
             const view = _converse.chatboxviews.get('lounge@localhost');
             const textarea = view.el.querySelector('textarea.chat-textarea');
@@ -2525,7 +2503,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
             const view = _converse.chatboxviews.get('lounge@localhost');
             const textarea = view.el.querySelector('textarea.chat-textarea');
@@ -2559,7 +2537,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async function (done, _converse) {
 
-            test_utils.createContacts(_converse, 'current');
+            await test_utils.waitForRoster(_converse, 'current');
             await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
             const view = _converse.chatboxviews.get('lounge@localhost');
             const textarea = view.el.querySelector('textarea.chat-textarea');

+ 7 - 13
spec/spoilers.js

@@ -14,8 +14,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async (done, _converse) => {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
             /* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
@@ -35,7 +34,7 @@
                       'xmlns': 'urn:xmpp:spoiler:0',
                     }).t(spoiler_hint)
                 .tree();
-            _converse.chatboxes.onMessage(msg);
+            await _converse.chatboxes.onMessage(msg);
 
             await test_utils.waitUntil(() => _converse.api.chats.get().length === 2);
             const view = _converse.chatboxviews.get(sender_jid);
@@ -53,8 +52,7 @@
                 null, ['rosterGroupsFetched'], {},
                 async (done, _converse) => {
 
-            test_utils.createContacts(_converse, 'current');
-            _converse.emit('rosterContactsFetched');
+            await test_utils.waitForRoster(_converse, 'current');
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
             /* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
              *      <body>And at the end of the story, both of them die! It is so tragic!</body>
@@ -71,7 +69,7 @@
                   .c('spoiler', {
                       'xmlns': 'urn:xmpp:spoiler:0',
                     }).tree();
-            _converse.chatboxes.onMessage(msg);
+            await _converse.chatboxes.onMessage(msg);
             await test_utils.waitUntil(() => _converse.api.chats.get().length === 2);
             const view = _converse.chatboxviews.get(sender_jid);
             await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
@@ -88,9 +86,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async (done, _converse) => {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
-
+            await test_utils.waitForRoster(_converse, 'current', 1);
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 
@@ -105,7 +101,7 @@
             _converse.connection._dataRecv(test_utils.createRequest(presence));
             await test_utils.openChatBoxFor(_converse, contact_jid);
             await test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]);
-            const view = _converse.chatboxviews.get(contact_jid);
+            const view = _converse.api.chatviews.get(contact_jid);
             spyOn(_converse.connection, 'send');
 
             await test_utils.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
@@ -163,9 +159,7 @@
                 null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                 async (done, _converse) => {
 
-            test_utils.createContacts(_converse, 'current', 1);
-            _converse.emit('rosterContactsFetched');
-
+            await test_utils.waitForRoster(_converse, 'current', 1);
             test_utils.openControlBox();
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
 

+ 9 - 7
src/headless/converse-chatboxes.js

@@ -225,11 +225,12 @@ converse.plugins.add('converse-chatboxes', {
                 return {
                     'bookmarked': false,
                     'chat_state': undefined,
+                    'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode),
+                    'message_type': 'chat',
+                    'nickname': undefined,
                     'num_unread': 0,
                     'type': _converse.PRIVATE_CHAT_TYPE,
-                    'message_type': 'chat',
-                    'url': '',
-                    'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode)
+                    'url': ''
                 }
             },
 
@@ -273,7 +274,8 @@ converse.plugins.add('converse-chatboxes', {
                     // and we listen for change:chat_state, so shouldn't set it to ACTIVE here.
                     'box_id' : b64_sha1(this.get('jid')),
                     'time_opened': this.get('time_opened') || moment().valueOf(),
-                    'user_id' : Strophe.getNodeFromJid(this.get('jid'))
+                    'user_id' : Strophe.getNodeFromJid(this.get('jid')),
+                    'nickname':_.get(_converse.api.contacts.get(this.get('jid')), 'attributes.nickname')
                 });
             },
 
@@ -685,7 +687,7 @@ converse.plugins.add('converse-chatboxes', {
                         attrs.fullname = _converse.xmppstatus.get('fullname');
                     } else {
                         attrs.sender = 'them';
-                        attrs.fullname = this.get('fullname');
+                        attrs.fullname = this.get('fullname') || this.get('fullname')
                     }
                 }
                 _.each(sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, stanza), (xform) => {
@@ -903,8 +905,8 @@ converse.plugins.add('converse-chatboxes', {
                 }
                 // Get chat box, but only create when the message has something to show to the user
                 const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}"]`, stanza).length > 0,
-                      chatbox_attrs = {'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname')},
-                      chatbox = this.getChatBox(contact_jid, chatbox_attrs, has_body);
+                      roster_nick = _.get(_converse.api.contacts.get(contact_jid), 'attributes.nickname'),
+                      chatbox = this.getChatBox(contact_jid, {'nickname': roster_nick}, has_body);
 
                 if (chatbox &&
                         !chatbox.findDuplicateFromOriginID(stanza) &&

+ 37 - 2
tests/utils.js

@@ -62,7 +62,7 @@
     };
 
     utils.openControlBox = function () {
-        var toggle = document.querySelector(".toggle-controlbox");
+        const toggle = document.querySelector(".toggle-controlbox");
         if (!u.isVisible(document.querySelector("#controlbox"))) {
             if (!u.isVisible(toggle)) {
                 u.removeClass('hidden', toggle);
@@ -260,10 +260,45 @@
         return this;
     };
 
+    utils.waitForRoster = async function (_converse, type='current', length, include_nick=true) {
+        const iq = await utils.waitUntil(() =>
+            _.filter(
+                _converse.connection.IQ_stanzas,
+                iq => sizzle(`iq[type="get"] query[xmlns="${Strophe.NS.ROSTER}"]`, iq.nodeTree).length
+            ).pop());
+
+        const result = $iq({
+            'to': _converse.connection.jid,
+            'type': 'result',
+            'id': iq.nodeTree.getAttribute('id')
+        }).c('query', {
+            'xmlns': 'jabber:iq:roster'
+        });
+        if (type === 'pending' || type === 'all') {
+            mock.pend_names.slice(0, length).map(name =>
+                result.c('item', {
+                    jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                    name: include_nick ? name : undefined,
+                    subscription: 'to'
+                }).up()
+            );
+        } else if (type === 'current' || type === 'all') {
+            mock.cur_names.slice(0, length).map(name =>
+                result.c('item', {
+                    jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                    name: include_nick ? name : undefined,
+                    subscription: 'both'
+                }).up()
+            );
+        }
+        _converse.connection._dataRecv(utils.createRequest(result));
+        await _converse.api.waitUntil('rosterContactsFetched');
+    };
+
     utils.createGroupedContacts = function (converse) {
         /* Create grouped contacts
          */
-        var i=0, j=0;
+        let i=0, j=0;
         _.each(_.keys(mock.groups), function (name) {
             j = i;
             for (i=j; i<j+mock.groups[name]; i++) {