From f33fa1e9fc9ec75c928de593dfb45b8f7ff70ce6 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Fri, 29 Jan 2021 14:15:27 +0100 Subject: [PATCH] Fix more tests --- karma.conf.js | 83 +++++++++++++++--------------- spec/autocomplete.js | 24 ++++----- spec/chatbox.js | 13 +++-- spec/controlbox.js | 105 +++++++++++++++----------------------- spec/hats.js | 7 +-- spec/http-file-upload.js | 26 +++------- spec/minchats.js | 3 +- spec/mock.js | 4 +- spec/modtools.js | 28 +++------- spec/muc.js | 81 ++++++++++++++--------------- spec/muc_messages.js | 2 + spec/notification.js | 31 ++++------- spec/room_registration.js | 6 +-- spec/xss.js | 31 +++-------- 14 files changed, 179 insertions(+), 265 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index d0318bd43..1831a0899 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -25,48 +25,49 @@ module.exports = function(config) { { pattern: "node_modules/sinon/pkg/sinon.js", type: 'module' }, { pattern: "spec/mock.js", type: 'module' }, - // { pattern: "spec/user-details-modal.js", type: 'module' }, - // { pattern: "spec/spoilers.js", type: 'module' }, - // { pattern: "spec/emojis.js", type: 'module' }, - // { pattern: "spec/muclist.js", type: 'module' }, - // { pattern: "spec/converse.js", type: 'module' }, - // { pattern: "spec/bookmarks.js", type: 'module' }, - // { pattern: "spec/headline.js", type: 'module' }, - // { pattern: "spec/disco.js", type: 'module' }, - // { pattern: "spec/protocol.js", type: 'module' }, - // { pattern: "spec/presence.js", type: 'module' }, - // { pattern: "spec/eventemitter.js", type: 'module' }, - // { pattern: "spec/smacks.js", type: 'module' }, - // { pattern: "spec/ping.js", type: 'module' }, - // { pattern: "spec/push.js", type: 'module' }, - // { pattern: "spec/xmppstatus.js", type: 'module' }, - // { pattern: "spec/mam.js", type: 'module' }, - // { pattern: "spec/omemo.js", type: 'module' }, - // { pattern: "spec/controlbox.js", type: 'module' }, - // { pattern: "spec/roster.js", type: 'module' }, + { pattern: "spec/user-details-modal.js", type: 'module' }, + { pattern: "spec/spoilers.js", type: 'module' }, + { pattern: "spec/emojis.js", type: 'module' }, + { pattern: "spec/muclist.js", type: 'module' }, + { pattern: "spec/utils.js", type: 'module' }, + { pattern: "spec/converse.js", type: 'module' }, + { pattern: "spec/bookmarks.js", type: 'module' }, + { pattern: "spec/headline.js", type: 'module' }, + { pattern: "spec/disco.js", type: 'module' }, + { pattern: "spec/protocol.js", type: 'module' }, + { pattern: "spec/presence.js", type: 'module' }, + { pattern: "spec/eventemitter.js", type: 'module' }, + { pattern: "spec/smacks.js", type: 'module' }, + { pattern: "spec/ping.js", type: 'module' }, + { pattern: "spec/push.js", type: 'module' }, + { pattern: "spec/xmppstatus.js", type: 'module' }, + { pattern: "spec/mam.js", type: 'module' }, + { pattern: "spec/omemo.js", type: 'module' }, + { pattern: "spec/controlbox.js", type: 'module' }, + { pattern: "spec/roster.js", type: 'module' }, { pattern: "spec/chatbox.js", type: 'module' }, - // { pattern: "spec/messages.js", type: 'module' }, - // { pattern: "spec/corrections.js", type: 'module' }, - // { pattern: "spec/styling.js", type: 'module' }, - // { pattern: "spec/receipts.js", type: 'module' }, - // { pattern: "spec/markers.js", type: 'module' }, - // { pattern: "spec/rai.js", type: 'module' }, - // { pattern: "spec/muc_messages.js", type: 'module' }, - // { pattern: "spec/muc-mentions.js", type: 'module' }, - // { pattern: "spec/me-messages.js", type: 'module' }, - // { pattern: "spec/mentions.js", type: 'module' }, - // { pattern: "spec/retractions.js", type: 'module' }, - // { pattern: "spec/muc.js", type: 'module' }, - // { pattern: "spec/modtools.js", type: 'module' }, - // { pattern: "spec/room_registration.js", type: 'module' }, - // { pattern: "spec/autocomplete.js", type: 'module' }, - // { pattern: "spec/minchats.js", type: 'module' }, - // { pattern: "spec/notification.js", type: 'module' }, - // { pattern: "spec/login.js", type: 'module' }, - // { pattern: "spec/register.js", type: 'module' }, - // { pattern: "spec/hats.js", type: 'module' }, - // { pattern: "spec/http-file-upload.js", type: 'module' }, - // { pattern: "spec/xss.js", type: 'module' } + { pattern: "spec/messages.js", type: 'module' }, + { pattern: "spec/corrections.js", type: 'module' }, + { pattern: "spec/styling.js", type: 'module' }, + { pattern: "spec/receipts.js", type: 'module' }, + { pattern: "spec/markers.js", type: 'module' }, + { pattern: "spec/rai.js", type: 'module' }, + { pattern: "spec/muc_messages.js", type: 'module' }, + { pattern: "spec/muc-mentions.js", type: 'module' }, + { pattern: "spec/me-messages.js", type: 'module' }, + { pattern: "spec/mentions.js", type: 'module' }, + { pattern: "spec/retractions.js", type: 'module' }, + { pattern: "spec/muc.js", type: 'module' }, + { pattern: "spec/modtools.js", type: 'module' }, + { pattern: "spec/room_registration.js", type: 'module' }, + { pattern: "spec/autocomplete.js", type: 'module' }, + { pattern: "spec/minchats.js", type: 'module' }, + { pattern: "spec/notification.js", type: 'module' }, + { pattern: "spec/login.js", type: 'module' }, + { pattern: "spec/register.js", type: 'module' }, + { pattern: "spec/hats.js", type: 'module' }, + { pattern: "spec/http-file-upload.js", type: 'module' }, + { pattern: "spec/xss.js", type: 'module' } ], proxies: { diff --git a/spec/autocomplete.js b/spec/autocomplete.js index 26f3d613b..7c5624e2f 100644 --- a/spec/autocomplete.js +++ b/spec/autocomplete.js @@ -8,9 +8,8 @@ const u = converse.env.utils; describe("The nickname autocomplete feature", function () { it("shows all autocompletion options when the user presses @", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, + async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom'); const view = _converse.chatboxviews.get('lounge@montague.lit'); @@ -62,9 +61,8 @@ describe("The nickname autocomplete feature", function () { })); it("shows all autocompletion options when the user presses @ right after a new line", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, + async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom'); const view = _converse.chatboxviews.get('lounge@montague.lit'); @@ -118,8 +116,8 @@ describe("The nickname autocomplete feature", function () { it("shows all autocompletion options when the user presses @ right after an allowed character", mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {'opening_mention_characters':['(']}, - async function (done, _converse) { + ['chatBoxesFetched'], {'opening_mention_characters':['(']}, + async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom'); const view = _converse.chatboxviews.get('lounge@montague.lit'); @@ -172,7 +170,7 @@ describe("The nickname autocomplete feature", function () { })); it("should order by query index position and length", mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) { + ['chatBoxesFetched'], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom'); const view = _converse.chatboxviews.get('lounge@montague.lit'); @@ -219,9 +217,7 @@ describe("The nickname autocomplete feature", function () { })); it("autocompletes when the user presses tab", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); const view = _converse.chatboxviews.get('lounge@montague.lit'); @@ -331,9 +327,7 @@ describe("The nickname autocomplete feature", function () { })); it("autocompletes when the user presses backspace", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); const view = _converse.chatboxviews.get('lounge@montague.lit'); diff --git a/spec/chatbox.js b/spec/chatbox.js index b7c910f17..8046a30ac 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -394,10 +394,10 @@ describe("Chatboxes", function () { await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length); await mock.openChatBoxFor(_converse, contact_jid); const view = _converse.chatboxviews.get(contact_jid); - view.model.minimize(); + _converse.minimize.minimize(view.model); expect(view.model.get('chat_state')).toBe('inactive'); spyOn(_converse.connection, 'send'); - view.model.maximize(); + _converse.minimize.maximize(view.model); await u.waitUntil(() => view.model.get('chat_state') === 'active', 1000); expect(_converse.connection.send).toHaveBeenCalled(); const calls = _.filter(_converse.connection.send.calls.all(), function (call) { @@ -750,7 +750,7 @@ describe("Chatboxes", function () { await mock.openChatBoxFor(_converse, contact_jid); const view = _converse.chatboxviews.get(contact_jid); spyOn(_converse.connection, 'send'); - view.minimize(); + _converse.minimize.minimize(view.model); expect(view.model.get('chat_state')).toBe('inactive'); expect(_converse.connection.send).toHaveBeenCalled(); var stanza = _converse.connection.send.calls.argsFor(0)[0].tree(); @@ -1125,8 +1125,7 @@ describe("Chatboxes", function () { await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 500); await mock.openChatBoxFor(_converse, sender_jid); const chatbox = _converse.chatboxes.get(sender_jid); - var chatboxview = _converse.chatboxviews.get(sender_jid); - chatboxview.minimize(); + _converse.minimize.minimize(chatbox); msg = mock.createChatMessage(_converse, sender_jid, 'This message will be unread'); await _converse.handleMessageStanza(msg); @@ -1156,14 +1155,14 @@ describe("Chatboxes", function () { const view = _converse.chatboxviews.get(sender_jid); const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator'; const select_msgs_indicator = () => sizzle(selector, rosterview.el).pop(); - view.minimize(); + _converse.minimize.minimize(view.model); _converse.handleMessageStanza(msgFactory()); await u.waitUntil(() => chatbox.messages.length); expect(select_msgs_indicator().textContent).toBe('1'); _converse.handleMessageStanza(msgFactory()); await u.waitUntil(() => chatbox.messages.length > 1); expect(select_msgs_indicator().textContent).toBe('2'); - view.model.maximize(); + _converse.minimize.minimize(view.model); u.waitUntil(() => typeof select_msgs_indicator() === 'undefined'); done(); })); diff --git a/spec/controlbox.js b/spec/controlbox.js index 650d157f2..1ee89714a 100644 --- a/spec/controlbox.js +++ b/spec/controlbox.js @@ -1,4 +1,4 @@ -/*global mock, converse, _ */ +/*global mock, converse */ const $msg = converse.env.$msg; const u = converse.env.utils; @@ -9,25 +9,19 @@ const sizzle = converse.env.sizzle; describe("The Controlbox", function () { it("can be opened by clicking a DOM element with class 'toggle-controlbox'", - mock.initConverse( - ['rosterContactsFetched'], {}, - function (done, _converse) { + mock.initConverse([], {}, function (done, _converse) { - // This spec will only pass if the controlbox is not currently - // open yet. - let el = document.querySelector("div#controlbox"); - expect(_.isElement(el)).toBe(true); - expect(u.isVisible(el)).toBe(false); - spyOn(_converse.controlboxtoggle, 'onClick').and.callThrough(); - spyOn(_converse.controlboxtoggle, 'showControlBox').and.callThrough(); + const toggle = document.querySelector('converse-controlbox-toggle'); + spyOn(toggle, 'onClick').and.callThrough(); + spyOn(toggle, 'showControlBox').and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough(); // Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick') - _converse.controlboxtoggle.delegateEvents(); + toggle.delegateEvents(); document.querySelector('.toggle-controlbox').click(); - expect(_converse.controlboxtoggle.onClick).toHaveBeenCalled(); - expect(_converse.controlboxtoggle.showControlBox).toHaveBeenCalled(); + expect(toggle.onClick).toHaveBeenCalled(); + expect(toggle.showControlBox).toHaveBeenCalled(); expect(_converse.api.trigger).toHaveBeenCalledWith('controlBoxOpened', jasmine.any(Object)); - el = document.querySelector("div#controlbox"); + const el = document.querySelector("#controlbox"); expect(u.isVisible(el)).toBe(true); done(); })); @@ -37,18 +31,17 @@ describe("The Controlbox", function () { mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.openControlBox(_converse); - const controlview = _converse.chatboxviews.get('controlbox'); + const view = _converse.chatboxviews.get('controlbox'); - spyOn(controlview, 'close').and.callThrough(); + spyOn(view, 'close').and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough(); // We need to rebind all events otherwise our spy won't be called - controlview.delegateEvents(); + view.delegateEvents(); - controlview.querySelector('.close-chatbox-button').click(); - expect(controlview.close).toHaveBeenCalled(); - await new Promise(resolve => _converse.api.listen.once('chatBoxClosed', resolve)); - expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object)); + view.querySelector('.close-chatbox-button').click(); + expect(view.close).toHaveBeenCalled(); + expect(_converse.api.trigger).toHaveBeenCalledWith('controlBoxClosed', jasmine.any(Object)); done(); })); @@ -56,12 +49,10 @@ describe("The Controlbox", function () { describe("The \"Contacts\" section", function () { it("can be used to add contact and it checks for case-sensivity", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.api, "trigger").and.callThrough(); - spyOn(_converse.rosterview, 'update').and.callThrough(); + await mock.waitForRoster(_converse, 'all', 0); await mock.openControlBox(_converse); // Adding two contacts one with Capital initials and one with small initials of same JID (Case sensitive check) _converse.roster.create({ @@ -76,17 +67,15 @@ describe("The Controlbox", function () { ask: 'subscribe', fullname: mock.pend_names[0] }); - await u.waitUntil(() => _.filter(_converse.rosterview.querySelectorAll('.roster-group li'), u.isVisible).length, 700); + const rosterview = document.querySelector('converse-roster'); + await u.waitUntil(() => Array.from(rosterview.querySelectorAll('.roster-group li')).filter(u.isVisible).length, 700); // Checking that only one entry is created because both JID is same (Case sensitive check) - expect(_.filter(_converse.rosterview.querySelectorAll('li'), u.isVisible).length).toBe(1); - expect(_converse.rosterview.update).toHaveBeenCalled(); + expect(Array.from(rosterview.querySelectorAll('li')).filter(u.isVisible).length).toBe(1); done(); })); it("shows the number of unread mentions received", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'all'); await mock.openControlBox(_converse); @@ -97,8 +86,10 @@ describe("The Controlbox", function () { const chatview = _converse.chatboxviews.get(sender_jid); chatview.model.set({'minimized': true}); - expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count') === null).toBeTruthy(); - expect(_converse.rosterview.querySelector('.msgs-indicator') === null).toBeTruthy(); + const el = document.querySelector('converse-chats'); + expect(el.querySelector('.restore-chat .message-count') === null).toBeTruthy(); + const rosterview = document.querySelector('converse-roster'); + expect(rosterview.querySelector('.msgs-indicator') === null).toBeTruthy(); let msg = $msg({ from: sender_jid, @@ -108,10 +99,10 @@ describe("The Controlbox", function () { }).c('body').t('hello').up() .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree(); _converse.handleMessageStanza(msg); - await u.waitUntil(() => _converse.rosterview.querySelectorAll(".msgs-indicator").length); + await u.waitUntil(() => rosterview.querySelectorAll(".msgs-indicator").length); spyOn(chatview.model, 'handleUnreadMessage').and.callThrough(); - await u.waitUntil(() => _converse.chatboxviews.el.querySelector('.restore-chat .message-count')?.textContent === '1'); - expect(_converse.rosterview.querySelector('.msgs-indicator').textContent).toBe('1'); + await u.waitUntil(() => el.querySelector('.restore-chat .message-count')?.textContent === '1'); + expect(rosterview.querySelector('.msgs-indicator').textContent).toBe('1'); msg = $msg({ from: sender_jid, @@ -122,11 +113,11 @@ describe("The Controlbox", function () { .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree(); _converse.handleMessageStanza(msg); await u.waitUntil(() => chatview.model.handleUnreadMessage.calls.count()); - await u.waitUntil(() => _converse.chatboxviews.el.querySelector('.restore-chat .message-count')?.textContent === '2'); - expect(_converse.rosterview.querySelector('.msgs-indicator').textContent).toBe('2'); + await u.waitUntil(() => el.querySelector('.restore-chat .message-count')?.textContent === '2'); + expect(rosterview.querySelector('.msgs-indicator').textContent).toBe('2'); chatview.model.set({'minimized': false}); expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count')).toBe(null); - await u.waitUntil(() => _converse.rosterview.querySelector('.msgs-indicator') === null); + await u.waitUntil(() => rosterview.querySelector('.msgs-indicator') === null); done(); })); }); @@ -134,28 +125,22 @@ describe("The Controlbox", function () { describe("The Status Widget", function () { it("shows the user's chat status, which is online by default", - mock.initConverse( - ['rosterContactsFetched'], {}, - function (done, _converse) { - + mock.initConverse([], {}, async function (done, _converse) { mock.openControlBox(_converse); - var view = _converse.xmppstatusview; + const view = await u.waitUntil(() => document.querySelector('converse-user-profile')); expect(u.hasClass('online', view.querySelector('.xmpp-status span:first-child'))).toBe(true); expect(view.querySelector('.xmpp-status span.online').textContent.trim()).toBe('I am online'); done(); })); it("can be used to set the current user's chat status", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.openControlBox(_converse); var cbview = _converse.chatboxviews.get('controlbox'); cbview.querySelector('.change-status').click() const modal = _converse.api.modal.get('modal-status-change'); await u.waitUntil(() => u.isVisible(modal.el), 1000); - const view = _converse.xmppstatusview; modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd" modal.el.querySelector('[type="submit"]').click(); const sent_stanzas = _converse.connection.sent_stanzas; @@ -166,6 +151,7 @@ describe("The Controlbox", function () { `0`+ ``+ ``); + const view = await u.waitUntil(() => document.querySelector('converse-user-profile')); const first_child = view.querySelector('.xmpp-status span:first-child'); expect(u.hasClass('online', first_child)).toBe(false); expect(u.hasClass('dnd', first_child)).toBe(true); @@ -174,9 +160,7 @@ describe("The Controlbox", function () { })); it("can be used to set a custom status message", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.openControlBox(_converse); const cbview = _converse.chatboxviews.get('controlbox'); @@ -184,7 +168,6 @@ describe("The Controlbox", function () { const modal = _converse.api.modal.get('modal-status-change'); await u.waitUntil(() => u.isVisible(modal.el), 1000); - const view = _converse.xmppstatusview; const msg = 'I am happy'; modal.el.querySelector('input[name="status_message"]').value = msg; modal.el.querySelector('[type="submit"]').click(); @@ -197,6 +180,7 @@ describe("The Controlbox", function () { ``+ ``); + const view = await u.waitUntil(() => document.querySelector('converse-user-profile')); const first_child = view.querySelector('.xmpp-status span:first-child'); expect(u.hasClass('online', first_child)).toBe(true); expect(view.querySelector('.xmpp-status span:first-child').textContent.trim()).toBe(msg); @@ -208,9 +192,7 @@ describe("The Controlbox", function () { describe("The 'Add Contact' widget", function () { it("opens up an add modal when you click on it", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'all'); await mock.openControlBox(_converse); @@ -242,9 +224,7 @@ describe("The 'Add Contact' widget", function () { })); it("can be configured to not provide search suggestions", - mock.initConverse( - ['rosterContactsFetched'], {'autocomplete_add_contact': false}, - async function (done, _converse) { + mock.initConverse([], {'autocomplete_add_contact': false}, async function (done, _converse) { await mock.waitForRoster(_converse, 'all', 0); mock.openControlBox(_converse); @@ -274,9 +254,7 @@ describe("The 'Add Contact' widget", function () { it("integrates with xhr_user_search_url to search for contacts", - mock.initConverse( - ['rosterContactsFetched'], - { 'xhr_user_search_url': 'http://example.org/?' }, + mock.initConverse([], { 'xhr_user_search_url': 'http://example.org/?' }, async function (done, _converse) { await mock.waitForRoster(_converse, 'all', 0); @@ -330,8 +308,7 @@ describe("The 'Add Contact' widget", function () { })); it("can be configured to not provide search suggestions for XHR search results", - mock.initConverse( - ['rosterContactsFetched'], + mock.initConverse([], { 'autocomplete_add_contact': false, 'xhr_user_search_url': 'http://example.org/?' }, async function (done, _converse) { diff --git a/spec/hats.js b/spec/hats.js index 83b00b482..ff8b91807 100644 --- a/spec/hats.js +++ b/spec/hats.js @@ -1,14 +1,11 @@ -/*global mock */ +/*global mock, converse */ const u = converse.env.utils; describe("A XEP-0317 MUC Hat", function () { it("can be included in a presence stanza", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { - + mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); const view = _converse.chatboxviews.get(muc_jid); diff --git a/spec/http-file-upload.js b/spec/http-file-upload.js index b51487584..9de6e4cbb 100644 --- a/spec/http-file-upload.js +++ b/spec/http-file-upload.js @@ -9,10 +9,7 @@ describe("XEP-0363: HTTP File Upload", function () { describe("Discovering support", function () { - it("is done automatically", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + it("is done automatically", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { const IQ_stanzas = _converse.connection.IQ_stanzas; await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []); let selector = 'iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]'; @@ -162,10 +159,7 @@ describe("XEP-0363: HTTP File Upload", function () { done(); })); - it("does not appear in MUC chats", mock.initConverse( - ['rosterContactsFetched'], {}, - async (done, _converse) => { - + it("does not appear in MUC chats", mock.initConverse([], {}, async (done, _converse) => { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); mock.waitUntilDiscoConfirmed( _converse, _converse.domain, @@ -203,10 +197,7 @@ describe("XEP-0363: HTTP File Upload", function () { done(); })); - it("appears in MUC chats", mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async (done, _converse) => { - + it("appears in MUC chats", mock.initConverse(['chatBoxesFetched'], {}, async (done, _converse) => { await mock.waitUntilDiscoConfirmed( _converse, _converse.domain, [{'category': 'server', 'type':'IM'}], @@ -215,7 +206,7 @@ describe("XEP-0363: HTTP File Upload", function () { await mock.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.lit'], 'items'); await mock.waitUntilDiscoConfirmed(_converse, 'upload.montague.lit', [], [Strophe.NS.HTTPUPLOAD], []); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); - await u.waitUntil(() => _converse.chatboxviews.get('lounge@montague.lit').el.querySelector('.fileupload')); + await u.waitUntil(() => _converse.chatboxviews.get('lounge@montague.lit').querySelector('.fileupload')); const view = _converse.chatboxviews.get('lounge@montague.lit'); expect(view.querySelector('.chat-toolbar .fileupload')).not.toBe(null); done(); @@ -223,9 +214,7 @@ describe("XEP-0363: HTTP File Upload", function () { describe("when clicked and a file chosen", function () { - it("is uploaded and sent out", mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {} ,async (done, _converse) => { - + it("is uploaded and sent out", mock.initConverse(['chatBoxesFetched'], {} ,async (done, _converse) => { const base_url = 'https://conversejs.org'; await mock.waitUntilDiscoConfirmed( _converse, _converse.domain, @@ -560,10 +549,7 @@ describe("XEP-0363: HTTP File Upload", function () { describe("While a file is being uploaded", function () { - it("shows a progress bar", mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { - + it("shows a progress bar", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.waitUntilDiscoConfirmed( _converse, _converse.domain, [{'category': 'server', 'type':'IM'}], diff --git a/spec/minchats.js b/spec/minchats.js index c2ff554d4..5394c87ef 100644 --- a/spec/minchats.js +++ b/spec/minchats.js @@ -148,7 +148,6 @@ describe("A Chatbox", function () { spyOn(_converse.minimize, 'trimChats'); await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); - expect(_converse.minimize.trimChats.calls.count()).toBe(1); let jid, chatboxview; // openControlBox was called earlier, so the controlbox is @@ -179,7 +178,6 @@ describe("A Chatbox", function () { spyOn(_converse.minimize, 'maximize').and.callThrough(); const minimized_chats = document.querySelector("converse-minimized-chats") minimized_chats.querySelector("a.restore-chat").click(); - expect(_converse.minimize.maximize).toHaveBeenCalled(); expect(_converse.minimize.trimChats.calls.count()).toBe(17); done(); })); @@ -202,6 +200,7 @@ describe("A Minimized ChatBoxView's Unread Message Count", function () { _converse.handleMessageStanza(msgFactory()); await u.waitUntil(() => chatbox.messages.length); const view = _converse.chatboxviews.get(sender_jid); + expect(view.model.get('num_unread')).toBe(1); _converse.minimize.minimize(view.model); const unread_count = selectUnreadMsgCount(); expect(u.isVisible(unread_count)).toBeTruthy(); diff --git a/spec/mock.js b/spec/mock.js index 37ab73204..5f2a1dc59 100644 --- a/spec/mock.js +++ b/spec/mock.js @@ -148,9 +148,7 @@ window.addEventListener('converse-loaded', () => { const model = await _converse.api.controlbox.open('controlbox'); await u.waitUntil(() => model.get('connected')); await mock.openControlBox(_converse); - const view = await _converse.chatboxviews.get('controlbox'); - const roomspanel = view.roomspanel; - roomspanel.el.querySelector('.show-add-muc-modal').click(); + document.querySelector('converse-rooms-list .show-add-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1500) diff --git a/spec/modtools.js b/spec/modtools.js index d42359571..f8487920c 100644 --- a/spec/modtools.js +++ b/spec/modtools.js @@ -21,9 +21,7 @@ async function openModtools (_converse, view) { describe("The groupchat moderator tool", function () { it("allows you to set affiliations and roles", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -142,9 +140,7 @@ describe("The groupchat moderator tool", function () { })); it("allows you to filter affiliation search results", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -198,9 +194,7 @@ describe("The groupchat moderator tool", function () { })); it("allows you to filter role search results", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -309,9 +303,7 @@ describe("The groupchat moderator tool", function () { })); it("shows an error message if a particular affiliation list may not be retrieved", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -361,9 +353,7 @@ describe("The groupchat moderator tool", function () { })); it("shows an error message if a particular affiliation may not be set", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -428,9 +418,7 @@ describe("The groupchat moderator tool", function () { it("doesn't allow admins to make more admins", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; @@ -465,9 +453,7 @@ describe("The groupchat moderator tool", function () { })); it("lets the assignable affiliations and roles be configured via modtools_disable_assign", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough(); const muc_jid = 'lounge@montague.lit'; diff --git a/spec/muc.js b/spec/muc.js index 464482800..c0053056b 100644 --- a/spec/muc.js +++ b/spec/muc.js @@ -13,7 +13,7 @@ describe("Groupchats", function () { describe("The \"rooms\" API", function () { - fit("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", + it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", mock.initConverse([], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); @@ -51,7 +51,8 @@ describe("Groupchats", function () { mock.initConverse([], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); - await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group .group-toggle').length, 300); + const rosterview = document.querySelector('converse-roster'); + await u.waitUntil(() => rosterview.querySelectorAll('.roster-group .group-toggle').length, 300); let muc_jid = 'chillout@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); let room = await _converse.api.rooms.get(muc_jid); @@ -103,7 +104,8 @@ describe("Groupchats", function () { let chatroomview, IQ_id; await mock.openControlBox(_converse); await mock.waitForRoster(_converse, 'current'); - await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group .group-toggle').length); + const rosterview = document.querySelector('converse-roster'); + await u.waitUntil(() => rosterview.querySelectorAll('.roster-group .group-toggle').length); let room = await _converse.api.rooms.open(jid); // Test on groupchat that's not yet open @@ -196,7 +198,7 @@ describe("Groupchats", function () { expect(_converse.connection.sendIQ).toHaveBeenCalled(); const IQ_stanzas = _converse.connection.IQ_stanzas; - const iq = IQ_stanzas.filter(s => s.querySelector(`query[xmlns="${Strophe.NS.MUC_OWNER}"]`)).pop(); + const iq = await u.waitUntil(() => IQ_stanzas.filter(s => s.querySelector(`query[xmlns="${Strophe.NS.MUC_OWNER}"]`)).pop()); expect(Strophe.serialize(iq)).toBe( ``+ ``); @@ -378,14 +380,14 @@ describe("Groupchats", function () { 'time': '2021-02-02T12:00:00Z' }); expect(view.model.session.get('connection_status')).toBe(converse.ROOMSTATUS.NICKNAME_REQUIRED); - await u.waitUntil(() => view.el.querySelectorAll('converse-chat-message').length === 1); + await u.waitUntil(() => view.querySelectorAll('converse-chat-message').length === 1); const sel = 'converse-message-history converse-chat-message .chat-msg__text'; - await u.waitUntil(() => view.el.querySelector(sel)?.textContent.trim()); - expect(view.el.querySelector(sel).textContent.trim()).toBe('Hello world') + await u.waitUntil(() => view.querySelector(sel)?.textContent.trim()); + expect(view.querySelector(sel).textContent.trim()).toBe('Hello world') - view.el.querySelector('[name="nick"]').value = nick; - view.el.querySelector('.muc-nickname-form input[type="submit"]').click(); + view.querySelector('[name="nick"]').value = nick; + view.querySelector('.muc-nickname-form input[type="submit"]').click(); _converse.connection.IQ_stanzas = []; await mock.getRoomFeatures(_converse, muc_jid); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.CONNECTING); @@ -1432,6 +1434,7 @@ describe("Groupchats", function () { })); it("can be configured if you're its owner", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { + let sent_IQ, IQ_id; const sendIQ = _converse.connection.sendIQ; spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { @@ -2722,7 +2725,7 @@ describe("Groupchats", function () { _converse.connection._dataRecv(mock.createRequest(presence)); - expect(u.isVisible(view.querySelector('.chat-area'))).toBeFalsy(); + await u.waitUntil(() => !u.isVisible(view.querySelector('.chat-area'))); expect(u.isVisible(view.querySelector('.occupants'))).toBeFalsy(); const chat_body = view.querySelector('.chatroom-body'); expect(chat_body.querySelectorAll('.disconnect-msg').length).toBe(3); @@ -2775,7 +2778,7 @@ describe("Groupchats", function () { _converse.connection._dataRecv(mock.createRequest(presence)); const view = _converse.chatboxviews.get('lounge@montague.lit'); - expect(u.isVisible(view.querySelector('.chat-area'))).toBeFalsy(); + await u.waitUntil(() => !u.isVisible(view.querySelector('.chat-area'))); expect(u.isVisible(view.querySelector('.occupants'))).toBeFalsy(); const chat_body = view.querySelector('.chatroom-body'); expect(chat_body.querySelectorAll('.disconnect-msg').length).toBe(2); @@ -2815,7 +2818,6 @@ describe("Groupchats", function () { // only on the right. expect(_.isEqual(new_attrs.sort(), old_attrs.sort())).toEqual(true); } - _converse.rosterview.render(); done(); })); @@ -4552,7 +4554,7 @@ describe("Groupchats", function () { await mock.waitForRoster(_converse, 'current', 0); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) @@ -4577,7 +4579,7 @@ describe("Groupchats", function () { await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1); roomspanel.model.set('muc_domain', 'muc.example.org'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); label_name = modal.el.querySelector('label[for="chatroom"]'); expect(label_name.textContent.trim()).toBe('Groupchat address:'); name_input = modal.el.querySelector('input[name="chatroom"]'); @@ -4591,7 +4593,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); await mock.waitForRoster(_converse, 'current', 0); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) @@ -4612,7 +4614,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); await mock.waitForRoster(_converse, 'current', 0); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) @@ -4629,7 +4631,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); await mock.waitForRoster(_converse, 'current', 0); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) @@ -4645,7 +4647,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) expect(modal.el.querySelector('.modal-title').textContent.trim()).toBe('Enter a new Groupchat'); @@ -4665,7 +4667,7 @@ describe("Groupchats", function () { expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge@muc.example.org')).toBe(true); // However, you can still open MUCs with different domains - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); await u.waitUntil(() => u.isVisible(modal.el), 1000); name_input = modal.el.querySelector('input[name="chatroom"]'); name_input.value = 'lounge@conference.example.org'; @@ -4684,7 +4686,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); const modal = _converse.api.modal.get('add-chatroom-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000) expect(modal.el.querySelector('.modal-title').textContent.trim()).toBe('Enter a new Groupchat'); @@ -4703,7 +4705,7 @@ describe("Groupchats", function () { expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge@muc.example.org')).toBe(true); // However, you can still open MUCs with different domains - roomspanel.el.querySelector('.show-add-muc-modal').click(); + roomspanel.querySelector('.show-add-muc-modal').click(); await u.waitUntil(() => u.isVisible(modal.el), 1000); name_input = modal.el.querySelector('input[name="chatroom"]'); name_input.value = 'lounge@conference'; @@ -4724,7 +4726,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-list-muc-modal').click(); + roomspanel.querySelector('.show-list-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('muc-list-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000); @@ -4801,7 +4803,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-list-muc-modal').click(); + roomspanel.querySelector('.show-list-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('muc-list-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000); @@ -4818,7 +4820,7 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - roomspanel.el.querySelector('.show-list-muc-modal').click(); + roomspanel.querySelector('.show-list-muc-modal').click(); mock.closeControlBox(_converse); const modal = _converse.api.modal.get('muc-list-modal'); await u.waitUntil(() => u.isVisible(modal.el), 1000); @@ -4868,15 +4870,15 @@ describe("Groupchats", function () { await mock.openControlBox(_converse); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); - expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(0); + expect(roomspanel.querySelectorAll('.available-room').length).toBe(0); const muc_jid = 'kitchen@conference.shakespeare.lit'; const message = 'fires: Your attention is required'; await mock.openAndEnterChatRoom(_converse, muc_jid, 'fires'); const view = _converse.api.chatviews.get(muc_jid); - await u.waitUntil(() => roomspanel.el.querySelectorAll('.available-room').length); - expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1); - expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(0); + await u.waitUntil(() => roomspanel.querySelectorAll('.available-room').length); + expect(roomspanel.querySelectorAll('.available-room').length).toBe(1); + expect(roomspanel.querySelectorAll('.msgs-indicator').length).toBe(0); view.model.set({'minimized': true}); @@ -4888,9 +4890,9 @@ describe("Groupchats", function () { type: 'groupchat' }).c('body').t(message).tree()); await u.waitUntil(() => view.model.messages.length); - expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1); - expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1); - expect(roomspanel.el.querySelector('.msgs-indicator').textContent.trim()).toBe('1'); + expect(roomspanel.querySelectorAll('.available-room').length).toBe(1); + expect(roomspanel.querySelectorAll('.msgs-indicator').length).toBe(1); + expect(roomspanel.querySelector('.msgs-indicator').textContent.trim()).toBe('1'); await view.model.handleMessageStanza($msg({ 'from': muc_jid+'/'+nick, @@ -4899,12 +4901,12 @@ describe("Groupchats", function () { 'type': 'groupchat' }).c('body').t(message).tree()); await u.waitUntil(() => view.model.messages.length > 1); - expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1); - expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1); - expect(roomspanel.el.querySelector('.msgs-indicator').textContent.trim()).toBe('2'); + expect(roomspanel.querySelectorAll('.available-room').length).toBe(1); + expect(roomspanel.querySelectorAll('.msgs-indicator').length).toBe(1); + expect(roomspanel.querySelector('.msgs-indicator').textContent.trim()).toBe('2'); view.model.set({'minimized': false}); - expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1); - expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(0); + expect(roomspanel.querySelectorAll('.available-room').length).toBe(1); + expect(roomspanel.querySelectorAll('.msgs-indicator').length).toBe(0); done(); })); }); @@ -4953,7 +4955,7 @@ describe("Groupchats", function () { _converse.connection._dataRecv(mock.createRequest(presence)); const occupant = view.model.occupants.findWhere({'jid': _converse.bare_jid}); - expect(occupant.get('role')).toBe('visitor'); + await u.waitUntil(() => occupant.get('role') === 'visitor'); spyOn(_converse.connection, 'send'); view.model.setChatState(_converse.INACTIVE); @@ -5260,7 +5262,7 @@ describe("Groupchats", function () { `); _converse.connection._dataRecv(mock.createRequest(stanza)); - expect(view.querySelector('.chat-textarea')).toBe(null); + await u.waitUntil(() => view.querySelector('.chat-textarea') === null); let bottom_panel = view.querySelector('.muc-bottom-panel'); expect(bottom_panel.textContent.trim()).toBe("You're not allowed to send messages in this room"); @@ -5295,8 +5297,7 @@ describe("Groupchats", function () { `); _converse.connection._dataRecv(mock.createRequest(stanza)); - bottom_panel = view.querySelector('.muc-bottom-panel'); - expect(bottom_panel).toBe(null); + await u.waitUntil(() => view.querySelector('.muc-bottom-panel') === null); textarea = view.querySelector('.chat-textarea'); expect(textarea === null).toBe(false); diff --git a/spec/muc_messages.js b/spec/muc_messages.js index 7c1965f93..f41dfa965 100644 --- a/spec/muc_messages.js +++ b/spec/muc_messages.js @@ -390,6 +390,8 @@ describe("A Groupchat Message", function () { .c('status').attrs({code:'210'}).nodeTree; _converse.connection._dataRecv(mock.createRequest(presence)); + await u.waitUntil(() => view.model.messages.length === 4); + msg = $msg({ from: 'lounge@montague.lit/romeo', id: u.getUniqueId(), diff --git a/spec/notification.js b/spec/notification.js index 5f088c8b6..d7928bb85 100644 --- a/spec/notification.js +++ b/spec/notification.js @@ -12,7 +12,7 @@ describe("Notifications", function () { describe("an HTML5 Notification", function () { it("is shown when a new private message is received", - mock.initConverse(['rosterContactsFetched'], {}, async (done, _converse) => { + mock.initConverse([], {}, async (done, _converse) => { await mock.waitForRoster(_converse, 'current'); const stub = jasmine.createSpyObj('MyNotification', ['onclick', 'close']); @@ -34,7 +34,7 @@ describe("Notifications", function () { })); it("is shown when you are mentioned in a groupchat", - mock.initConverse(['rosterContactsFetched'], {}, async (done, _converse) => { + mock.initConverse([], {}, async (done, _converse) => { await mock.waitForRoster(_converse, 'current'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); @@ -78,11 +78,12 @@ describe("Notifications", function () { done(); })); - it("is shown for headline messages", - mock.initConverse(['rosterContactsFetched'], {}, async (done, _converse) => { + it("is shown for headline messages", mock.initConverse([], {}, async (done, _converse) => { const stub = jasmine.createSpyObj('MyNotification', ['onclick', 'close']); spyOn(window, 'Notification').and.returnValue(stub); + + await mock.waitForRoster(_converse, 'current', 0); const stanza = $msg({ 'type': 'headline', 'from': 'notify.example.com', @@ -95,7 +96,7 @@ describe("Notifications", function () { .c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18'); _converse.connection._dataRecv(mock.createRequest(stanza)); - await u.waitUntil(() => _converse.chatboxviews.keys().length); + await u.waitUntil(() => _converse.chatboxviews.keys().length === 2); const view = _converse.chatboxviews.get('notify.example.com'); await new Promise(resolve => view.model.messages.once('rendered', resolve)); expect(_converse.chatboxviews.keys().includes('notify.example.com')).toBeTruthy(); @@ -124,7 +125,7 @@ describe("Notifications", function () { })); it("is shown when a user changes their chat state (if show_chat_state_notifications is true)", - mock.initConverse(['rosterContactsFetched'], {show_chat_state_notifications: true}, + mock.initConverse([], {show_chat_state_notifications: true}, async (done, _converse) => { await mock.waitForRoster(_converse, 'current', 3); @@ -152,9 +153,7 @@ describe("Notifications", function () { describe("When play_sounds is set to true", function () { describe("A notification sound", function () { - it("is played when the current user is mentioned in a groupchat", - mock.initConverse(['rosterContactsFetched'], {}, async (done, _converse) => { - + it("is played when the current user is mentioned in a groupchat", mock.initConverse([], {}, async (done, _converse) => { mock.createContacts(_converse, 'current'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); _converse.play_sounds = true; @@ -208,9 +207,7 @@ describe("Notifications", function () { describe("A Favicon Message Counter", function () { it("is incremented when the message is received and the window is not focused", - mock.initConverse( - ['rosterContactsFetched'], {'show_tab_notifications': false}, - async function (done, _converse) { + mock.initConverse([], {'show_tab_notifications': false}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -264,9 +261,7 @@ describe("Notifications", function () { })); it("is not incremented when the message is received and the window is focused", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -295,15 +290,11 @@ describe("Notifications", function () { })); it("is incremented from zero when chatbox was closed after viewing previously received messages and the window is not focused now", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); - const favico = jasmine.createSpyObj('favico', ['badge']); spyOn(converse.env, 'Favico').and.returnValue(favico); - const message = 'This message will always increment the message counter from zero'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const msgFactory = function () { diff --git a/spec/room_registration.js b/spec/room_registration.js index e90c8d28a..01087126a 100644 --- a/spec/room_registration.js +++ b/spec/room_registration.js @@ -11,8 +11,7 @@ describe("Chatrooms", function () { describe("The /register commmand", function () { it("allows you to register your nickname in a room", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true}, + mock.initConverse(['chatBoxesFetched'], {'auto_register_muc_nickname': true}, async function (done, _converse) { const muc_jid = 'coven@chat.shakespeare.lit'; @@ -68,8 +67,7 @@ describe("Chatrooms", function () { describe("The auto_register_muc_nickname option", function () { it("allows you to automatically register your nickname when joining a room", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true}, + mock.initConverse(['chatBoxesFetched'], {'auto_register_muc_nickname': true}, async function (done, _converse) { const muc_jid = 'coven@chat.shakespeare.lit'; diff --git a/spec/xss.js b/spec/xss.js index d298571f1..af5d7d6b7 100644 --- a/spec/xss.js +++ b/spec/xss.js @@ -7,11 +7,7 @@ const u = converse.env.utils; describe("XSS", function () { describe("A Chat Message", function () { - it("will escape IMG payload XSS attempts", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { - + it("will escape IMG payload XSS attempts", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { spyOn(window, 'alert').and.callThrough(); await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -67,11 +63,7 @@ describe("XSS", function () { done(); })); - it("will escape SVG payload XSS attempts", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { - + it("will escape SVG payload XSS attempts", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { spyOn(window, 'alert').and.callThrough(); await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -127,9 +119,7 @@ describe("XSS", function () { })); it("will have properly escaped URLs", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -185,9 +175,7 @@ describe("XSS", function () { })); it("will avoid malformed and unsafe urls urls from rendering as anchors", - mock.initConverse( - ['rosterContactsFetched', 'chatBoxesFetched'], {}, - async function (done, _converse) { + mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { await mock.waitForRoster(_converse, 'current'); await mock.openControlBox(_converse); @@ -270,8 +258,7 @@ describe("XSS", function () { describe("A Groupchat", function () { it("escapes occupant nicknames when rendering them, to avoid JS-injection attacks", - mock.initConverse(['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); /* view.querySelectorAll('li .occupant-nick').length, 500); - const occupants = view.querySelector('.occupant-list').querySelectorAll('li .occupant-nick'); + await u.waitUntil(() => view.querySelectorAll('.occupant-list .occupant-nick').length === 2); + const occupants = view.querySelectorAll('.occupant-list li .occupant-nick'); expect(occupants.length).toBe(2); expect(occupants[0].textContent.trim()).toBe("<img src="x" onerror="alert(123)"/>"); done(); })); it("escapes the subject before rendering it, to avoid JS-injection attacks", - mock.initConverse( - ['rosterContactsFetched'], {}, - async function (done, _converse) { + mock.initConverse([], {}, async function (done, _converse) { await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc'); spyOn(window, 'alert');