瀏覽代碼

Start fixing tests

JC Brand 5 年之前
父節點
當前提交
710f38ce97
共有 12 個文件被更改,包括 92 次插入98 次删除
  1. 11 11
      spec/chatbox.js
  2. 5 5
      spec/emojis.js
  3. 3 3
      spec/http-file-upload.js
  4. 1 1
      spec/mam.js
  5. 41 41
      spec/messages.js
  6. 1 1
      spec/mock.js
  7. 10 10
      spec/muc.js
  8. 12 12
      spec/muc_messages.js
  9. 2 2
      spec/notification.js
  10. 3 3
      spec/omemo.js
  11. 3 3
      spec/spoilers.js
  12. 0 6
      src/components/chat_content.js

+ 11 - 11
spec/chatbox.js

@@ -35,12 +35,13 @@ fdescribe("Chatboxes", function () {
                 }).c('body').t('hello world').tree();
             await _converse.handleMessageStanza(msg);
             await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
-            expect(view.msgs_container.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
+            const msg_txt_sel = 'converse-chat-message:last-child .chat-msg__body';
+            await u.waitUntil(() => view.el.querySelector(msg_txt_sel).textContent.trim() === 'hello world');
             done();
         }));
 
 
-        fit("supports the /me command", mock.initConverse(['rosterGroupsFetched'], {}, async function (done, _converse) {
+        it("supports the /me command", mock.initConverse(['rosterGroupsFetched'], {}, 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'));
@@ -75,12 +76,15 @@ fdescribe("Chatboxes", function () {
             // get the 'chat-msg--followup' class.
             message = 'This a normal message';
             await mock.sendMessage(view, message);
-            await u.waitUntil(() => view.el.querySelector('.message:last-child').textContent === message);
-            expect(u.hasClass('chat-msg--followup', view.el.querySelector('.message:last-child'))).toBeFalsy();
+            const msg_txt_sel = 'converse-chat-message:last-child .chat-msg__body';
+            await u.waitUntil(() => view.el.querySelector(msg_txt_sel).textContent.trim() === message);
+            let el = view.el.querySelector('converse-chat-message:last-child .chat-msg__body');
+            expect(u.hasClass('chat-msg--followup', el)).toBeFalsy();
 
             message = '/me wrote a 3rd person message';
             await mock.sendMessage(view, message);
-            await u.waitUntil(() => view.el.querySelector('.message:last-child').textContent === message);
+            await u.waitUntil(() => view.el.querySelector(msg_txt_sel).textContent.trim() === message.replace('/me ', ''));
+            el = view.el.querySelector('converse-chat-message:last-child .chat-msg__body');
             expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(3);
 
             expect(sizzle('.chat-msg__text:last', view.el).pop().textContent).toBe('wrote a 3rd person message');
@@ -454,7 +458,7 @@ fdescribe("Chatboxes", function () {
                     keyCode: 13 // Enter
                 };
                 view.onKeyDown(ev);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 view.onKeyUp(ev);
                 expect(counter.textContent).toBe('200');
 
@@ -1158,7 +1162,7 @@ fdescribe("Chatboxes", function () {
 
     describe("A Message Counter", function () {
 
-        fit("is incremented when the message is received and the window is not focused",
+        it("is incremented when the message is received and the window is not focused",
                 mock.initConverse(
                     ['rosterGroupsFetched'], {},
                     async function (done, _converse) {
@@ -1169,8 +1173,6 @@ fdescribe("Chatboxes", function () {
             expect(document.title).toBe('Converse Tests');
 
             const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
-            const view = await mock.openChatBoxFor(_converse, sender_jid)
-
             const previous_state = _converse.windowState;
             const message = 'This message will increment the message counter';
             const msg = $msg({
@@ -1186,9 +1188,7 @@ fdescribe("Chatboxes", function () {
             spyOn(_converse, 'incrementMsgCounter').and.callThrough();
             spyOn(_converse, 'clearMsgCounter').and.callThrough();
 
-            const promise = new Promise(resolve => view.once('messageInserted', resolve));
             await _converse.handleMessageStanza(msg);
-            await promise;
             expect(_converse.incrementMsgCounter).toHaveBeenCalled();
             expect(_converse.clearMsgCounter).not.toHaveBeenCalled();
             expect(document.title).toBe('Messages (1) Converse Tests');

+ 5 - 5
spec/emojis.js

@@ -170,7 +170,7 @@ describe("Emojis", function () {
                 .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
             await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
             const view = _converse.api.chatviews.get(sender_jid);
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             let message = view.content.querySelector('.chat-msg__text');
             expect(u.hasClass('chat-msg__text--larger', message)).toBe(true);
 
@@ -181,7 +181,7 @@ describe("Emojis", function () {
                     'id': _converse.connection.getUniqueId()
                 }).c('body').t('😇 Hello world! 😇 😇').up()
                 .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             message = view.content.querySelector('.message:last-child .chat-msg__text');
             expect(u.hasClass('chat-msg__text--larger', message)).toBe(false);
 
@@ -194,7 +194,7 @@ describe("Emojis", function () {
                 preventDefault: function preventDefault () {},
                 keyCode: 13 // Enter
             });
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
             expect(view.content.querySelector('.message:last-child .chat-msg__text').textContent).toBe('💩 😇');
             expect(textarea.value).toBe('');
@@ -222,7 +222,7 @@ describe("Emojis", function () {
                 preventDefault: function preventDefault () {},
                 keyCode: 13 // Enter
             });
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             textarea.value = ':smile: :smiley: :imp:';
             view.onKeyDown({
@@ -230,7 +230,7 @@ describe("Emojis", function () {
                 preventDefault: function preventDefault () {},
                 keyCode: 13 // Enter
             });
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             message = view.content.querySelector('.message:last-child .chat-msg__text');
             expect(u.hasClass('chat-msg__text--larger', message)).toBe(true);

+ 3 - 3
spec/http-file-upload.js

@@ -247,7 +247,7 @@ describe("XEP-0363: HTTP File Upload", function () {
                         'name': "my-juliet.jpg"
                     };
                     view.model.sendFiles([file]);
-                    await new Promise(resolve => view.once('messageInserted', resolve));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
                     await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
                     const iq = IQ_stanzas.pop();
@@ -352,7 +352,7 @@ describe("XEP-0363: HTTP File Upload", function () {
                         'name': "my-juliet.jpg"
                     };
                     view.model.sendFiles([file]);
-                    await new Promise(resolve => view.once('messageInserted', resolve));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
                     await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
                     const iq = IQ_stanzas.pop();
@@ -575,7 +575,7 @@ describe("XEP-0363: HTTP File Upload", function () {
                     'name': "my-juliet.jpg"
                 };
                 view.model.sendFiles([file]);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length)
                 const iq = IQ_stanzas.pop();
                 expect(Strophe.serialize(iq)).toBe(

+ 1 - 1
spec/mam.js

@@ -253,7 +253,7 @@ describe("Message Archive Management", function () {
                             .c('count').t('16');
                 _converse.connection._dataRecv(mock.createRequest(iq_result));
 
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(view.model.messages.length).toBe(1);
                 expect(view.model.messages.at(0).get('message')).toBe("Thrice the brinded cat hath mew'd.");
                 done();

+ 41 - 41
spec/messages.js

@@ -69,7 +69,7 @@ describe("A Chat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
         expect(view.el.querySelector('.chat-msg__text').textContent)
@@ -153,7 +153,7 @@ describe("A Chat Message", function () {
             }).c('body').t('Hello').up()
             .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
         );
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg .chat-msg__action').length).toBe(2);
 
         // Test confirmation dialog
@@ -203,7 +203,7 @@ describe("A Chat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
         expect(view.el.querySelector('.chat-msg__text').textContent)
             .toBe('But soft, what light through yonder airlock breaks?');
@@ -279,7 +279,7 @@ describe("A Chat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
 
         textarea.value =  'Arise, fair sun, and kill the envious moon';
@@ -288,7 +288,7 @@ describe("A Chat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
 
         view.onKeyDown({
@@ -372,7 +372,7 @@ describe("A Chat Message", function () {
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':'2017-12-31T22:08:25Z'})
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         msg = $msg({
                 'xmlns': 'jabber:client',
@@ -384,7 +384,7 @@ describe("A Chat Message", function () {
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':'2018-01-01T13:18:23Z'})
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         msg = $msg({
                 'xmlns': 'jabber:client',
@@ -396,7 +396,7 @@ describe("A Chat Message", function () {
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':'2018-01-01T13:18:23Z'})
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         msg = $msg({
                 'xmlns': 'jabber:client',
@@ -408,7 +408,7 @@ describe("A Chat Message", function () {
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':'2018-01-02T12:18:23Z'})
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         msg = $msg({
                 'xmlns': 'jabber:client',
@@ -420,7 +420,7 @@ describe("A Chat Message", function () {
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':'2018-01-02T22:28:23Z'})
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         // Insert <composing> message, to also check that
         // text messages are inserted correctly with
@@ -434,7 +434,7 @@ describe("A Chat Message", function () {
             .c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
             .tree();
         _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         msg = $msg({
                 'id': _converse.connection.getUniqueId(),
@@ -446,7 +446,7 @@ describe("A Chat Message", function () {
             .c('body').t("latest message")
             .tree();
         await _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         view.clearSpinner(); //cleanup
         expect(view.content.querySelectorAll('.date-separator').length).toEqual(4);
@@ -766,7 +766,7 @@ describe("A Chat Message", function () {
         .c('delay', { xmlns:'urn:xmpp:delay', from: 'montague.lit', stamp: one_day_ago.toISOString() })
         .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
         await _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
         expect(chatbox.messages.length).toEqual(1);
@@ -798,7 +798,7 @@ describe("A Chat Message", function () {
         }).c('body').t(message).up()
         .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
         await _converse.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
         // Check that there is a <time> element, with the required props.
@@ -863,7 +863,7 @@ describe("A Chat Message", function () {
         spyOn(view.model, 'sendMessage').and.callThrough();
         mock.sendMessage(view, message);
         expect(view.model.sendMessage).toHaveBeenCalled();
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop();
         expect(msg.textContent).toEqual(message);
         expect(msg.innerHTML)
@@ -886,7 +886,7 @@ describe("A Chat Message", function () {
                 <body>Hey\nHave you heard the news?</body>
             </message>`);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.content.querySelector('.chat-msg__text').innerHTML).toBe('Hey<br>Have you heard the news?');
         stanza = u.toStanza(`
             <message from="${contact_jid}"
@@ -895,7 +895,7 @@ describe("A Chat Message", function () {
                 <body>Hey\n\n\nHave you heard the news?</body>
             </message>`);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br><br>Have you heard the news?');
         stanza = u.toStanza(`
             <message from="${contact_jid}"
@@ -904,7 +904,7 @@ describe("A Chat Message", function () {
                 <body>Hey\nHave you heard\nthe news?</body>
             </message>`);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.content.querySelector('.message:last-child .chat-msg__text').innerHTML).toBe('Hey<br>Have you heard<br>the news?');
         done();
     }));
@@ -1006,7 +1006,7 @@ describe("A Chat Message", function () {
             .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
         await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
         const view = _converse.api.chatviews.get(sender_jid);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         jasmine.clock().tick(3*ONE_MINUTE_LATER);
         _converse.handleMessageStanza($msg({
@@ -1016,7 +1016,7 @@ describe("A Chat Message", function () {
                 'id': u.getUniqueId()
             }).c('body').t("Another message 3 minutes later").up()
             .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         jasmine.clock().tick(11*ONE_MINUTE_LATER);
         _converse.handleMessageStanza($msg({
@@ -1026,7 +1026,7 @@ describe("A Chat Message", function () {
                 'id': u.getUniqueId()
             }).c('body').t("Another message 14 minutes since we started").up()
             .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         jasmine.clock().tick(1*ONE_MINUTE_LATER);
 
@@ -1037,7 +1037,7 @@ describe("A Chat Message", function () {
                 'id': _converse.connection.getUniqueId()
             }).c('body').t("Another message 1 minute and 1 second since the previous one").up()
             .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         jasmine.clock().tick(1*ONE_MINUTE_LATER);
         await mock.sendMessage(view, "Another message within 10 minutes, but from a different person");
@@ -1070,7 +1070,7 @@ describe("A Chat Message", function () {
             }).c('body').t("A delayed message, sent 5 minutes since we started").up()
               .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp': dayjs(base_time).add(5, 'minutes').toISOString()})
               .tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         expect(view.content.querySelectorAll('.message').length).toBe(7);
         expect(view.content.querySelectorAll('.chat-msg').length).toBe(6);
@@ -1101,7 +1101,7 @@ describe("A Chat Message", function () {
             .c('body').t("A carbon message 4 minutes later").up()
             .c('delay', {'xmlns': 'urn:xmpp:delay', 'stamp':dayjs(base_time).add(4, 'minutes').toISOString()})
             .tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         expect(view.content.querySelectorAll('.message').length).toBe(8);
         expect(view.content.querySelectorAll('.chat-msg').length).toBe(7);
@@ -1205,7 +1205,7 @@ describe("A Chat Message", function () {
             });
             const chatbox = _converse.chatboxes.get(contact_jid);
             expect(chatbox).toBeDefined();
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             let msg_obj = chatbox.messages.models[0];
             let msg_id = msg_obj.get('msgid');
             let msg = $msg({
@@ -1225,7 +1225,7 @@ describe("A Chat Message", function () {
                 preventDefault: function preventDefault () {},
                 keyCode: 13 // Enter
             });
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             msg_obj = chatbox.messages.models[1];
             msg_id = msg_obj.get('msgid');
@@ -1377,7 +1377,7 @@ describe("A Chat Message", function () {
                     'type': 'chat',
                     'id': msg_id,
                 }).c('body').t('But soft, what light through yonder airlock breaks?').tree());
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
             expect(view.el.querySelector('.chat-msg__text').textContent)
                 .toBe('But soft, what light through yonder airlock breaks?');
@@ -1456,7 +1456,7 @@ describe("A Chat Message", function () {
 
                 await _converse.handleMessageStanza(msg);
                 const view = await u.waitUntil(() => _converse.api.chatviews.get(sender_jid));
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
 
                 // Check that the chatbox and its view now exist
@@ -1508,7 +1508,7 @@ describe("A Chat Message", function () {
                 _converse.allow_non_roster_messaging = true;
                 await _converse.handleMessageStanza(msg);
                 view = _converse.chatboxviews.get(sender_jid);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
                 // Check that the chatbox and its view now exist
                 chatbox = await _converse.api.chats.get(sender_jid);
@@ -1563,7 +1563,7 @@ describe("A Chat Message", function () {
                 let msg_text = 'This message will not be sent, due to an error';
                 const view = _converse.api.chatviews.get(sender_jid);
                 const message = await view.model.sendMessage(msg_text);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 let msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
                 expect(msg_txt).toEqual(msg_text);
 
@@ -1598,7 +1598,7 @@ describe("A Chat Message", function () {
                     .c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
                         .t('Server-to-server connection failed: Connecting failed: connection timeout');
                 _converse.connection._dataRecv(mock.createRequest(stanza));
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(view.content.querySelector('.chat-error').textContent.trim()).toEqual(error_txt);
                 stanza = $msg({
                         'to': _converse.connection.jid,
@@ -1611,7 +1611,7 @@ describe("A Chat Message", function () {
                     .c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
                         .t('Server-to-server connection failed: Connecting failed: connection timeout');
                 _converse.connection._dataRecv(mock.createRequest(stanza));
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(view.content.querySelectorAll('.chat-error').length).toEqual(2);
 
                 // We don't render duplicates
@@ -1630,7 +1630,7 @@ describe("A Chat Message", function () {
 
                 msg_text = 'This message will be sent, and also receive an error';
                 const third_message = await view.model.sendMessage(msg_text);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
                 expect(msg_txt).toEqual(msg_text);
 
@@ -1647,7 +1647,7 @@ describe("A Chat Message", function () {
                         .t('Something else went wrong as well');
                 _converse.connection._dataRecv(mock.createRequest(stanza));
                 await u.waitUntil(() => view.model.messages.length > 3);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(view.content.querySelectorAll('.chat-error').length).toEqual(3);
                 done();
             }));
@@ -1709,7 +1709,7 @@ describe("A Chat Message", function () {
                         id: _converse.connection.getUniqueId(),
                     }).c('body').t('Message: '+i).up()
                     .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-                promises.push(new Promise(resolve => view.once('messageInserted', resolve)));
+                promises.push(new Promise(resolve => view.model.messages.once('rendered', resolve)));
             }
             await Promise.all(promises);
             // XXX Fails on Travis
@@ -1728,7 +1728,7 @@ describe("A Chat Message", function () {
                     id: u.getUniqueId()
                 }).c('body').t(message).up()
                 .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             await u.waitUntil(() => view.model.messages.length > 20, 1000);
             // Now check that the message appears inside the chatbox in the DOM
             const  msg_txt = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop().textContent;
@@ -1813,7 +1813,7 @@ describe("A Chat Message", function () {
                     <x xmlns="jabber:x:oob"><url>https://montague.lit/audio.mp3</url></x>
                 </message>`)
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
             let msg = view.el.querySelector('.chat-msg .chat-msg__text');
             expect(msg.classList.length).toEqual(1);
@@ -1833,7 +1833,7 @@ describe("A Chat Message", function () {
                     <x xmlns="jabber:x:oob"><url>https://montague.lit/audio.mp3</url></x>
                 </message>`);
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
             expect(msg.innerHTML).toEqual('<!-- message gets added here via renderMessage -->'); // Emtpy
             media = view.el.querySelector('.chat-msg:last-child .chat-msg__media');
@@ -1881,7 +1881,7 @@ describe("A Chat Message", function () {
                     <x xmlns="jabber:x:oob"><url>https://montague.lit/video.mp4</url></x>
                 </message>`);
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             msg = view.el.querySelector('.chat-msg:last-child .chat-msg__text');
             expect(msg.innerHTML).toEqual('<!-- message gets added here via renderMessage -->'); // Emtpy
             media = view.el.querySelector('.chat-msg:last-child .chat-msg__media');
@@ -1908,7 +1908,7 @@ describe("A Chat Message", function () {
                     <x xmlns="jabber:x:oob"><url>https://montague.lit/funny.pdf</url></x>
                 </message>`);
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
             const msg = view.el.querySelector('.chat-msg .chat-msg__text');
             expect(u.hasClass('chat-msg__text', msg)).toBe(true);
@@ -2048,7 +2048,7 @@ describe("A XEP-0333 Chat Marker", function () {
                 <stanza-id xmlns="urn:xmpp:sid:0" id="IxVDLJ0RYbWcWvqC" by="${_converse.bare_jid}"/>
             </message>`);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
         expect(view.model.messages.length).toBe(1);
 

+ 1 - 1
spec/mock.js

@@ -449,7 +449,7 @@ window.addEventListener('converse-loaded', () => {
     }
 
     mock.sendMessage = function (view, message) {
-        const promise = new Promise(resolve => view.once('messageInserted', resolve));
+        const promise = new Promise(resolve => view.model.messages.once('rendered', resolve));
         view.el.querySelector('.chat-textarea').value = message;
         view.onKeyDown({
             target: view.el.querySelector('textarea.chat-textarea'),

+ 10 - 10
spec/muc.js

@@ -527,7 +527,7 @@ describe("Groupchats", function () {
                         <body>This is a message</body>
                     </message>`);
                 _converse.connection._dataRecv(mock.createRequest(stanza));
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(sizzle('.chat-msg__subject', view.el).length).toBe(1);
                 expect(sizzle('.chat-msg__subject', view.el).pop().textContent.trim()).toBe('This is a message subject');
                 expect(sizzle('.chat-msg__text').length).toBe(1);
@@ -562,7 +562,7 @@ describe("Groupchats", function () {
                         <body>This is a message</body>
                     </message>`);
                 _converse.connection._dataRecv(mock.createRequest(stanza));
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 expect(sizzle('.chat-msg__subject', view.el).length).toBe(1);
                 expect(sizzle('.chat-msg__subject', view.el).pop().textContent.trim()).toBe('This is a message subject');
                 expect(sizzle('.chat-msg__text').length).toBe(1);
@@ -861,7 +861,7 @@ describe("Groupchats", function () {
                 'type': 'groupchat'
             }).c('body').t('hello world').tree();
             _converse.connection._dataRecv(mock.createRequest(msg));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             // Add another entrant, otherwise the above message will be
             // collapsed if "newguy" leaves immediately again
@@ -2042,7 +2042,7 @@ describe("Groupchats", function () {
                 preventDefault: function preventDefault () {},
                 keyCode: 13
             });
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             expect(_converse.api.trigger).toHaveBeenCalledWith('messageSend', jasmine.any(_converse.Message));
             expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
@@ -2102,7 +2102,7 @@ describe("Groupchats", function () {
                         type: 'groupchat',
                         id: u.getUniqueId(),
                     }).c('body').t(message).tree());
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
                 // Now check that the message appears inside the chatbox in the DOM
                 const msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
                 expect(msg_txt).toEqual(message);
@@ -5056,7 +5056,7 @@ describe("Groupchats", function () {
                     type: 'groupchat'
                 }).c('body').t('hello world').tree();
                 await view.model.handleMessageStanza(msg);
-                await new Promise(resolve => view.once('messageInserted', resolve));
+                await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
                 const messages = view.el.querySelectorAll('.message');
                 expect(messages.length).toBe(2);
@@ -5186,20 +5186,20 @@ describe("Groupchats", function () {
             const textarea = view.el.querySelector('.chat-textarea');
             textarea.value = 'Hello world';
             view.onFormSubmitted(new Event('submit'));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             let stanza = u.toStanza(`
                 <message xmlns="jabber:client" type="error" to="troll@montague.lit/resource" from="trollbox@montague.lit">
                     <error type="auth"><forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
                 </message>`);
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             expect(view.el.querySelector('.chat-error').textContent.trim()).toBe(
                 "Your message was not delivered because you weren't allowed to send it.");
 
             textarea.value = 'Hello again';
             view.onFormSubmitted(new Event('submit'));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             stanza = u.toStanza(`
                 <message xmlns="jabber:client" type="error" to="troll@montague.lit/resource" from="trollbox@montague.lit">
@@ -5209,7 +5209,7 @@ describe("Groupchats", function () {
                     </error>
                 </message>`);
             _converse.connection._dataRecv(mock.createRequest(stanza));
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             expect(view.el.querySelector('.message:last-child').textContent.trim()).toBe(
                 'Your message was not delivered because you weren\'t allowed to send it. '+

+ 12 - 12
spec/muc_messages.js

@@ -25,7 +25,7 @@ describe("A Groupchat Message", function () {
                 'keyCode': 13 // Enter
             }
             view.onKeyDown(enter_event);
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             const msg = view.model.messages.at(0);
             const err_msg_text = "Message rejected because you're sending messages too quickly";
@@ -180,7 +180,7 @@ describe("A Groupchat Message", function () {
               .c('active', {'xmlns': "http://jabber.org/protocol/chatstates"})
               .tree();
         await view.model.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelector('.chat-msg')).not.toBe(null);
         done();
     }));
@@ -203,7 +203,7 @@ describe("A Groupchat Message", function () {
                 type: 'groupchat'
             }).c('body').t(message).tree();
         await view.model.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(u.hasClass('mentioned', view.el.querySelector('.chat-msg'))).toBeTruthy();
         done();
     }));
@@ -435,7 +435,7 @@ describe("A Groupchat Message", function () {
             type: 'groupchat'
         }).c('body').t('Another message!').tree();
         await view.model.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.model.messages.last().occupant.get('affiliation')).toBe('member');
         expect(view.model.messages.last().occupant.get('role')).toBe('participant');
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
@@ -472,7 +472,7 @@ describe("A Groupchat Message", function () {
             type: 'groupchat'
         }).c('body').t('Message from someone not in the MUC right now').tree();
         await view.model.handleMessageStanza(msg);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.model.messages.last().occupant).toBeUndefined();
         // Check that there's a new "add" event handler, for when the occupant appears.
         expect(view.model.occupants._events.add.length).toBe(add_events+1);
@@ -688,7 +688,7 @@ describe("A Groupchat Message", function () {
             'to': 'romeo@montague.lit',
             'type': 'groupchat'
         }).c('body').t('Hello world').tree());
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
 
         // Test that pressing the down arrow cancels message correction
@@ -729,7 +729,7 @@ describe("A Groupchat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(0);
 
         const msg_obj = view.model.messages.at(0);
@@ -807,7 +807,7 @@ describe("A Groupchat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
 
         const msg_obj = view.model.messages.at(0);
@@ -841,7 +841,7 @@ describe("A Groupchat Message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13 // Enter
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
         expect(view.el.querySelector('.chat-msg .chat-msg__body').textContent.trim())
             .toBe("But soft, what light through yonder airlock breaks?");
@@ -1144,7 +1144,7 @@ describe("A Groupchat Message", function () {
             }
             spyOn(_converse.connection, 'send');
             view.onKeyDown(enter_event);
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             const msg = _converse.connection.send.calls.all()[0].args[0];
             expect(msg.toLocaleString())
                 .toBe(`<message from="romeo@montague.lit/orchard" id="${msg.nodeTree.getAttribute("id")}" `+
@@ -1191,7 +1191,7 @@ describe("A Groupchat Message", function () {
             }
             spyOn(_converse.connection, 'send');
             view.onKeyDown(enter_event);
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
             const msg = _converse.connection.send.calls.all()[0].args[0];
             expect(msg.toLocaleString())
                 .toBe(`<message from="romeo@montague.lit/orchard" id="${msg.nodeTree.getAttribute("id")}" `+
@@ -1269,7 +1269,7 @@ describe("A Groupchat Message", function () {
                 'keyCode': 13 // Enter
             }
             view.onKeyDown(enter_event);
-            await new Promise(resolve => view.once('messageInserted', resolve));
+            await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
             const msg = _converse.connection.send.calls.all()[0].args[0];
             expect(msg.toLocaleString())

+ 2 - 2
spec/notification.js

@@ -65,7 +65,7 @@ describe("Notifications", function () {
                             type: 'groupchat'
                         }).c('body').t(message).tree();
                     _converse.connection._dataRecv(mock.createRequest(msg));
-                    await new Promise(resolve => view.once('messageInserted', resolve));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
                     await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
                     expect(_converse.showMessageNotification).toHaveBeenCalled();
@@ -94,7 +94,7 @@ describe("Notifications", function () {
                     _converse.connection._dataRecv(mock.createRequest(stanza));
                     await u.waitUntil(() => _converse.chatboxviews.keys().length);
                     const view = _converse.chatboxviews.get('notify.example.com');
-                    await new Promise(resolve => view.once('messageInserted', resolve));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
                     expect(_converse.chatboxviews.keys().includes('notify.example.com')).toBeTruthy();
                     expect(_converse.showMessageNotification).toHaveBeenCalled();
                     done();

+ 3 - 3
spec/omemo.js

@@ -199,7 +199,7 @@ describe("The OMEMO module", function() {
                         .up().up()
                     .c('payload').t(obj.payload);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.model.messages.length).toBe(2);
         expect(view.el.querySelectorAll('.chat-msg__body')[1].textContent.trim())
             .toBe('This is an encrypted message from the contact');
@@ -218,7 +218,7 @@ describe("The OMEMO module", function() {
                     .up().up()
                 .c('payload').t(obj.payload);
         _converse.connection._dataRecv(mock.createRequest(stanza));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         await u.waitUntil(() => view.model.messages.length > 1);
         expect(view.model.messages.length).toBe(3);
         expect(view.el.querySelectorAll('.chat-msg__body')[2].textContent.trim())
@@ -435,7 +435,7 @@ describe("The OMEMO module", function() {
             </message>
         `);
         _converse.connection._dataRecv(mock.createRequest(carbon));
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         expect(view.model.messages.length).toBe(1);
         expect(view.el.querySelector('.chat-msg__body').textContent.trim())
             .toBe('This is an encrypted carbon message from another device of mine');

+ 3 - 3
spec/spoilers.js

@@ -32,7 +32,7 @@ describe("A spoiler message", function () {
         _converse.connection._dataRecv(mock.createRequest(msg));
         await new Promise(resolve => _converse.api.listen.once('chatBoxViewInitialized', resolve));
         const view = _converse.chatboxviews.get(sender_jid);
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
         await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
         expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Mercutio');
         const message_content = view.el.querySelector('.chat-msg__text');
@@ -118,7 +118,7 @@ describe("A spoiler message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         /* Test the XML stanza
             *
@@ -201,7 +201,7 @@ describe("A spoiler message", function () {
             preventDefault: function preventDefault () {},
             keyCode: 13
         });
-        await new Promise(resolve => view.once('messageInserted', resolve));
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
 
         /* Test the XML stanza
             *

+ 0 - 6
src/components/chat_content.js

@@ -76,12 +76,6 @@ class ChatContent extends CustomElement {
                 is_retracted,
                 model,
             }));
-
-        if (model.collection) {
-            // If the model gets destroyed in the meantime, it no
-            // longer has a collection.
-            model.collection.trigger('rendered', this);
-        }
         return [...templates, message];
     }