diff --git a/dist/converse.js b/dist/converse.js index 8f3b674a7..d3a794fd9 100644 --- a/dist/converse.js +++ b/dist/converse.js @@ -58580,7 +58580,10 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins * loaded by converse.js's plugin machinery. */ const _converse = this._converse, - __ = _converse.__; + __ = _converse.__; // Promises exposed by this plugin + + _converse.api.promises.add('roomsListInitialized'); + _converse.OpenRooms = Backbone.Collection.extend({ comparator(room) { if (room.get('bookmarked')) { @@ -58840,23 +58843,16 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins _converse.rooms_list_view = new _converse.RoomsListView({ 'model': model }); + + _converse.api.emit('roomsListInitialized'); }; if (_converse.allow_bookmarks) { - u.onMultipleEvents([{ - 'object': _converse, - 'event': 'chatBoxesFetched' - }, { - 'object': _converse, - 'event': 'roomsPanelRendered' - }, { - 'object': _converse, - 'event': 'bookmarksInitialized' - }], initRoomsListView); + _converse.api.waitUntil('bookmarksInitialized').then(initRoomsListView); } else { u.onMultipleEvents([{ 'object': _converse, - 'event': 'chatBoxesFetched' + 'event': 'chatBoxesInitialized' }, { 'object': _converse, 'event': 'roomsPanelRendered' diff --git a/spec/roomslist.js b/spec/roomslist.js index a682b7aa1..a4bf46d72 100644 --- a/spec/roomslist.js +++ b/spec/roomslist.js @@ -1,17 +1,13 @@ (function (root, factory) { define(["jasmine", "mock", "test-utils"], factory); } (this, function (jasmine, mock, test_utils) { - var _ = converse.env._; - var $msg = converse.env.$msg; - var $iq = converse.env.$iq; - var $pres = converse.env.$pres; - var Promise = converse.env.Promise; - var Strophe = converse.env.Strophe; - var u = converse.env.utils; + const { Backbone, Promise, Strophe, $iq, $msg, $pres, b64_sha1, sizzle, _ } = converse.env; + const u = converse.env.utils; - describe("A list of open rooms", function () { - it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises( + describe("A list of open groupchats", function () { + + it("is shown in controlbox", mock.initConverseWithPromises( null, ['rosterGroupsFetched', 'chatBoxesFetched'], { allow_bookmarks: false // Makes testing easier, otherwise we // have to mock stanza traffic. @@ -49,6 +45,70 @@ done(); } )); + + it("uses bookmarks to determine groupchat names", + mock.initConverseWithPromises( + ['send'], ['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'}, + async function (done, _converse) { + + await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); + const view = _converse.chatboxviews.get('lounge@localhost'); + + const contact_jid = 'newguy@localhost'; + let stanza = $pres({ + to: 'dummy@localhost/resource', + from: 'lounge@localhost/newguy' + }) + .c('x', {xmlns: Strophe.NS.MUC_USER}) + .c('item', { + 'affiliation': 'none', + 'jid': 'newguy@localhost/_converse.js-290929789', + 'role': 'participant' + }).tree(); + _converse.connection._dataRecv(test_utils.createRequest(stanza)); + + spyOn(_converse.Bookmarks.prototype, 'fetchBookmarks').and.callThrough(); + + await test_utils.waitUntilDiscoConfirmed( + _converse, _converse.bare_jid, + [{'category': 'pubsub', 'type':'pep'}], + [`${Strophe.NS.PUBSUB}#publish-options`] + ); + + const call = await test_utils.waitUntil(() => + _.filter( + _converse.connection.send.calls.all(), + c => sizzle('items[node="storage:bookmarks"]', c.args[0]).length + ).pop() + ); + expect(Strophe.serialize(call.args[0])).toBe( + ``+ + ''+ + ''+ + ''+ + ''); + + stanza = $iq({'to': _converse.connection.jid, 'type':'result', 'id':call.args[0].getAttribute('id')}) + .c('pubsub', {'xmlns': Strophe.NS.PUBSUB}) + .c('items', {'node': 'storage:bookmarks'}) + .c('item', {'id': 'current'}) + .c('storage', {'xmlns': 'storage:bookmarks'}) + .c('conference', { + 'name': 'Bookmarked Lounge', + 'jid': 'lounge@localhost' + }); + _converse.connection._dataRecv(test_utils.createRequest(stanza)); + + await _converse.api.waitUntil('roomsListInitialized'); + const controlbox = _converse.chatboxviews.get('controlbox'); + const list = controlbox.el.querySelector('div.rooms-list-container'); + expect(_.includes(list.classList, 'hidden')).toBeFalsy(); + const items = list.querySelectorAll('.list-item'); + expect(items.length).toBe(1); + expect(items[0].textContent.trim()).toBe('Bookmarked Lounge'); + expect(_converse.bookmarks.fetchBookmarks).toHaveBeenCalled(); + done(); + })); }); describe("A groupchat shown in the groupchats list", function () { diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 207e8b738..c6a079381 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -40,6 +40,9 @@ converse.plugins.add('converse-roomslist', { const { _converse } = this, { __ } = _converse; + // Promises exposed by this plugin + _converse.api.promises.add('roomsListInitialized'); + _converse.OpenRooms = Backbone.Collection.extend({ @@ -266,17 +269,14 @@ converse.plugins.add('converse-roomslist', { model.browserStorage = new Backbone.BrowserStorage[storage](id); _converse.rooms_list_view = new _converse.RoomsListView({'model': model}); + _converse.api.emit('roomsListInitialized'); }; if (_converse.allow_bookmarks) { - u.onMultipleEvents([ - {'object': _converse, 'event': 'chatBoxesFetched'}, - {'object': _converse, 'event': 'roomsPanelRendered'}, - {'object': _converse, 'event': 'bookmarksInitialized'} - ], initRoomsListView); + _converse.api.waitUntil('bookmarksInitialized').then(initRoomsListView); } else { u.onMultipleEvents([ - {'object': _converse, 'event': 'chatBoxesFetched'}, + {'object': _converse, 'event': 'chatBoxesInitialized'}, {'object': _converse, 'event': 'roomsPanelRendered'} ], initRoomsListView); } diff --git a/tests/utils.js b/tests/utils.js index 37fef4963..c16594755 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -15,7 +15,7 @@ } utils.waitUntil = waitUntilPromise.default; - utils.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features, items, type='info') { + utils.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features=[], items=[], type='info') { const iq = await utils.waitUntil(() => { return _.filter( _converse.connection.IQ_stanzas,