Support for IndexedDB. updates #1105
Depend on latest backbone.browserStorage which has support for IndexedDB via localforage. Storage operations are now asynchronous and transactional. Bugs fixed (mostly by waiting for operations to complete): * Rooms are now fetched asynchronously, so wait before triggering `show` or when closing. * Make sure chat create/update transactions complete before firing events * Make sure chats and messages have been fetched before creating new ones. * When doing a `fetch` with `wait: false` on a collection and then creating a model in that collection, then once the read operation finishes (after creating the model), the collection is emptied again. * Patch and wait when saving. Otherwise we have previously set attributes overriding later ones. * Make sure api.roomviews.close returns a promise Test fixes: * Chats are now asynchronously returned, so we need to use `await` * Wait for the storage transaction to complete when creating and updating messages * Wait for all chatboxes to close Otherwise we get sessionStorage inconsistencies due to the async nature of localforage. * Wait for room views to close in spec/chatroom.js In the process, remove the `closeAllChatBoxes` override in converse-controlbox by letting the `close` method decide whether it should be closed or not.
This commit is contained in:
parent
66c052f3fd
commit
1fa203c990
@ -22,13 +22,7 @@
|
||||
},
|
||||
"rules": {
|
||||
"lodash/prefer-lodash-chain": "off",
|
||||
"lodash/prefer-lodash-method": [2, {
|
||||
"ignoreMethods": [
|
||||
"assign", "every", "keys", "find", "endsWith", "startsWith", "filter",
|
||||
"reduce", "isArray", "create", "map", "replace", "some", "toLower",
|
||||
"split", "trim", "forEach", "toUpperCase", "includes", "values", "padStart"
|
||||
]
|
||||
}],
|
||||
"lodash/prefer-lodash-method": "off",
|
||||
"lodash/import-scope": "off",
|
||||
"lodash/prefer-constant": "off",
|
||||
"lodash/prefer-get": "off",
|
||||
|
@ -3,6 +3,7 @@
|
||||
## 6.0.0 (Unreleased)
|
||||
|
||||
- #129: Add support for XEP-0156: Disovering Alternative XMPP Connection Methods. Only XML is supported for now.
|
||||
- #1105: Preliminary support for storing persistent data in IndexedDB instead of localStorage
|
||||
- #1089: When filtering the roster for `online` users, show all non-offline users.
|
||||
- #1691: Fix `collection.chatbox is undefined` errors
|
||||
- #1733: New message notifications for a minimized chat stack on top of each other
|
||||
@ -15,6 +16,10 @@
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- In contrast to sessionStorage and localStorage, IndexedDB is an asynchronous database.
|
||||
A lot of code that relied on database access to be synchronous had to be
|
||||
updated to work with asynchronous access via promises.
|
||||
|
||||
- In order to add support for XEP-0156, the XMPP connection needs to be created
|
||||
only once we know the JID of the user that's logging in. This means that the
|
||||
[connectionInitialized](https://conversejs.org/docs/html/api/-_converse.html#event:connectionInitialized)
|
||||
@ -26,6 +31,7 @@
|
||||
* `_converse.api.chats.create`
|
||||
* `_converse.api.rooms.get`
|
||||
* `_converse.api.rooms.create`
|
||||
* `_converse.api.roomviews.close`
|
||||
|
||||
- The `show_only_online_users` setting has been removed.
|
||||
- The order of certain events have now changed: `statusInitialized` is now triggered after `initialized` and `connected` and `reconnected`.
|
||||
|
36825
package-lock.json
generated
36825
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -83,7 +83,7 @@
|
||||
"install": "^0.9.5",
|
||||
"jasmine-core": "2.99.1",
|
||||
"jsdoc": "^3.6.2",
|
||||
"lerna": "^3.16.4",
|
||||
"lerna": "^3.18.1",
|
||||
"lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
|
||||
"mini-css-extract-plugin": "^0.7.0",
|
||||
"minimist": "^1.2.0",
|
||||
|
@ -168,7 +168,8 @@
|
||||
'name': 'The Play',
|
||||
'nick': ' Othello'
|
||||
});
|
||||
expect(_converse.chatboxviews.get(jid) === undefined).toBeFalsy();
|
||||
await u.waitUntil(() => _converse.api.rooms.get().length);
|
||||
expect(_.isUndefined(_converse.chatboxviews.get(jid))).toBeFalsy();
|
||||
|
||||
// Check that we don't auto-join if muc_respect_autojoin is false
|
||||
_converse.muc_respect_autojoin = false;
|
||||
@ -188,20 +189,20 @@
|
||||
|
||||
it("will use the nickname from the bookmark", mock.initConverse(
|
||||
['rosterGroupsFetched'], {}, async function (done, _converse) {
|
||||
|
||||
await test_utils.waitUntilBookmarksReturned(_converse);
|
||||
const room_jid = 'coven@chat.shakespeare.lit';
|
||||
await u.waitUntil(() => _converse.bookmarks);
|
||||
_converse.bookmarks.create({
|
||||
'jid': room_jid,
|
||||
'autojoin': false,
|
||||
'name': 'The Play',
|
||||
'nick': 'Othello'
|
||||
});
|
||||
const model = await _converse.api.rooms.open(room_jid);
|
||||
spyOn(model, 'join').and.callThrough();
|
||||
const room = await _converse.api.rooms.open(room_jid);
|
||||
spyOn(room, 'join').and.callThrough();
|
||||
await test_utils.getRoomFeatures(_converse, 'coven', 'chat.shakespeare.lit');
|
||||
await u.waitUntil(() => model.join.calls.count());
|
||||
expect(model.get('nick')).toBe('Othello');
|
||||
await u.waitUntil(() => room.join.calls.count());
|
||||
expect(room.get('nick')).toBe('Othello');
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -234,22 +235,13 @@
|
||||
}));
|
||||
|
||||
it("can be unbookmarked", mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
['rosterGroupsFetched'], {}, async function (done, _converse) {
|
||||
|
||||
let sent_stanza, IQ_id;
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(
|
||||
_converse, _converse.bare_jid,
|
||||
[{'category': 'pubsub', 'type': 'pep'}],
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
const sendIQ = _converse.connection.sendIQ;
|
||||
await test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
|
||||
|
||||
const jid = 'theplay@conference.shakespeare.lit';
|
||||
const view = _converse.chatboxviews.get(jid);
|
||||
await u.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
|
||||
await test_utils.waitUntilBookmarksReturned(_converse);
|
||||
const muc_jid = 'theplay@conference.shakespeare.lit';
|
||||
await _converse.api.rooms.open(muc_jid);
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
|
||||
|
||||
spyOn(view, 'toggleBookmark').and.callThrough();
|
||||
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
|
||||
@ -261,16 +253,13 @@
|
||||
'name': 'The Play',
|
||||
'nick': ' Othello'
|
||||
});
|
||||
|
||||
expect(_converse.bookmarks.length).toBe(1);
|
||||
await u.waitUntil(() => _converse.chatboxes.length >= 1);
|
||||
expect(view.model.get('bookmarked')).toBeTruthy();
|
||||
let bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
|
||||
expect(u.hasClass('button-on', bookmark_icon)).toBeTruthy();
|
||||
|
||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
spyOn(_converse.connection, 'getUniqueId').and.callThrough();
|
||||
bookmark_icon.click();
|
||||
bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
|
||||
@ -281,8 +270,9 @@
|
||||
// Check that an IQ stanza is sent out, containing no
|
||||
// conferences to bookmark (since we removed the one and
|
||||
// only bookmark).
|
||||
expect(sent_stanza.toLocaleString()).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||
const sent_stanza = _converse.connection.IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(sent_stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
|
||||
`<publish node="storage:bookmarks">`+
|
||||
`<item id="current">`+
|
||||
@ -478,7 +468,7 @@
|
||||
[{'category': 'pubsub', 'type': 'pep'}],
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
|
||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(
|
||||
@ -546,10 +536,9 @@
|
||||
|
||||
|
||||
it("remembers the toggle state of the bookmarks list", mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
['rosterGroupsFetched'], {}, async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitUntilDiscoConfirmed(
|
||||
_converse, _converse.bare_jid,
|
||||
[{'category': 'pubsub', 'type': 'pep'}],
|
||||
@ -558,7 +547,7 @@
|
||||
|
||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(
|
||||
() => IQ_stanzas.filter(s => sizzle('items[node="storage:bookmarks"]', s).length).pop());
|
||||
() => IQ_stanzas.filter(s => sizzle('iq items[node="storage:bookmarks"]', s).length).pop());
|
||||
|
||||
expect(Strophe.serialize(sent_stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${sent_stanza.getAttribute('id')}" type="get" xmlns="jabber:client">`+
|
||||
@ -567,13 +556,13 @@
|
||||
'</pubsub>'+
|
||||
'</iq>'
|
||||
);
|
||||
|
||||
const stanza = $iq({'to': _converse.connection.jid, 'type':'result', 'id':sent_stanza.getAttribute('id')})
|
||||
const stanza = $iq({'to': _converse.connection.jid, 'type':'result', 'id': sent_stanza.getAttribute('id')})
|
||||
.c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
|
||||
.c('items', {'node': 'storage:bookmarks'})
|
||||
.c('item', {'id': 'current'})
|
||||
.c('storage', {'xmlns': 'storage:bookmarks'});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
await _converse.api.waitUntil('bookmarksInitialized');
|
||||
|
||||
_converse.bookmarks.create({
|
||||
'jid': 'theplay@conference.shakespeare.lit',
|
||||
@ -606,7 +595,7 @@
|
||||
{ hide_open_bookmarks: true },
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitUntilBookmarksReturned(_converse);
|
||||
|
||||
// Check that it's there
|
||||
|
@ -19,7 +19,7 @@
|
||||
it("has a /help command to show the available commands", mock.initConverse(['rosterGroupsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -49,7 +49,7 @@
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
|
||||
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
|
||||
await test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
expect(_converse.chatboxes.length).toEqual(1);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
let message = '/me is tired';
|
||||
@ -95,7 +95,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
// openControlBox was called earlier, so the controlbox is
|
||||
// visible, but no other chat boxes have been created.
|
||||
@ -105,7 +105,7 @@
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
|
||||
const online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
|
||||
expect(online_contacts.length).toBe(15);
|
||||
expect(online_contacts.length).toBe(17);
|
||||
let el = online_contacts[0];
|
||||
el.click();
|
||||
await u.waitUntil(() => document.querySelectorAll("#conversejs .chatbox").length == 2);
|
||||
@ -124,7 +124,7 @@
|
||||
['rosterGroupsFetched'], {'allow_non_roster_messaging': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const stanza = u.toStanza(`
|
||||
<message from="${sender_jid}"
|
||||
@ -171,7 +171,7 @@
|
||||
spyOn(trimmed_chatboxes, 'removeChat').and.callThrough();
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
let jid, chatboxview;
|
||||
// openControlBox was called earlier, so the controlbox is
|
||||
@ -183,7 +183,7 @@
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length);
|
||||
// Test that they can be maximized again
|
||||
const online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
|
||||
expect(online_contacts.length).toBe(15);
|
||||
expect(online_contacts.length).toBe(17);
|
||||
let i;
|
||||
for (i=0; i<online_contacts.length; i++) {
|
||||
const el = online_contacts[i];
|
||||
@ -192,11 +192,11 @@
|
||||
await u.waitUntil(() => _converse.chatboxes.length == 16);
|
||||
expect(_converse.chatboxviews.trimChats.calls.count()).toBe(16);
|
||||
|
||||
_converse.api.chatviews.get().forEach(v => spyOn(v, 'onMinimized').and.callThrough());
|
||||
for (i=0; i<online_contacts.length; i++) {
|
||||
const el = online_contacts[i];
|
||||
jid = _.trim(el.textContent.trim()).replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
chatboxview = _converse.chatboxviews.get(jid);
|
||||
spyOn(chatboxview, 'onMinimized').and.callThrough();
|
||||
chatboxview.model.set({'minimized': true});
|
||||
expect(trimmed_chatboxes.addChat).toHaveBeenCalled();
|
||||
expect(chatboxview.onMinimized).toHaveBeenCalled();
|
||||
@ -240,7 +240,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
expect(_converse.chatboxes.length).toEqual(1);
|
||||
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -267,10 +267,9 @@
|
||||
|
||||
spyOn(_converse.ChatBoxViews.prototype, 'trimChats');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
test_utils.openControlBox();
|
||||
|
||||
test_utils.openChatBoxes(_converse, 6);
|
||||
await u.waitUntil(() => _converse.chatboxes.length == 7);
|
||||
@ -282,6 +281,7 @@
|
||||
// The chatboxes will then be fetched from browserStorage inside the
|
||||
// onConnected method
|
||||
newchatboxes.onConnected();
|
||||
await new Promise(resolve => _converse.api.listen.on('chatBoxesFetched', resolve));
|
||||
expect(newchatboxes.length).toEqual(7);
|
||||
// Check that the chatboxes items retrieved from browserStorage
|
||||
// have the same attributes values as the original ones.
|
||||
@ -302,7 +302,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -337,7 +337,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -377,13 +377,11 @@
|
||||
|
||||
spyOn(_converse.ChatBoxViews.prototype, 'trimChats');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
_converse.chatboxes.browserStorage._clear();
|
||||
|
||||
test_utils.closeControlBox();
|
||||
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
|
||||
expect(_converse.chatboxes.length).toEqual(1);
|
||||
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
|
||||
@ -392,18 +390,19 @@
|
||||
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
|
||||
expect(_converse.chatboxes.length).toEqual(7);
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxInitialized', jasmine.any(Object));
|
||||
test_utils.closeAllChatBoxes(_converse);
|
||||
await test_utils.closeAllChatBoxes(_converse);
|
||||
|
||||
expect(_converse.chatboxes.length).toEqual(1);
|
||||
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
|
||||
var newchatboxes = new _converse.ChatBoxes();
|
||||
const newchatboxes = new _converse.ChatBoxes();
|
||||
expect(newchatboxes.length).toEqual(0);
|
||||
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
|
||||
// onConnected will fetch chatboxes in browserStorage, but
|
||||
// because there aren't any open chatboxes, there won't be any
|
||||
// in browserStorage either. XXX except for the controlbox
|
||||
newchatboxes.onConnected();
|
||||
await new Promise(resolve => _converse.api.listen.on('chatBoxesFetched', resolve));
|
||||
expect(newchatboxes.length).toEqual(1);
|
||||
expect(newchatboxes.models[0].id).toBe("controlbox");
|
||||
done();
|
||||
@ -417,7 +416,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const chatbox = _converse.chatboxes.get(contact_jid);
|
||||
@ -436,7 +435,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -476,7 +475,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -492,7 +491,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
let toolbar, call_button;
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -527,7 +526,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
@ -559,7 +558,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -585,7 +584,7 @@
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
spyOn(_converse.connection, 'send');
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -606,7 +605,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -640,7 +639,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -679,7 +678,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -703,7 +702,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
@ -794,7 +793,7 @@
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
|
||||
_converse.TIMEOUTS.PAUSED = 200; // Make the timeout shorter so that we can test
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -847,7 +846,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
// TODO: only show paused state if the previous state was composing
|
||||
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
|
||||
@ -926,7 +925,7 @@
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 1000);
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -983,7 +982,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -1005,7 +1004,7 @@
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
const view = await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
expect(view.model.get('chat_state')).toBe('active');
|
||||
@ -1028,7 +1027,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
@ -1070,7 +1069,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -1101,7 +1100,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
@ -1110,8 +1109,9 @@
|
||||
let message = 'This message is another sent from this chatbox';
|
||||
await test_utils.sendMessage(view, message);
|
||||
|
||||
expect(view.model.messages.length > 0).toBeTruthy();
|
||||
expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy();
|
||||
expect(view.model.messages.length === 1).toBeTruthy();
|
||||
let stored_messages = await view.model.messages.browserStorage.findAll();
|
||||
expect(stored_messages.length).toBe(1);
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg'));
|
||||
|
||||
message = '/clear';
|
||||
@ -1125,10 +1125,12 @@
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13
|
||||
});
|
||||
expect(view.clearMessages).toHaveBeenCalled();
|
||||
expect(view.clearMessages.calls.all().length).toBe(1);
|
||||
await view.clearMessages.calls.all()[0].returnValue;
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
expect(view.model.messages.length, 0); // The messages must be removed from the chatbox
|
||||
expect(view.model.messages.browserStorage.records.length, 0); // And also from browserStorage
|
||||
stored_messages = await view.model.messages.browserStorage.findAll();
|
||||
expect(stored_messages.length).toBe(0);
|
||||
expect(_converse.api.trigger.calls.count(), 1);
|
||||
expect(_converse.api.trigger.calls.mostRecent().args, ['messageSend', message]);
|
||||
done();
|
||||
@ -1143,7 +1145,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
expect(document.title).toBe('Converse Tests');
|
||||
|
||||
@ -1181,7 +1183,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
_converse.windowState = 'hidden';
|
||||
spyOn(_converse, 'clearMsgCounter').and.callThrough();
|
||||
_converse.saveWindowState(null, 'focus');
|
||||
@ -1196,7 +1198,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
expect(document.title).toBe('Converse Tests');
|
||||
spyOn(_converse, 'incrementMsgCounter').and.callThrough();
|
||||
@ -1466,7 +1468,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
// Adding two contacts one with Capital initials and one with small initials of same JID (Case sensitive check)
|
||||
_converse.roster.create({
|
||||
jid: mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
@ -69,8 +69,8 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
@ -78,8 +78,8 @@
|
||||
const chatview = _converse.chatboxviews.get(sender_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
|
||||
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
|
||||
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count') === null).toBeTruthy();
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator') === null).toBeTruthy();
|
||||
|
||||
let msg = $msg({
|
||||
from: sender_jid,
|
||||
@ -119,7 +119,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
var view = _converse.xmppstatusview;
|
||||
expect(u.hasClass('online', view.el.querySelector('.xmpp-status span:first-child'))).toBe(true);
|
||||
expect(view.el.querySelector('.xmpp-status span.online').textContent.trim()).toBe('I am online');
|
||||
@ -131,8 +131,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
|
||||
await test_utils.openControlBox(_converse);
|
||||
var cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.change-status').click()
|
||||
var modal = _converse.xmppstatusview.status_modal;
|
||||
@ -160,8 +159,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
|
||||
await test_utils.openControlBox(_converse);
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.change-status').click()
|
||||
const modal = _converse.xmppstatusview.status_modal;
|
||||
@ -194,7 +192,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
@ -229,7 +228,7 @@
|
||||
['rosterGroupsFetched'], {'autocomplete_add_contact': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
const modal = _converse.rosterview.add_contact_modal;
|
||||
@ -319,7 +318,8 @@
|
||||
'xhr_user_search_url': 'http://example.org/?' },
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await test_utils.openControlBox(_converse);
|
||||
var modal;
|
||||
const xhr = {
|
||||
'open': function open () {},
|
||||
|
@ -258,9 +258,8 @@
|
||||
['rosterInitialized', 'chatBoxesInitialized'], {},
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current', 2);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 2);
|
||||
|
||||
// Test on chat that doesn't exist.
|
||||
let chat = await _converse.api.chats.get('non-existing@jabber.org');
|
||||
@ -294,9 +293,8 @@
|
||||
['rosterGroupsFetched', 'chatBoxesInitialized'], {},
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current', 2);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 2);
|
||||
|
||||
const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
@ -18,7 +18,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
|
@ -6,13 +6,16 @@
|
||||
], factory);
|
||||
} (this, function (jasmine, mock, test_utils) {
|
||||
"use strict";
|
||||
var $msg = converse.env.$msg,
|
||||
_ = converse.env._,
|
||||
utils = converse.env.utils;
|
||||
const $msg = converse.env.$msg,
|
||||
_ = converse.env._,
|
||||
u = converse.env.utils;
|
||||
|
||||
describe("A headlines box", function () {
|
||||
|
||||
it("will not open nor display non-headline messages", mock.initConverse((done, _converse) => {
|
||||
it("will not open nor display non-headline messages",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) {
|
||||
|
||||
/* XMPP spam message:
|
||||
*
|
||||
* <message xmlns="jabber:client"
|
||||
@ -23,7 +26,7 @@
|
||||
* <body>SORRY FOR THIS ADVERT</body
|
||||
* </message
|
||||
*/
|
||||
sinon.spy(utils, 'isHeadlineMessage');
|
||||
sinon.spy(u, 'isHeadlineMessage');
|
||||
const stanza = $msg({
|
||||
'xmlns': 'jabber:client',
|
||||
'to': 'romeo@montague.lit',
|
||||
@ -33,9 +36,10 @@
|
||||
.c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up()
|
||||
.c('body').t('SORRY FOR THIS ADVERT');
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
expect(utils.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
|
||||
utils.isHeadlineMessage.restore();
|
||||
await u.waitUntil(() => _converse.api.chats.get().length);
|
||||
expect(u.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(u.isHeadlineMessage.returned(false)).toBeTruthy();
|
||||
u.isHeadlineMessage.restore();
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -55,7 +59,7 @@
|
||||
* </x>
|
||||
* </message>
|
||||
*/
|
||||
sinon.spy(utils, 'isHeadlineMessage');
|
||||
sinon.spy(u, 'isHeadlineMessage');
|
||||
const stanza = $msg({
|
||||
'type': 'headline',
|
||||
'from': 'notify.example.com',
|
||||
@ -73,9 +77,9 @@
|
||||
_converse.chatboxviews.keys(),
|
||||
'notify.example.com')
|
||||
).toBeTruthy();
|
||||
expect(utils.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
|
||||
utils.isHeadlineMessage.restore(); // unwraps
|
||||
expect(u.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(u.isHeadlineMessage.returned(true)).toBeTruthy();
|
||||
u.isHeadlineMessage.restore(); // unwraps
|
||||
// Headlines boxes don't show an avatar
|
||||
const view = _converse.chatboxviews.get('notify.example.com');
|
||||
expect(view.model.get('show_avatar')).toBeFalsy();
|
||||
@ -84,11 +88,12 @@
|
||||
}));
|
||||
|
||||
it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
|
||||
mock.initConverse((done, _converse) => {
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
|
||||
|
||||
_converse.allow_non_roster_messaging = false;
|
||||
sinon.spy(utils, 'isHeadlineMessage');
|
||||
var stanza = $msg({
|
||||
sinon.spy(u, 'isHeadlineMessage');
|
||||
const stanza = $msg({
|
||||
'type': 'headline',
|
||||
'from': 'andre5114@jabber.snc.ru/Spark',
|
||||
'to': 'romeo@montague.lit',
|
||||
@ -98,9 +103,9 @@
|
||||
.c('body').t('Здравствуйте друзья');
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
expect(_.without('controlbox', _converse.chatboxviews.keys()).length).toBe(0);
|
||||
expect(utils.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
|
||||
utils.isHeadlineMessage.restore(); // unwraps
|
||||
expect(u.isHeadlineMessage.called).toBeTruthy();
|
||||
expect(u.isHeadlineMessage.returned(true)).toBeTruthy();
|
||||
u.isHeadlineMessage.restore(); // unwraps
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
@ -176,7 +176,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
await test_utils.waitUntilDiscoConfirmed(
|
||||
@ -222,8 +222,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.lit'], 'items')
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.lit', [], [Strophe.NS.HTTPUPLOAD], []);
|
||||
test_utils.createContacts(_converse, 'current', 3);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -264,8 +263,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items');
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []);
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -561,8 +559,7 @@
|
||||
entities = await _converse.api.disco.entities.get();
|
||||
expect(entities.get('montague.lit').items.get('upload.montague.lit').identities.where({'category': 'store'}).length).toBe(1);
|
||||
await _converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, _converse.domain);
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -599,8 +596,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items');
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []);
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
|
@ -13,7 +13,7 @@
|
||||
allow_registration: false },
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const cbview = await u.waitUntil(() => _converse.chatboxviews.get('controlbox'));
|
||||
const checkboxes = cbview.el.querySelectorAll('input[type="checkbox"]');
|
||||
expect(checkboxes.length).toBe(1);
|
||||
@ -51,7 +51,7 @@
|
||||
u.waitUntil(() => _converse.chatboxviews.get('controlbox'))
|
||||
.then(() => {
|
||||
var cbview = _converse.chatboxviews.get('controlbox');
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const checkboxes = cbview.el.querySelectorAll('input[type="checkbox"]');
|
||||
expect(checkboxes.length).toBe(1);
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
@ -92,7 +92,7 @@
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(u.hasClass('correcting', view.el.querySelector('.chat-msg'))).toBe(true);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')));
|
||||
|
||||
spyOn(_converse.connection, 'send');
|
||||
textarea.value = 'But soft, what light through yonder window breaks?';
|
||||
@ -189,10 +189,10 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
@ -348,7 +348,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
|
||||
@ -514,11 +514,10 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
/* Ideally we wouldn't have to filter out headline
|
||||
* messages, but Prosody gives them the wrong 'type' :(
|
||||
*/
|
||||
// Ideally we wouldn't have to filter out headline
|
||||
// messages, but Prosody gives them the wrong 'type' :(
|
||||
sinon.spy(_converse, 'log');
|
||||
sinon.spy(_converse.chatboxes, 'getChatBox');
|
||||
sinon.spy(u, 'isHeadlineMessage');
|
||||
@ -551,7 +550,7 @@
|
||||
|
||||
const include_nick = false;
|
||||
await test_utils.waitForRoster(_converse, 'current', 2, include_nick);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
// Send a message from a different resource
|
||||
const msgtext = 'This is a carbon message';
|
||||
@ -603,7 +602,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
// Send a message from a different resource
|
||||
const msgtext = 'This is a sent carbon message';
|
||||
@ -622,13 +621,15 @@
|
||||
'to': recipient_jid,
|
||||
'type': 'chat'
|
||||
}).c('body').t(msgtext).tree();
|
||||
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
// Check that the chatbox and its view now exist
|
||||
const chatbox = _converse.chatboxes.get(recipient_jid);
|
||||
const view = _converse.chatboxviews.get(recipient_jid);
|
||||
const chatbox = await _converse.api.chats.get(recipient_jid);
|
||||
const view = _converse.api.chatviews.get(recipient_jid);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(chatbox).toBeDefined();
|
||||
expect(view).toBeDefined();
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
// Check that the message was received and check the message parameters
|
||||
expect(chatbox.messages.length).toEqual(1);
|
||||
const msg_obj = chatbox.messages.models[0];
|
||||
@ -648,7 +649,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
/* <message from="mallory@evil.example" to="b@xmpp.example">
|
||||
* <received xmlns='urn:xmpp:carbons:2'>
|
||||
* <forwarded xmlns='urn:xmpp:forward:0'>
|
||||
@ -679,11 +680,11 @@
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
|
||||
// Check that chatbox for impersonated user is not created.
|
||||
let chatbox = _converse.chatboxes.get(impersonated_jid);
|
||||
let chatbox = await _converse.api.chats.get(impersonated_jid);
|
||||
expect(chatbox).not.toBeDefined();
|
||||
|
||||
// Check that the chatbox for the malicous user is not created
|
||||
chatbox = _converse.chatboxes.get(sender_jid);
|
||||
chatbox = await _converse.api.chats.get(sender_jid);
|
||||
expect(chatbox).not.toBeDefined();
|
||||
done();
|
||||
}));
|
||||
@ -699,7 +700,7 @@
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_name = mock.cur_names[0];
|
||||
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
@ -757,14 +758,14 @@
|
||||
|
||||
const include_nick = false;
|
||||
await test_utils.waitForRoster(_converse, 'current', 2, include_nick);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const contact_name = mock.cur_names[1];
|
||||
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
test_utils.clearChatBoxMessages(_converse, contact_jid);
|
||||
await test_utils.clearChatBoxMessages(_converse, contact_jid);
|
||||
const one_day_ago = dayjs().subtract(1, 'day');
|
||||
const chatbox = _converse.chatboxes.get(contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
@ -849,10 +850,10 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
const message = '<p>This message contains <em>some</em> <b>markup</b></p>';
|
||||
spyOn(view.model, 'sendMessage').and.callThrough();
|
||||
await test_utils.sendMessage(view, message);
|
||||
@ -869,10 +870,10 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
const message = 'This message contains a hyperlink: www.opkode.com';
|
||||
spyOn(view.model, 'sendMessage').and.callThrough();
|
||||
test_utils.sendMessage(view, message);
|
||||
@ -891,11 +892,11 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
|
||||
let message = "http://www.opkode.com/'onmouseover='alert(1)'whatever";
|
||||
await test_utils.sendMessage(view, message);
|
||||
@ -990,11 +991,11 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
let base_url = 'https://conversejs.org';
|
||||
const base_url = 'https://conversejs.org';
|
||||
let message = base_url+"/logo/conversejs-filled.svg";
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
spyOn(view.model, 'sendMessage').and.callThrough();
|
||||
test_utils.sendMessage(view, message);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length, 1000)
|
||||
@ -1024,7 +1025,6 @@
|
||||
expect(msg.querySelectorAll('img').length).toEqual(2);
|
||||
|
||||
// Non-https images aren't rendered
|
||||
base_url = document.URL.split(window.location.pathname)[0];
|
||||
message = base_url+"/logo/conversejs-filled.svg";
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
expect(chat_content.querySelectorAll('img').length).toBe(4);
|
||||
@ -1065,7 +1065,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const base_time = new Date();
|
||||
const ONE_MINUTE_LATER = 60000;
|
||||
@ -1345,7 +1345,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
@ -1389,7 +1389,7 @@
|
||||
|
||||
const include_nick = false;
|
||||
await test_utils.waitForRoster(_converse, 'current', 1, include_nick);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const message = 'This is a received message';
|
||||
@ -1463,7 +1463,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const msg_id = u.getUniqueId();
|
||||
const view = await test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
@ -1492,7 +1492,6 @@
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
expect(view.model.messages.browserStorage.records.length).toBe(1);
|
||||
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
'from': sender_jid,
|
||||
@ -1515,7 +1514,6 @@
|
||||
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[0].childNodes[1].textContent).toBe(': But soft, what light through yonder airlock breaks?');
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
expect(view.model.messages.browserStorage.records.length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -1524,11 +1522,10 @@
|
||||
|
||||
it("the VCard for that user is fetched and the chatbox updated with the results",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
['rosterGroupsFetched', 'emojisInitialized'], {'allow_non_roster_messaging': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
_converse.allow_non_roster_messaging = true;
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -1558,14 +1555,14 @@
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
|
||||
// Check that the chatbox and its view now exist
|
||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
const chatbox = await _converse.api.chats.get(sender_jid);
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
expect(chatbox).toBeDefined();
|
||||
expect(view).toBeDefined();
|
||||
expect(chatbox.get('fullname') === sender_jid);
|
||||
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
|
||||
let author_el = view.el.querySelector('.chat-msg__author');
|
||||
expect( _.includes(author_el.textContent.trim(), 'Mercutio')).toBeTruthy();
|
||||
@ -1583,11 +1580,10 @@
|
||||
|
||||
it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
['rosterGroupsFetched'], {'allow_non_roster_messaging': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.allow_non_roster_messaging = false;
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const message = 'This is a received message from someone not on the roster';
|
||||
@ -1607,7 +1603,6 @@
|
||||
expect(chatbox).not.toBeDefined();
|
||||
// onMessage is a handler for received XMPP messages
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.api.chats.get().length).toBe(1);
|
||||
let view = _converse.chatboxviews.get(sender_jid);
|
||||
expect(view).not.toBeDefined();
|
||||
|
||||
@ -1618,7 +1613,7 @@
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
// Check that the chatbox and its view now exist
|
||||
chatbox = _converse.chatboxes.get(sender_jid);
|
||||
chatbox = await _converse.api.chats.get(sender_jid);
|
||||
expect(chatbox).toBeDefined();
|
||||
expect(view).toBeDefined();
|
||||
// Check that the message was received and check the message parameters
|
||||
@ -1755,6 +1750,7 @@
|
||||
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
|
||||
.t('Something else went wrong as well');
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.messages.length > 3);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(chat_content.querySelectorAll('.chat-error').length).toEqual(3);
|
||||
done();
|
||||
@ -1768,7 +1764,7 @@
|
||||
// See #1317
|
||||
// https://github.com/conversejs/converse.js/issues/1317
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -1887,7 +1883,7 @@
|
||||
type: 'chat',
|
||||
id: '134234623462346'
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await u.waitUntil(() => _converse.chatboxviews.keys().length > 1, 1000);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
@ -2111,7 +2107,7 @@
|
||||
['rosterGroupsFetched', 'emojisInitialized'], {'allow_non_roster_messaging': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const contact_jid = 'someone@montague.lit';
|
||||
const msgid = u.getUniqueId();
|
||||
const stanza = u.toStanza(`
|
||||
|
@ -13,11 +13,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
test_utils.openControlBox();
|
||||
_converse.minimized_chats.toggleview.model.browserStorage._clear();
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
_converse.minimized_chats.initToggle();
|
||||
|
||||
let contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -48,11 +45,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
test_utils.openControlBox();
|
||||
_converse.minimized_chats.toggleview.model.browserStorage._clear();
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
_converse.minimized_chats.initToggle();
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -74,13 +68,10 @@
|
||||
it("shows the number messages received to minimized chats",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
test_utils.openControlBox();
|
||||
_converse.minimized_chats.toggleview.model.browserStorage._clear();
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
_converse.minimized_chats.initToggle();
|
||||
|
||||
var i, contact_jid, chatview, msg;
|
||||
|
117
spec/muc.js
117
spec/muc.js
@ -28,12 +28,12 @@
|
||||
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
|
||||
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy();
|
||||
|
||||
_converse.api.roomviews.close('lounge@montague.lit');
|
||||
await _converse.api.roomviews.close('lounge@montague.lit');
|
||||
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
|
||||
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
|
||||
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy();
|
||||
|
||||
_converse.api.roomviews.close(['leisure@montague.lit', 'news@montague.lit']);
|
||||
await _converse.api.roomviews.close(['leisure@montague.lit', 'news@montague.lit']);
|
||||
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
|
||||
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
|
||||
expect(_converse.chatboxviews.get('news@montague.lit')).toBeUndefined();
|
||||
@ -41,7 +41,7 @@
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'leisure@montague.lit', 'romeo');
|
||||
expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit').el)).toBeTruthy();
|
||||
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy();
|
||||
_converse.api.roomviews.close();
|
||||
await _converse.api.roomviews.close();
|
||||
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
|
||||
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
|
||||
done();
|
||||
@ -52,7 +52,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length, 300);
|
||||
let muc_jid = 'chillout@montague.lit';
|
||||
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
@ -63,7 +63,7 @@
|
||||
expect(chatroomview.is_chatroom).toBeTruthy();
|
||||
|
||||
expect(u.isVisible(chatroomview.el)).toBeTruthy();
|
||||
chatroomview.close();
|
||||
await chatroomview.close();
|
||||
|
||||
// Test with mixed case
|
||||
muc_jid = 'Leisure@montague.lit';
|
||||
@ -105,8 +105,8 @@
|
||||
|
||||
let jid = 'lounge@montague.lit';
|
||||
let chatroomview, IQ_id;
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length);
|
||||
let room = await _converse.api.rooms.open(jid);
|
||||
// Test on groupchat that's not yet open
|
||||
@ -121,7 +121,7 @@
|
||||
chatroomview = _converse.chatboxviews.get(jid);
|
||||
expect(chatroomview.is_chatroom).toBeTruthy();
|
||||
expect(u.isVisible(chatroomview.el)).toBeTruthy();
|
||||
chatroomview.close();
|
||||
await chatroomview.close();
|
||||
|
||||
// Test with mixed case in JID
|
||||
jid = 'Leisure@montague.lit';
|
||||
@ -489,10 +489,9 @@
|
||||
}).c('body').t(message).tree();
|
||||
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
spyOn(view.model, 'clearMessages').and.callThrough();
|
||||
view.model.close();
|
||||
await view.model.close();
|
||||
await u.waitUntil(() => view.model.clearMessages.calls.count());
|
||||
expect(view.model.messages.length).toBe(0);
|
||||
expect(view.content.innerHTML).toBe('');
|
||||
@ -504,7 +503,7 @@
|
||||
['rosterGroupsFetched', 'emojisInitialized'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
if (!view.el.querySelectorAll('.chat-area').length) {
|
||||
@ -521,7 +520,6 @@
|
||||
}).c('body').t(message).tree();
|
||||
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
view.el.querySelector('.chat-msg__text a').click();
|
||||
await u.waitUntil(() => _converse.chatboxes.length === 3)
|
||||
expect(_.includes(_converse.chatboxes.pluck('id'), 'coven@chat.shakespeare.lit')).toBe(true);
|
||||
@ -890,6 +888,8 @@
|
||||
</x>
|
||||
</presence>`);
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
await u.waitUntil(() => sizzle('div.chat-info', chat_content).length > 3);
|
||||
|
||||
expect(sizzle('div.chat-info', chat_content).length).toBe(4);
|
||||
expect(sizzle('div.chat-info:last', chat_content).pop().textContent.trim()).toBe("jcbrand has entered the groupchat");
|
||||
|
||||
@ -1106,7 +1106,6 @@
|
||||
}).c('body').t('Some message').tree();
|
||||
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
let stanza = u.toStanza(
|
||||
`<presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="conversations@conference.siacs.eu/Guus">
|
||||
@ -1307,7 +1306,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
|
||||
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
if (!view.el.querySelectorAll('.chat-area').length) {
|
||||
@ -1322,7 +1321,6 @@
|
||||
'type': 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, '**Dyon van de Wege')).toBeTruthy();
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent.trim()).toBe('is tired');
|
||||
|
||||
@ -1334,7 +1332,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(_.includes(sizzle('.chat-msg__author:last', view.el).pop().textContent, '**Romeo Montague')).toBeTruthy();
|
||||
expect(sizzle('.chat-msg__text:last', view.el).pop().textContent.trim()).toBe('is as well');
|
||||
done();
|
||||
@ -1931,11 +1928,8 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current'); // We need roster contacts, so that we have someone to invite
|
||||
// Since we don't actually fetch roster contacts, we need to
|
||||
// cheat here and emit the event.
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
// We need roster contacts, so that we have someone to invite
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const features = [
|
||||
'http://jabber.org/protocol/muc',
|
||||
'jabber:iq:register',
|
||||
@ -1994,14 +1988,16 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current'); // We need roster contacts, who can invite us
|
||||
await test_utils.waitForRoster(_converse, 'current'); // We need roster contacts, who can invite us
|
||||
const name = mock.cur_names[0];
|
||||
const from_jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => _converse.roster.get(from_jid).vcard.get('fullname'));
|
||||
|
||||
spyOn(window, 'confirm').and.callFake(() => true);
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
view.close(); // Hack, otherwise we have to mock stanzas.
|
||||
await view.close(); // Hack, otherwise we have to mock stanzas.
|
||||
|
||||
const name = mock.cur_names[0];
|
||||
const from_jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
const reason = "Please join this groupchat";
|
||||
|
||||
@ -2012,7 +2008,8 @@
|
||||
<message xmlns="jabber:client" to="${_converse.bare_jid}" from="${from_jid}" id="9bceb415-f34b-4fa4-80d5-c0d076a24231">
|
||||
<x xmlns="jabber:x:conference" jid="${muc_jid}" reason="${reason}"/>
|
||||
</message>`);
|
||||
_converse.onDirectMUCInvitation(stanza);
|
||||
await _converse.onDirectMUCInvitation(stanza);
|
||||
|
||||
expect(window.confirm).toHaveBeenCalledWith(
|
||||
name + ' has invited you to join a groupchat: '+ muc_jid +
|
||||
', and left the following reason: "'+reason+'"');
|
||||
@ -2047,7 +2044,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t(text);
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
expect(chat_content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(chat_content.querySelector('.chat-msg__text').textContent.trim()).toBe(text);
|
||||
@ -2107,21 +2103,22 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
var message = 'This message is received while the chat area is scrolled up';
|
||||
const message = 'This message is received while the chat area is scrolled up';
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
var view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
spyOn(view, 'scrollDown').and.callThrough();
|
||||
// Create enough messages so that there's a scrollbar.
|
||||
const promises = [];
|
||||
for (var i=0; i<20; i++) {
|
||||
view.model.onMessage(
|
||||
$msg({
|
||||
from: 'lounge@montague.lit/someone',
|
||||
to: 'romeo@montague.lit.com',
|
||||
type: 'groupchat',
|
||||
id: (new Date()).getTime(),
|
||||
}).c('body').t('Message: '+i).tree());
|
||||
promises.push(new Promise(resolve => view.once('messageInserted', resolve)))
|
||||
for (let i=0; i<20; i++) {
|
||||
promises.push(
|
||||
view.model.onMessage(
|
||||
$msg({
|
||||
from: 'lounge@montague.lit/someone',
|
||||
to: 'romeo@montague.lit.com',
|
||||
type: 'groupchat',
|
||||
id: (new Date()).getTime(),
|
||||
}).c('body').t('Message: '+i).tree())
|
||||
);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
// Give enough time for `markScrolled` to have been called
|
||||
@ -2134,8 +2131,6 @@
|
||||
type: 'groupchat',
|
||||
id: (new Date()).getTime(),
|
||||
}).c('body').t(message).tree());
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
// Now check that the message appears inside the chatbox in the DOM
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
const msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
|
||||
@ -2765,12 +2760,14 @@
|
||||
await test_utils.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
|
||||
// We instantiate a new ChatBoxes collection, which by default
|
||||
// will be empty.
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const newchatboxes = new _converse.ChatBoxes();
|
||||
expect(newchatboxes.length).toEqual(0);
|
||||
// The chatboxes will then be fetched from browserStorage inside the
|
||||
// onConnected method
|
||||
newchatboxes.onConnected();
|
||||
await new Promise(resolve => _converse.api.listen.once('chatBoxesFetched', resolve));
|
||||
|
||||
expect(newchatboxes.length).toEqual(2);
|
||||
// Check that the chatrooms retrieved from browserStorage
|
||||
// have the same attributes values as the original ones.
|
||||
@ -2834,6 +2831,7 @@
|
||||
view.el.querySelector('.close-chatbox-button').click();
|
||||
expect(view.close).toHaveBeenCalled();
|
||||
expect(view.model.leave).toHaveBeenCalled();
|
||||
await u.waitUntil(() => _converse.api.trigger.calls.count());
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
|
||||
done();
|
||||
}));
|
||||
@ -2952,12 +2950,15 @@
|
||||
textarea = view.el.querySelector('.chat-textarea');
|
||||
textarea.value = '/clear';
|
||||
view.onKeyDown(enter);
|
||||
await u.waitUntil(() => sizzle('.chat-info:not(.chat-event)', view.el).length === 0);
|
||||
|
||||
textarea.value = '/help';
|
||||
view.onKeyDown(enter);
|
||||
info_messages = sizzle('.chat-info', view.el).slice(1);
|
||||
expect(info_messages.length).toBe(18);
|
||||
info_messages = sizzle('.chat-info:not(.chat-event)', view.el);
|
||||
expect(info_messages.length).toBe(19);
|
||||
let commands = info_messages.map(m => m.textContent.replace(/:.*$/, ''));
|
||||
expect(commands).toEqual([
|
||||
"You can run the following commands",
|
||||
"/admin", "/ban", "/clear", "/deop", "/destroy",
|
||||
"/help", "/kick", "/me", "/member", "/modtools", "/mute", "/nick",
|
||||
"/op", "/register", "/revoke", "/subject", "/topic", "/voice"
|
||||
@ -3004,7 +3005,7 @@
|
||||
textarea.value = '/help';
|
||||
view.onKeyDown(enter);
|
||||
|
||||
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
||||
const info_messages = sizzle('.chat-info:not(.chat-event)', view.el);
|
||||
expect(info_messages.length).toBe(18);
|
||||
expect(info_messages.pop().textContent.trim()).toBe('/topic: Set groupchat subject (alias for /subject)');
|
||||
expect(info_messages.pop().textContent.trim()).toBe('/subject: Set groupchat subject');
|
||||
@ -3854,7 +3855,7 @@
|
||||
expect(_converse.chatboxes.length).toBe(2);
|
||||
_converse.connection._dataRecv(test_utils.createRequest(result_stanza));
|
||||
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
|
||||
expect(_converse.chatboxes.length).toBe(1);
|
||||
await u.waitUntil(() => _converse.chatboxes.length === 1);
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
|
||||
done();
|
||||
}));
|
||||
@ -4269,6 +4270,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
|
||||
const sent_IQs = _converse.connection.IQ_stanzas;
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
@ -4304,7 +4306,7 @@
|
||||
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
|
||||
expect(view.model.features.get('membersonly')).toBeTruthy();
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.createContacts(_converse, 'current');
|
||||
|
||||
let sent_stanza, sent_id;
|
||||
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
|
||||
@ -4480,7 +4482,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
@ -4522,7 +4524,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'locked_muc_nickname': true, 'muc_nickname_from_jid': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
@ -4545,7 +4547,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'muc_nickname_from_jid': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
@ -4564,7 +4566,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'nickname': 'st.nick'},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
@ -4583,7 +4585,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org'},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
const modal = roomspanel.add_room_modal;
|
||||
@ -4623,7 +4625,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org', 'locked_muc_domain': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
const modal = roomspanel.add_room_modal;
|
||||
@ -4665,7 +4667,7 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-list-muc-modal').click();
|
||||
test_utils.closeControlBox(_converse);
|
||||
@ -4742,7 +4744,7 @@
|
||||
{'muc_domain': 'muc.example.org'},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-list-muc-modal').click();
|
||||
test_utils.closeControlBox(_converse);
|
||||
@ -4759,7 +4761,7 @@
|
||||
{'muc_domain': 'chat.shakespeare.lit', 'locked_muc_domain': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
roomspanel.el.querySelector('.show-list-muc-modal').click();
|
||||
test_utils.closeControlBox(_converse);
|
||||
@ -4809,7 +4811,7 @@
|
||||
['rosterGroupsFetched', 'emojisInitialized'], {'allow_bookmarks': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(0);
|
||||
|
||||
@ -4890,7 +4892,7 @@
|
||||
// Romeo loses his voice
|
||||
const presence = $pres({
|
||||
to: 'romeo@montague.lit/orchard',
|
||||
from: `${muc_jid}/some1`
|
||||
from: `${muc_jid}/romeo`
|
||||
}).c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {'affiliation': 'none', 'role': 'visitor'}).up()
|
||||
.c('status', {code: '110'});
|
||||
@ -5027,7 +5029,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('hello world').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
|
||||
const messages = view.el.querySelectorAll('.message');
|
||||
expect(messages.length).toBe(7);
|
||||
|
@ -65,7 +65,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(u.hasClass('mentioned', view.el.querySelector('.chat-msg'))).toBeTruthy();
|
||||
done();
|
||||
}));
|
||||
@ -87,8 +86,7 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('First message').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 1);
|
||||
|
||||
msg = $msg({
|
||||
from: 'lounge@montague.lit/some2',
|
||||
@ -97,8 +95,8 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Another message').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 2);
|
||||
expect(view.model.messages.length).toBe(2);
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -154,7 +152,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const muc_jid = 'xsf@muc.xmpp.org';
|
||||
const sender_jid = `${muc_jid}/romeo`;
|
||||
const impersonated_jid = `${muc_jid}/i_am_groot`
|
||||
@ -223,7 +221,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('I wrote this message!').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.model.messages.last().occupant.get('affiliation')).toBe('owner');
|
||||
expect(view.model.messages.last().occupant.get('role')).toBe('moderator');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
@ -250,7 +247,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Another message!').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', 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);
|
||||
@ -286,7 +282,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Message from someone not in the MUC right now').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', 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);
|
||||
@ -351,7 +346,6 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('I wrote this message!').tree();
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.model.messages.last().get('sender')).toBe('me');
|
||||
done();
|
||||
}));
|
||||
@ -382,7 +376,6 @@
|
||||
'type': 'groupchat',
|
||||
'id': msg_id,
|
||||
}).c('body').t('But soft, what light through yonder airlock breaks?').tree());
|
||||
await new Promise(resolve => view.once('messageInserted', 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?');
|
||||
@ -445,8 +438,7 @@
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
@ -503,7 +495,6 @@
|
||||
'to': 'romeo@montague.lit',
|
||||
'type': 'groupchat'
|
||||
}).c('body').t('Hello world').tree());
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
|
||||
// Test that pressing the down arrow cancels message correction
|
||||
@ -744,7 +735,6 @@
|
||||
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'11', 'end':'14', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).up()
|
||||
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'15', 'end':'23', 'type':'mention', 'uri':'xmpp:mr.robot@montague.lit'}).nodeTree;
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
const messages = view.el.querySelectorAll('.chat-msg__text');
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].classList.length).toEqual(1);
|
||||
|
@ -40,7 +40,7 @@
|
||||
it("is shown when you are mentioned in a groupchat",
|
||||
mock.initConverse(['rosterGroupsFetched'], {}, async (done, _converse) => {
|
||||
|
||||
await test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
const view = _converse.api.chatviews.get('lounge@montague.lit');
|
||||
if (!view.el.querySelectorAll('.chat-area').length) {
|
||||
@ -66,10 +66,10 @@
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
|
||||
_converse.connection._dataRecv(test_utils.createRequest(msg));
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
||||
|
||||
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
|
||||
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
||||
if (no_notification) {
|
||||
delete window.Notification;
|
||||
@ -128,16 +128,16 @@
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is shown when a user changes their chat state (if show_chat_state_notifications is true)", mock.initConverse((done, _converse) => {
|
||||
// TODO: not yet testing show_desktop_notifications setting
|
||||
_converse.show_chat_state_notifications = true;
|
||||
it("is shown when a user changes their chat state (if show_chat_state_notifications is true)",
|
||||
mock.initConverse(['rosterGroupsFetched'], {show_chat_state_notifications: true},
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current', 3);
|
||||
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
||||
spyOn(_converse, 'showChatStateNotification');
|
||||
const jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'busy'); // This will emit 'contactStatusChanged'
|
||||
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
||||
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
|
||||
expect(_converse.showChatStateNotification).toHaveBeenCalled();
|
||||
done()
|
||||
}));
|
||||
|
@ -81,8 +81,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
const message = 'This message will be encrypted'
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const view = await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
const payload = await view.model.encryptMessage(message);
|
||||
@ -98,8 +97,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
let sent_stanza;
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => initializedOMEMO(_converse));
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -386,8 +384,7 @@
|
||||
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
|
||||
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await u.waitUntil(() => initializedOMEMO(_converse));
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
@ -605,8 +602,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.NUM_PREKEYS = 5; // Restrict to 5, otherwise the resulting stanza is too large to easily test
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
await u.waitUntil(() => initializedOMEMO(_converse));
|
||||
@ -710,7 +706,7 @@
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
// Wait until own devices are fetched
|
||||
@ -884,7 +880,7 @@
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
|
||||
expect(Strophe.serialize(iq_stanza)).toBe(
|
||||
@ -1036,8 +1032,7 @@
|
||||
|
||||
_converse.NUM_PREKEYS = 2; // Restrict to 2, otherwise the resulting stanza is too large to easily test
|
||||
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
|
||||
let stanza = $iq({
|
||||
@ -1113,8 +1108,7 @@
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
|
||||
@ -1460,8 +1454,7 @@
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid)
|
||||
// We simply emit, to avoid doing all the setup work
|
||||
|
@ -74,7 +74,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const view = _converse.xmppstatusview;
|
||||
spyOn(view.model, 'sendPresence').and.callThrough();
|
||||
spyOn(_converse.connection, 'send').and.callThrough();
|
||||
@ -112,12 +112,12 @@
|
||||
it("has its priority taken into account",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
(done, _converse) => {
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
|
||||
test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
const contact_jid = mock.cur_names[8].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const contact = _converse.roster.get(contact_jid);
|
||||
const contact = await _converse.api.contacts.get(contact_jid);
|
||||
let stanza = u.toStanza(`
|
||||
<presence xmlns="jabber:client"
|
||||
to="romeo@montague.lit/converse.js-21770972"
|
||||
|
@ -13,7 +13,7 @@
|
||||
['rosterGroupsFetched'], {'muc_show_join_leave': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
_.rangeRight(3000, 0).forEach(i => {
|
||||
const name = `User ${i.toString().padStart(5, '0')}`;
|
||||
@ -41,7 +41,7 @@
|
||||
function (done, _converse) {
|
||||
|
||||
_converse.roster_groups = false;
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
|
||||
expect(_converse.roster.pluck('jid').length).toBe(0);
|
||||
var stanza = $iq({
|
||||
@ -86,7 +86,7 @@
|
||||
|
||||
// _converse.show_only_online_users = true;
|
||||
_converse.roster_groups = true;
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
|
||||
expect(_converse.roster.pluck('jid').length).toBe(0);
|
||||
var stanza = $iq({
|
||||
|
@ -5,9 +5,9 @@
|
||||
"test-utils"], factory);
|
||||
} (this, function (jasmine, mock, test_utils) {
|
||||
"use strict";
|
||||
const Strophe = converse.env.Strophe;
|
||||
const $iq = converse.env.$iq;
|
||||
const $pres = converse.env.$pres;
|
||||
const Strophe = converse.env.Strophe;
|
||||
const _ = converse.env._;
|
||||
const sizzle = converse.env.sizzle;
|
||||
const u = converse.env.utils;
|
||||
@ -175,7 +175,7 @@
|
||||
*/
|
||||
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => s.match('presence')).pop());
|
||||
expect(contact.subscribe).toHaveBeenCalled();
|
||||
expect(sent_presence).toBe( // Strophe adds the xmlns attr (although not in spec)
|
||||
expect(sent_presence).toBe(
|
||||
`<presence to="contact@example.org" type="subscribe" xmlns="jabber:client">`+
|
||||
`<nick xmlns="http://jabber.org/protocol/nick">Romeo Montague</nick>`+
|
||||
`</presence>`
|
||||
@ -455,18 +455,13 @@
|
||||
{ roster_groups: false },
|
||||
async function (done, _converse) {
|
||||
|
||||
var sent_IQ, IQ_id, jid = 'abram@montague.lit';
|
||||
test_utils.openControlBox(_converse);
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
const jid = 'abram@montague.lit';
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
// We now have a contact we want to remove
|
||||
expect(_converse.roster.get(jid) instanceof _converse.RosterContact).toBeTruthy();
|
||||
|
||||
var sendIQ = _converse.connection.sendIQ;
|
||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||
sent_IQ = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
const header = sizzle('a:contains("My contacts")', _converse.rosterview.el).pop();
|
||||
await u.waitUntil(() => header.parentElement.querySelectorAll('li').length);
|
||||
|
||||
@ -493,8 +488,9 @@
|
||||
* </query>
|
||||
* </iq>
|
||||
*/
|
||||
expect(sent_IQ.toLocaleString()).toBe(
|
||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||
const sent_iq = _converse.connection.IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(sent_iq)).toBe(
|
||||
`<iq id="${sent_iq.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:roster">`+
|
||||
`<item jid="abram@montague.lit" subscription="remove"/>`+
|
||||
`</query>`+
|
||||
@ -502,7 +498,7 @@
|
||||
|
||||
// Receive confirmation from the contact's server
|
||||
// <iq type='result' id='remove1'/>
|
||||
const stanza = $iq({'type': 'result', 'id':IQ_id});
|
||||
const stanza = $iq({'type': 'result', 'id': sent_iq.getAttribute('id')});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
// Our contact has now been removed
|
||||
await u.waitUntil(() => typeof _converse.roster.get(jid) === "undefined");
|
||||
@ -514,9 +510,8 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
test_utils.openControlBox(_converse);
|
||||
// Create some contacts so that we can test positioning
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
/* <presence
|
||||
* from='user@example.com'
|
||||
* to='contact@example.org'
|
||||
@ -534,7 +529,7 @@
|
||||
const header = sizzle('a:contains("Contact requests")', _converse.rosterview.el).pop();
|
||||
const contacts = _.filter(header.parentElement.querySelectorAll('li'), u.isVisible);
|
||||
return contacts.length;
|
||||
}, 300);
|
||||
}, 500);
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
|
||||
const header = sizzle('a:contains("Contact requests")', _converse.rosterview.el).pop();
|
||||
expect(u.isVisible(header)).toBe(true);
|
||||
|
@ -16,8 +16,7 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await u.waitUntil(() => _converse.chatboxviews.get('controlbox'));
|
||||
test_utils.openControlBox();
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
const cbview = _converse.api.controlbox.get();
|
||||
expect(cbview.el.querySelectorAll('a.register-account').length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
@ -29,15 +28,22 @@
|
||||
allow_registration: true },
|
||||
async function (done, _converse) {
|
||||
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
}
|
||||
toggle.click();
|
||||
}
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'), 300);
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
test_utils.openControlBox();
|
||||
const panels = cbview.el.querySelector('.controlbox-panes');
|
||||
const login = panels.firstElementChild;
|
||||
const registration = panels.childNodes[1];
|
||||
const register_link = cbview.el.querySelector('a.register-account');
|
||||
expect(register_link.textContent).toBe("Create an account");
|
||||
register_link.click();
|
||||
|
||||
await u.waitUntil(() => u.isVisible(registration));
|
||||
expect(u.isVisible(login)).toBe(false);
|
||||
done();
|
||||
@ -52,8 +58,7 @@
|
||||
|
||||
spyOn(Strophe.Connection.prototype, 'connect');
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
|
||||
test_utils.openControlBox();
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
const cbview = _converse.api.controlbox.get();
|
||||
const registerview = cbview.registerpanel;
|
||||
spyOn(registerview, 'onProviderChosen').and.callThrough();
|
||||
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
|
||||
@ -88,8 +93,7 @@
|
||||
|
||||
spyOn(Strophe.Connection.prototype, 'connect');
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
|
||||
test_utils.openControlBox();
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
const cbview = _converse.api.controlbox.get();
|
||||
cbview.el.querySelector('.toggle-register-login').click();
|
||||
|
||||
const registerview = _converse.chatboxviews.get('controlbox').registerpanel;
|
||||
@ -100,7 +104,7 @@
|
||||
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
|
||||
|
||||
expect(registerview._registering).toBeFalsy();
|
||||
expect(_converse.connection.connected).toBeFalsy();
|
||||
expect(_converse.api.connection.connected()).toBeFalsy();
|
||||
registerview.el.querySelector('input[name=domain]').value = 'conversejs.org';
|
||||
registerview.el.querySelector('input[type=submit]').click();
|
||||
expect(registerview.onProviderChosen).toHaveBeenCalled();
|
||||
@ -143,8 +147,14 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
|
||||
test_utils.openControlBox();
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
}
|
||||
toggle.click();
|
||||
}
|
||||
const cbview = _converse.api.controlbox.get();
|
||||
cbview.el.querySelector('.toggle-register-login').click();
|
||||
|
||||
const registerview = cbview.registerpanel;
|
||||
@ -153,7 +163,6 @@
|
||||
spyOn(registerview, 'onRegistrationFields').and.callThrough();
|
||||
spyOn(registerview, 'renderRegistrationForm').and.callThrough();
|
||||
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
|
||||
spyOn(_converse.connection, 'connect').and.callThrough();
|
||||
|
||||
registerview.el.querySelector('input[name=domain]').value = 'conversejs.org';
|
||||
registerview.el.querySelector('input[type=submit]').click();
|
||||
@ -200,8 +209,14 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
|
||||
test_utils.openControlBox();
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
}
|
||||
toggle.click();
|
||||
}
|
||||
const cbview = _converse.api.controlbox.get();
|
||||
cbview.el.querySelector('.toggle-register-login').click();
|
||||
const registerview = _converse.chatboxviews.get('controlbox').registerpanel;
|
||||
spyOn(registerview, 'onProviderChosen').and.callThrough();
|
||||
@ -209,7 +224,6 @@
|
||||
spyOn(registerview, 'onRegistrationFields').and.callThrough();
|
||||
spyOn(registerview, 'renderRegistrationForm').and.callThrough();
|
||||
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
|
||||
spyOn(_converse.connection, 'connect').and.callThrough();
|
||||
|
||||
registerview.el.querySelector('input[name=domain]').value = 'conversejs.org';
|
||||
registerview.el.querySelector('input[type=submit]').click();
|
||||
@ -274,7 +288,13 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
|
||||
test_utils.openControlBox();
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
}
|
||||
toggle.click();
|
||||
}
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.toggle-register-login').click();
|
||||
const registerview = _converse.chatboxviews.get('controlbox').registerpanel;
|
||||
|
@ -13,7 +13,7 @@
|
||||
// have to mock stanza traffic.
|
||||
}, async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const controlbox = _converse.chatboxviews.get('controlbox');
|
||||
let list = controlbox.el.querySelector('.list-container--openrooms');
|
||||
expect(_.includes(list.classList, 'hidden')).toBeTruthy();
|
||||
@ -31,7 +31,7 @@
|
||||
expect(room_els.length).toBe(2);
|
||||
|
||||
let view = _converse.chatboxviews.get('room@conference.shakespeare.lit');
|
||||
view.close();
|
||||
await view.close();
|
||||
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
|
||||
expect(room_els.length).toBe(1);
|
||||
expect(room_els[0].innerText).toBe('lounge@montague.lit');
|
||||
@ -39,7 +39,7 @@
|
||||
u.waitUntil(() => _.includes(list.classList, 'hidden'));
|
||||
|
||||
view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
view.close();
|
||||
await view.close();
|
||||
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
|
||||
expect(room_els.length).toBe(0);
|
||||
|
||||
@ -110,19 +110,21 @@
|
||||
describe("A groupchat shown in the groupchats list", function () {
|
||||
|
||||
it("is highlighted if it's currently open", mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'],
|
||||
{ view_mode: 'fullscreen',
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
|
||||
}, async function (done, _converse) {
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'],
|
||||
{ view_mode: 'fullscreen',
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
|
||||
}, async function (done, _converse) {
|
||||
|
||||
await _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await _converse.api.rooms.open(muc_jid, {'nick': 'some1'});
|
||||
const lview = _converse.rooms_list_view
|
||||
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
|
||||
let room_els = lview.el.querySelectorAll(".available-chatroom");
|
||||
expect(room_els.length).toBe(1);
|
||||
|
||||
let item = room_els[0];
|
||||
expect(u.hasClass('open', item)).toBe(true);
|
||||
await u.waitUntil(() => lview.model.get(muc_jid).get('hidden') === false);
|
||||
await u.waitUntil(() => u.hasClass('open', item), 1000);
|
||||
expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
|
||||
await _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'});
|
||||
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
|
||||
@ -137,15 +139,15 @@
|
||||
}));
|
||||
|
||||
it("has an info icon which opens a details modal when clicked", mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'],
|
||||
{ whitelisted_plugins: ['converse-roomslist'],
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we
|
||||
// have to mock stanza traffic.
|
||||
}, async function (done, _converse) {
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'],
|
||||
{ whitelisted_plugins: ['converse-roomslist'],
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we
|
||||
// have to mock stanza traffic.
|
||||
}, async function (done, _converse) {
|
||||
|
||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
const room_jid = 'coven@chat.shakespeare.lit';
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await _converse.api.rooms.open(room_jid, {'nick': 'some1'});
|
||||
const view = _converse.chatboxviews.get(room_jid);
|
||||
|
||||
@ -242,11 +244,11 @@
|
||||
}));
|
||||
|
||||
it("can be closed", mock.initConverse(
|
||||
['rosterGroupsFetched', 'emojisInitialized'],
|
||||
{ whitelisted_plugins: ['converse-roomslist'],
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
|
||||
},
|
||||
async function (done, _converse) {
|
||||
['rosterGroupsFetched', 'emojisInitialized'],
|
||||
{ whitelisted_plugins: ['converse-roomslist'],
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
|
||||
},
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(window, 'confirm').and.callFake(() => true);
|
||||
expect(_converse.chatboxes.length).toBe(1);
|
||||
@ -260,6 +262,8 @@
|
||||
close_el.click();
|
||||
expect(window.confirm).toHaveBeenCalledWith(
|
||||
'Are you sure you want to leave the groupchat lounge@conference.shakespeare.lit?');
|
||||
|
||||
await u.waitUntil(() => !_converse.api.rooms.get().length);
|
||||
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
|
||||
expect(room_els.length).toBe(0);
|
||||
expect(_converse.chatboxes.length).toBe(1);
|
||||
@ -272,7 +276,7 @@
|
||||
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
|
||||
}, async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
const room_jid = 'kitchen@conference.shakespeare.lit';
|
||||
await u.waitUntil(() => _converse.rooms_list_view !== undefined, 500);
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'kitchen@conference.shakespeare.lit', 'romeo');
|
||||
@ -287,12 +291,10 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('foo').tree());
|
||||
|
||||
const lview = _converse.rooms_list_view
|
||||
await u.waitUntil(() => lview.el.querySelectorAll(".available-chatroom").length, 500);
|
||||
|
||||
// If the user isn't mentioned, the counter doesn't get incremented, but the text of the groupchat is bold
|
||||
let room_el = lview.el.querySelector(".available-chatroom");
|
||||
expect(_.includes(room_el.classList, 'unread-msgs')).toBeTruthy();
|
||||
const lview = _converse.rooms_list_view
|
||||
let room_el = await u.waitUntil(() => lview.el.querySelector(".available-chatroom"));
|
||||
expect(Array.from(room_el.classList).includes('unread-msgs')).toBeTruthy();
|
||||
|
||||
// If the user is mentioned, the counter also gets updated
|
||||
await view.model.onMessage(
|
||||
@ -303,10 +305,11 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('romeo: Your attention is required').tree()
|
||||
);
|
||||
await u.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".msgs-indicator").length);
|
||||
spyOn(view.model, 'incrementUnreadMsgCounter').and.callThrough();
|
||||
let indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
|
||||
|
||||
let indicator_el = await u.waitUntil(() => lview.el.querySelector(".msgs-indicator"));
|
||||
expect(indicator_el.textContent).toBe('1');
|
||||
|
||||
spyOn(view.model, 'incrementUnreadMsgCounter').and.callThrough();
|
||||
await view.model.onMessage(
|
||||
$msg({
|
||||
from: room_jid+'/'+nick,
|
||||
@ -316,14 +319,13 @@
|
||||
}).c('body').t('romeo: and another thing...').tree()
|
||||
);
|
||||
await u.waitUntil(() => view.model.incrementUnreadMsgCounter.calls.count());
|
||||
indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
|
||||
expect(indicator_el.textContent).toBe('2');
|
||||
await u.waitUntil(() => lview.el.querySelector(".msgs-indicator").textContent === '2', 1000);
|
||||
|
||||
// When the chat gets maximized again, the unread indicators are removed
|
||||
view.model.set({'minimized': false});
|
||||
indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
|
||||
indicator_el = lview.el.querySelector(".msgs-indicator");
|
||||
expect(indicator_el === null);
|
||||
room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom");
|
||||
room_el = lview.el.querySelector(".available-chatroom");
|
||||
expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy();
|
||||
done();
|
||||
}));
|
||||
|
404
spec/roster.js
404
spec/roster.js
@ -74,11 +74,9 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
const IQs = _converse.connection.IQ_stanzas;
|
||||
const stanza = await u.waitUntil(
|
||||
() => _.filter(IQs, iq => iq.querySelector('iq query[xmlns="jabber:iq:roster"]')).pop());
|
||||
expect(_converse.api.trigger.calls.all().map(c => c.args[0]).includes('rosterContactsFetched')).toBeFalsy();
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq id="${stanza.getAttribute('id')}" type="get" xmlns="jabber:client">`+
|
||||
@ -93,7 +91,7 @@
|
||||
}).c('item', {'jid': 'nurse@example.com'}).up()
|
||||
.c('item', {'jid': 'romeo@example.com'})
|
||||
_converse.connection._dataRecv(test_utils.createRequest(result));
|
||||
await u.waitUntil(() => _converse.api.trigger.calls.all().map(c => c.args[0]).includes('rosterContactsFetched'));
|
||||
await u.waitUntil(() => _converse.promises['rosterContactsFetched'].isResolved === true);
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -160,9 +158,9 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
const filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
test_utils.openControlBox();
|
||||
expect(filter === null).toBe(false);
|
||||
test_utils.createContacts(_converse, 'current').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
|
||||
const view = _converse.chatboxviews.get('controlbox');
|
||||
const flyout = view.el.querySelector('.box-flyout');
|
||||
@ -180,13 +178,13 @@
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
let filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
const roster = _converse.rosterview.roster_el;
|
||||
_converse.rosterview.filter_view.delegateEvents();
|
||||
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 17), 600);
|
||||
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(5);
|
||||
filter.value = "juliet";
|
||||
u.triggerEvent(filter, "keydown", "KeyboardEvent");
|
||||
@ -198,7 +196,7 @@
|
||||
// Only one foster group is still visible
|
||||
expect(sizzle('.roster-group', roster).filter(u.isVisible).length).toBe(1);
|
||||
const visible_group = sizzle('.roster-group', roster).filter(u.isVisible).pop();
|
||||
expect(visible_group.querySelector('a.group-toggle').textContent.trim()).toBe('colleagues');
|
||||
expect(visible_group.querySelector('a.group-toggle').textContent.trim()).toBe('friends & acquaintences');
|
||||
|
||||
filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
filter.value = "j";
|
||||
@ -210,7 +208,7 @@
|
||||
|
||||
let visible_groups = sizzle('.roster-group', roster).filter(u.isVisible).map(el => el.querySelector('a.group-toggle'));
|
||||
expect(visible_groups.length).toBe(2);
|
||||
expect(visible_groups[0].textContent.trim()).toBe('colleagues');
|
||||
expect(visible_groups[0].textContent.trim()).toBe('friends & acquaintences');
|
||||
expect(visible_groups[1].textContent.trim()).toBe('Ungrouped');
|
||||
|
||||
filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
@ -223,7 +221,7 @@
|
||||
filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
filter.value = "";
|
||||
u.triggerEvent(filter, "keydown", "KeyboardEvent");
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 17), 600);
|
||||
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(5);
|
||||
done();
|
||||
}));
|
||||
@ -233,26 +231,27 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
|
||||
const filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
const roster = _converse.rosterview.roster_el;
|
||||
_converse.rosterview.filter_view.delegateEvents();
|
||||
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 17), 800);
|
||||
filter.value = "la";
|
||||
u.triggerEvent(filter, "keydown", "KeyboardEvent");
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 3), 600);
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 4), 800);
|
||||
|
||||
// Five roster contact is now visible
|
||||
const visible_contacts = sizzle('li', roster).filter(u.isVisible);
|
||||
expect(visible_contacts.length).toBe(3);
|
||||
expect(visible_contacts.length).toBe(4);
|
||||
let visible_groups = sizzle('.roster-group', roster).filter(u.isVisible).map(el => el.querySelector('a.group-toggle'));
|
||||
expect(visible_groups.length).toBe(3);
|
||||
expect(visible_groups[0].textContent.trim()).toBe('colleagues');
|
||||
expect(visible_groups.length).toBe(4);
|
||||
expect(visible_groups[0].textContent.trim()).toBe('Colleagues');
|
||||
expect(visible_groups[1].textContent.trim()).toBe('Family');
|
||||
expect(visible_groups[2].textContent.trim()).toBe('friends & acquaintences');
|
||||
expect(visible_groups[3].textContent.trim()).toBe('ænemies');
|
||||
|
||||
_converse.roster.create({
|
||||
jid: 'valentine@montague.lit',
|
||||
@ -264,10 +263,11 @@
|
||||
await u.waitUntil(() => sizzle('.roster-group[data-group="newgroup"] li', roster).length, 300);
|
||||
visible_groups = sizzle('.roster-group', roster).filter(u.isVisible).map(el => el.querySelector('a.group-toggle'));
|
||||
// The "newgroup" group doesn't appear
|
||||
expect(visible_groups.length).toBe(3);
|
||||
expect(visible_groups[0].textContent.trim()).toBe('colleagues');
|
||||
expect(visible_groups.length).toBe(4);
|
||||
expect(visible_groups[0].textContent.trim()).toBe('Colleagues');
|
||||
expect(visible_groups[1].textContent.trim()).toBe('Family');
|
||||
expect(visible_groups[2].textContent.trim()).toBe('friends & acquaintences');
|
||||
expect(visible_groups[3].textContent.trim()).toBe('ænemies');
|
||||
expect(roster.querySelectorAll('.roster-group').length).toBe(6);
|
||||
done();
|
||||
}));
|
||||
@ -277,15 +277,15 @@
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
_converse.rosterview.filter_view.delegateEvents();
|
||||
var roster = _converse.rosterview.roster_el;
|
||||
|
||||
var button = _converse.rosterview.el.querySelector('span[data-type="groups"]');
|
||||
button.click();
|
||||
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
|
||||
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 17), 600);
|
||||
expect(sizzle('.roster-group', roster).filter(u.isVisible).length).toBe(5);
|
||||
|
||||
var filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
@ -293,8 +293,8 @@
|
||||
u.triggerEvent(filter, "keydown", "KeyboardEvent");
|
||||
|
||||
await u.waitUntil(() => (sizzle('div.roster-group:not(.collapsed)', roster).length === 1), 600);
|
||||
expect(sizzle('div.roster-group:not(.collapsed)', roster).pop().firstElementChild.textContent.trim()).toBe('colleagues');
|
||||
expect(sizzle('div.roster-group:not(.collapsed) li', roster).filter(u.isVisible).length).toBe(3);
|
||||
expect(sizzle('div.roster-group:not(.collapsed)', roster).pop().firstElementChild.textContent.trim()).toBe('Colleagues');
|
||||
expect(sizzle('div.roster-group:not(.collapsed) li', roster).filter(u.isVisible).length).toBe(6);
|
||||
// Check that all contacts under the group are shown
|
||||
expect(sizzle('div.roster-group:not(.collapsed) li', roster).filter(l => !u.isVisible(l)).length).toBe(0);
|
||||
|
||||
@ -310,18 +310,17 @@
|
||||
u.triggerEvent(filter, "keydown", "KeyboardEvent");
|
||||
await u.waitUntil(() => (roster.querySelectorAll('div.roster-group.collapsed').length === 0), 700);
|
||||
expect(sizzle('div.roster-group:not(collapsed)', roster).length).toBe(5);
|
||||
expect(sizzle('div.roster-group:not(collapsed) li', roster).length).toBe(15);
|
||||
expect(sizzle('div.roster-group:not(collapsed) li', roster).length).toBe(17);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("has a button with which its contents can be cleared",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.roster_groups = true;
|
||||
test_utils.openControlBox();
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
|
||||
const filter = _converse.rosterview.el.querySelector('.roster-filter');
|
||||
filter.value = "xxx";
|
||||
@ -343,12 +342,12 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
test_utils.waitForRoster(_converse, 'all');
|
||||
let jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'online');
|
||||
jid = mock.cur_names[4].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'dnd');
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const button = _converse.rosterview.el.querySelector('span[data-type="state"]');
|
||||
button.click();
|
||||
const roster = _converse.rosterview.roster_el;
|
||||
@ -375,26 +374,21 @@
|
||||
|
||||
it("can be used to organize existing contacts",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.roster_groups = true;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
_converse.rosterview.render();
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'pending');
|
||||
test_utils.createContacts(_converse, 'requesting');
|
||||
test_utils.createGroupedContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await test_utils.createContacts(_converse, 'requesting');
|
||||
// Check that the groups appear alphabetically and that
|
||||
// requesting and pending contacts are last.
|
||||
await u.waitUntil(() => sizzle('.roster-group a.group-toggle', _converse.rosterview.el).length);
|
||||
const group_titles = _.map(
|
||||
sizzle('.roster-group a.group-toggle', _converse.rosterview.el),
|
||||
o => o.textContent.trim()
|
||||
);
|
||||
const group_titles = sizzle('.roster-group a.group-toggle', _converse.rosterview.el).map(o => o.textContent.trim());
|
||||
expect(group_titles).toEqual([
|
||||
"Contact requests",
|
||||
"colleagues",
|
||||
"Colleagues",
|
||||
"Family",
|
||||
"friends & acquaintences",
|
||||
"ænemies",
|
||||
@ -402,7 +396,7 @@
|
||||
"Pending contacts"
|
||||
]);
|
||||
// Check that usernames appear alphabetically per group
|
||||
_.each(_.keys(mock.groups), function (name) {
|
||||
Object.keys(mock.groups).forEach(name => {
|
||||
const contacts = sizzle('.roster-group[data-group="'+name+'"] ul', _converse.rosterview.el);
|
||||
const names = _.map(contacts, o => o.textContent.trim());
|
||||
expect(names).toEqual(_.clone(names).sort());
|
||||
@ -412,14 +406,14 @@
|
||||
|
||||
it("gets created when a contact's \"groups\" attribute changes",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.roster_groups = true;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
_converse.rosterview.render();
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
|
||||
_converse.roster.create({
|
||||
jid: 'groupchanger@montague.lit',
|
||||
@ -460,9 +454,9 @@
|
||||
['rosterGroupsFetched'], {'roster_groups': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
const groups = ['colleagues', 'friends'];
|
||||
const groups = ['Colleagues', 'friends'];
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
_converse.rosterview.render();
|
||||
for (var i=0; i<mock.cur_names.length; i++) {
|
||||
_converse.roster.create({
|
||||
@ -490,11 +484,11 @@
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.roster_groups = true;
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
|
||||
var i=0, j=0;
|
||||
var groups = {
|
||||
'colleagues': 3,
|
||||
'Colleagues': 3,
|
||||
'friends & acquaintences': 3,
|
||||
'Ungrouped': 2
|
||||
};
|
||||
@ -510,7 +504,7 @@
|
||||
});
|
||||
}
|
||||
});
|
||||
const view = _converse.rosterview.get('colleagues');
|
||||
const view = _converse.rosterview.get('Colleagues');
|
||||
const toggle = view.el.querySelector('a.group-toggle');
|
||||
expect(view.model.get('state')).toBe('opened');
|
||||
toggle.click();
|
||||
@ -523,18 +517,14 @@
|
||||
|
||||
describe("Pending Contacts", function () {
|
||||
|
||||
async function _addContacts (_converse) {
|
||||
// Must be initialized, so that render is called and documentFragment set up.
|
||||
test_utils.createContacts(_converse, 'pending').openControlBox()
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
}
|
||||
|
||||
it("can be collapsed under their own header",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await _addContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length, 1000);
|
||||
await checkHeaderToggling.apply(
|
||||
_converse,
|
||||
@ -546,10 +536,10 @@
|
||||
it("can be added to the roster",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
_converse.roster.create({
|
||||
jid: mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
subscription: 'none',
|
||||
@ -560,30 +550,15 @@
|
||||
done();
|
||||
}));
|
||||
|
||||
it("are shown in the roster when show_only_online_users",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
_converse.show_only_online_users = true;
|
||||
test_utils.openControlBox();
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
_addContacts(_converse);
|
||||
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
|
||||
expect(u.isVisible(_converse.rosterview.el)).toEqual(true);
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
expect(_converse.rosterview.el.querySelectorAll('li').length).toBe(3);
|
||||
expect(_.filter(_converse.rosterview.el.querySelectorAll('ul.roster-group-contacts'), u.isVisible).length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("are shown in the roster when hide_offline_users",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {'hide_offline_users': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
_addContacts(_converse);
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'pending');
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
expect(u.isVisible(_converse.rosterview.el)).toBe(true);
|
||||
@ -597,7 +572,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
_addContacts(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
const name = mock.pend_names[0];
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const contact = _converse.roster.get(jid);
|
||||
@ -628,7 +604,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const name = mock.pend_names[0];
|
||||
_converse.roster.create({
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
@ -666,7 +643,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
_addContacts(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'all');
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
await u.waitUntil(() => _converse.roster.at(0).vcard.get('fullname'))
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
for (var i=0; i<mock.pend_names.length; i++) {
|
||||
@ -682,9 +660,11 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
let i;
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
let i;
|
||||
for (i=0; i<mock.pend_names.length; i++) {
|
||||
_converse.roster.create({
|
||||
jid: mock.pend_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
@ -694,7 +674,7 @@
|
||||
});
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
}
|
||||
await u.waitUntil(() => sizzle('li', _converse.rosterview.get('Pending contacts').el).filter(u.isVisible).length, 700);
|
||||
await u.waitUntil(() => sizzle('li', _converse.rosterview.get('Pending contacts').el).filter(u.isVisible).length, 900);
|
||||
// Check that they are sorted alphabetically
|
||||
const view = _converse.rosterview.get('Pending contacts');
|
||||
const spans = view.el.querySelectorAll('.pending-xmpp-contact span');
|
||||
@ -706,7 +686,8 @@
|
||||
|
||||
describe("Existing Contacts", function () {
|
||||
async function _addContacts (_converse) {
|
||||
test_utils.createContacts(_converse, 'current').openControlBox()
|
||||
await test_utils.waitForRoster(_converse, 'current');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await Promise.all(_converse.roster.forEach(contact => u.waitUntil(() => contact.vcard.get('fullname'))));
|
||||
}
|
||||
|
||||
@ -749,7 +730,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
await Promise.all(mock.cur_names.map(name => {
|
||||
const contact = _converse.roster.create({
|
||||
@ -802,10 +783,10 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
var name = mock.cur_names[0];
|
||||
var contact;
|
||||
contact = _converse.roster.create({
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
const name = mock.cur_names[0];
|
||||
const contact = _converse.roster.create({
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
subscription: 'both',
|
||||
ask: null,
|
||||
@ -833,17 +814,21 @@
|
||||
|
||||
await _addContacts(_converse);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
|
||||
let jid, t;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
const roster = _converse.rosterview.el;
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let i=0; i<mock.cur_names.length; i++) {
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'online');
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
const chat_els = roster.querySelectorAll('.roster-group .current-xmpp-contact.online a.open-chat');
|
||||
t = _.reduce(chat_els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = group.querySelectorAll('.current-xmpp-contact.online a.open-chat');
|
||||
const t = _.reduce(els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.groups_map[groupname].slice(0, els.length).sort().join(''));
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -855,17 +840,21 @@
|
||||
|
||||
await _addContacts(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
|
||||
let jid, t;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
const roster = _converse.rosterview.el;
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let i=0; i<mock.cur_names.length; i++) {
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'dnd');
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
const chat_els = roster.querySelectorAll('.roster-group .current-xmpp-contact.dnd a.open-chat');
|
||||
t = _.reduce(chat_els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = group.querySelectorAll('.current-xmpp-contact.dnd a.open-chat');
|
||||
const t = _.reduce(els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.groups_map[groupname].slice(0, els.length).sort().join(''));
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -877,17 +866,21 @@
|
||||
|
||||
await _addContacts(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
|
||||
let jid, t;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
const roster = _converse.rosterview.el;
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let i=0; i<mock.cur_names.length; i++) {
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'away');
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
const chat_els = roster.querySelectorAll('.roster-group .current-xmpp-contact.away a.open-chat');
|
||||
t = _.reduce(chat_els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = group.querySelectorAll('.current-xmpp-contact.away a.open-chat');
|
||||
const t = _.reduce(els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.groups_map[groupname].slice(0, els.length).sort().join(''));
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -899,19 +892,21 @@
|
||||
|
||||
await _addContacts(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
|
||||
var jid, t;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
const roster = _converse.rosterview.el;
|
||||
for (var i=0; i<mock.cur_names.length; i++) {
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let i=0; i<mock.cur_names.length; i++) {
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'xa');
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
t = _.reduce(roster.querySelectorAll('.roster-group .current-xmpp-contact.xa a.open-chat'),
|
||||
function (result, value) {
|
||||
return result + _.trim(value.textContent);
|
||||
}, '');
|
||||
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = group.querySelectorAll('.current-xmpp-contact.xa a.open-chat');
|
||||
const t = _.reduce(els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.groups_map[groupname].slice(0, els.length).sort().join(''));
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -923,19 +918,21 @@
|
||||
|
||||
await _addContacts(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 500)
|
||||
var jid, t;
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
var roster = _converse.rosterview.el;
|
||||
for (var i=0; i<mock.cur_names.length; i++) {
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const roster = _converse.rosterview.el;
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let i=0; i<mock.cur_names.length; i++) {
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'unavailable');
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
t = _.reduce(roster.querySelectorAll('.roster-group .current-xmpp-contact.unavailable a.open-chat'),
|
||||
function (result, value) {
|
||||
return result + _.trim(value.textContent);
|
||||
}, '');
|
||||
expect(t).toEqual(mock.cur_names.slice(0,i+1).sort().join(''));
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = group.querySelectorAll('.current-xmpp-contact.unavailable a.open-chat');
|
||||
const t = _.reduce(els, (result, value) => result + _.trim(value.textContent), '');
|
||||
expect(t).toEqual(mock.groups_map[groupname].slice(0, els.length).sort().join(''));
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -968,62 +965,54 @@
|
||||
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.roster.get(jid).presence.set('show', 'unavailable');
|
||||
}
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('li.online').length)
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelector('li:first-child').textContent.trim() === 'Juliet Capulet', 900);
|
||||
const contacts = _converse.rosterview.el.querySelectorAll('.current-xmpp-contact');
|
||||
for (i=0; i<3; i++) {
|
||||
expect(u.hasClass('online', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('away', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(false);
|
||||
}
|
||||
for (i=3; i<6; i++) {
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('online', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('away', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(false);
|
||||
}
|
||||
for (i=6; i<9; i++) {
|
||||
expect(u.hasClass('away', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('online', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(false);
|
||||
}
|
||||
for (i=9; i<12; i++) {
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('online', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('away', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(false);
|
||||
}
|
||||
for (i=12; i<15; i++) {
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('online', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('away', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(false);
|
||||
}
|
||||
for (i=15; i<mock.cur_names.length; i++) {
|
||||
expect(u.hasClass('offline', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('both', contacts[i])).toBe(true);
|
||||
expect(u.hasClass('online', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('dnd', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('away', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('xa', contacts[i])).toBe(false);
|
||||
expect(u.hasClass('unavailable', contacts[i])).toBe(false);
|
||||
|
||||
await u.waitUntil(() => u.isVisible(_converse.rosterview.el.querySelector('li:first-child')), 900);
|
||||
const roster = _converse.rosterview.el;
|
||||
const groups = roster.querySelectorAll('.roster-group');
|
||||
const groupnames = Array.from(groups).map(g => g.getAttribute('data-group'));
|
||||
expect(groupnames.join(' ')).toBe("Colleagues Family friends & acquaintences ænemies Ungrouped");
|
||||
for (let j=0; j<groups.length; j++) {
|
||||
const group = groups[j];
|
||||
const groupname = groupnames[j];
|
||||
const els = Array.from(group.querySelectorAll('.current-xmpp-contact'));
|
||||
expect(els.length).toBe(mock.groups_map[groupname].length);
|
||||
|
||||
if (groupname === "Colleagues") {
|
||||
const statuses = els.map(e => e.getAttribute('data-status'));
|
||||
const subscription_classes = els.map(e => e.classList[3]);
|
||||
const status_classes = els.map(e => e.classList[4]);
|
||||
expect(statuses.join(" ")).toBe("online online away xa xa xa");
|
||||
expect(status_classes.join(" ")).toBe("online online away xa xa xa");
|
||||
expect(subscription_classes.join(" ")).toBe("both both both both both both");
|
||||
} else if (groupname === "friends & acquaintences") {
|
||||
const statuses = els.map(e => e.getAttribute('data-status'));
|
||||
const subscription_classes = els.map(e => e.classList[3]);
|
||||
const status_classes = els.map(e => e.classList[4]);
|
||||
expect(statuses.join(" ")).toBe("online online dnd dnd away unavailable");
|
||||
expect(status_classes.join(" ")).toBe("online online dnd dnd away unavailable");
|
||||
expect(subscription_classes.join(" ")).toBe("both both both both both both");
|
||||
} else if (groupname === "Family") {
|
||||
const statuses = els.map(e => e.getAttribute('data-status'));
|
||||
const subscription_classes = els.map(e => e.classList[3]);
|
||||
const status_classes = els.map(e => e.classList[4]);
|
||||
expect(statuses.join(" ")).toBe("online dnd");
|
||||
expect(status_classes.join(" ")).toBe("online dnd");
|
||||
expect(subscription_classes.join(" ")).toBe("both both");
|
||||
} else if (groupname === "ænemies") {
|
||||
const statuses = els.map(e => e.getAttribute('data-status'));
|
||||
const subscription_classes = els.map(e => e.classList[3]);
|
||||
const status_classes = els.map(e => e.classList[4]);
|
||||
expect(statuses.join(" ")).toBe("away");
|
||||
expect(status_classes.join(" ")).toBe("away");
|
||||
expect(subscription_classes.join(" ")).toBe("both");
|
||||
} else if (groupname === "Ungrouped") {
|
||||
const statuses = els.map(e => e.getAttribute('data-status'));
|
||||
const subscription_classes = els.map(e => e.classList[3]);
|
||||
const status_classes = els.map(e => e.classList[4]);
|
||||
expect(statuses.join(" ")).toBe("unavailable unavailable");
|
||||
expect(status_classes.join(" ")).toBe("unavailable unavailable");
|
||||
expect(subscription_classes.join(" ")).toBe("both both");
|
||||
}
|
||||
}
|
||||
done();
|
||||
}));
|
||||
@ -1036,7 +1025,7 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
let names = [];
|
||||
const addName = function (item) {
|
||||
if (!u.hasClass('request-actions', item)) {
|
||||
@ -1069,7 +1058,8 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, "current", 0);
|
||||
const name = mock.req_names[0];
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
_converse.roster.create({
|
||||
@ -1093,7 +1083,9 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'requesting').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
test_utils.createContacts(_converse, 'requesting');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).length, 700);
|
||||
await checkHeaderToggling.apply(
|
||||
_converse,
|
||||
@ -1107,8 +1099,9 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'requesting').openControlBox();
|
||||
await test_utils.openControlBox(_converse);
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
await test_utils.createContacts(_converse, 'requesting');
|
||||
const name = mock.req_names.sort()[0];
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const contact = _converse.roster.get(jid);
|
||||
@ -1131,7 +1124,9 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'requesting').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
await test_utils.createContacts(_converse, 'requesting');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
|
||||
_converse.rosterview.update(); // XXX: Hack to make sure $roster element is attaced.
|
||||
const name = mock.req_names.sort()[1];
|
||||
@ -1206,16 +1201,18 @@
|
||||
it("are saved to, and can be retrieved from browserStorage",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'current', 0);
|
||||
await test_utils.createContacts(_converse, 'requesting');
|
||||
await test_utils.openControlBox(_converse);
|
||||
var new_attrs, old_attrs, attrs;
|
||||
var num_contacts = _converse.roster.length;
|
||||
var new_roster = new _converse.RosterContacts();
|
||||
// Roster items are yet to be fetched from browserStorage
|
||||
expect(new_roster.length).toEqual(0);
|
||||
new_roster.browserStorage = _converse.roster.browserStorage;
|
||||
new_roster.fetch();
|
||||
await new Promise(success => new_roster.fetch({success}));
|
||||
expect(new_roster.length).toEqual(num_contacts);
|
||||
// Check that the roster items retrieved from browserStorage
|
||||
// have the same attributes values as the original ones.
|
||||
@ -1236,7 +1233,9 @@
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
await test_utils.waitForRoster(_converse, 'current', 'all');
|
||||
await test_utils.createContacts(_converse, 'requesting');
|
||||
await test_utils.openControlBox(_converse);
|
||||
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
|
||||
await Promise.all(mock.cur_names.map(async name => {
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -1246,6 +1245,13 @@
|
||||
expect(child.getAttribute('title')).toContain(name);
|
||||
expect(child.getAttribute('title')).toContain(jid);
|
||||
}));
|
||||
await Promise.all(mock.req_names.map(async name => {
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const el = await u.waitUntil(() => sizzle("li:contains('"+name+"')", _converse.rosterview.el).pop());
|
||||
const child = el.firstElementChild;
|
||||
expect(child.textContent.trim()).toBe(name);
|
||||
expect(child.firstElementChild.getAttribute('title')).toContain(jid);
|
||||
}));
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
@ -39,18 +39,12 @@
|
||||
let IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
await u.waitUntil(() => IQ_stanzas.length === 4);
|
||||
|
||||
let iq = IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${iq.getAttribute('id')}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
|
||||
|
||||
iq = IQ_stanzas[IQ_stanzas.length-1];
|
||||
let iq = IQ_stanzas[IQ_stanzas.length-1];
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq id="${iq.getAttribute('id')}" type="get" xmlns="jabber:client"><query xmlns="jabber:iq:roster"/></iq>`);
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
|
||||
IQ_stanzas.pop();
|
||||
|
||||
const disco_iq = IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(disco_iq)).toBe(
|
||||
`<iq from="romeo@montague.lit" id="${disco_iq.getAttribute('id')}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
|
||||
@ -58,9 +52,13 @@
|
||||
|
||||
iq = IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${iq.getAttribute('id')}" to="montague.lit" type="get" xmlns="jabber:client">`+
|
||||
`<iq from="romeo@montague.lit/orchard" id="${iq.getAttribute('id')}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
|
||||
|
||||
iq = IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${iq.getAttribute('id')}" to="montague.lit" type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
|
||||
|
||||
expect(sent_stanzas.filter(s => (s.nodeName === 'r')).length).toBe(2);
|
||||
expect(_converse.session.get('unacked_stanzas').length).toBe(5);
|
||||
@ -104,7 +102,7 @@
|
||||
// test session resumption
|
||||
_converse.connection.IQ_stanzas = [];
|
||||
IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
_converse.api.connection.reconnect();
|
||||
await _converse.api.connection.reconnect();
|
||||
stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toEqual('<resume h="2" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
|
||||
@ -120,9 +118,7 @@
|
||||
|
||||
// Test that unacked stanzas get resent out
|
||||
iq = IQ_stanzas.pop();
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${iq.getAttribute('id')}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
|
||||
expect(Strophe.serialize(iq)).toBe(`<iq id="${iq.getAttribute('id')}" type="get" xmlns="jabber:client"><query xmlns="jabber:iq:roster"/></iq>`);
|
||||
|
||||
expect(IQ_stanzas.filter(iq => sizzle('query[xmlns="jabber:iq:roster"]', iq).pop()).length).toBe(0);
|
||||
|
||||
@ -141,9 +137,6 @@
|
||||
},
|
||||
async function (done, _converse) {
|
||||
|
||||
const view = _converse.chatboxviews.get('controlbox');
|
||||
spyOn(view, 'renderControlBoxPane').and.callThrough();
|
||||
|
||||
_converse.api.user.login('romeo@montague.lit/orchard', 'secret');
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
let stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'enable')).pop());
|
||||
@ -154,7 +147,7 @@
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
|
||||
// test session resumption
|
||||
_converse.api.connection.reconnect();
|
||||
await _converse.api.connection.reconnect();
|
||||
stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
|
||||
expect(Strophe.serialize(stanza)).toEqual('<resume h="1" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
}).t(spoiler_hint)
|
||||
.tree();
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await u.waitUntil(() => _converse.api.chats.get().length === 2);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
||||
@ -69,6 +70,7 @@
|
||||
'xmlns': 'urn:xmpp:spoiler:0',
|
||||
}).tree();
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await u.waitUntil(() => _converse.api.chats.get().length === 2);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise(resolve => view.once('messageInserted', resolve));
|
||||
await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
||||
@ -86,7 +88,7 @@
|
||||
async (done, _converse) => {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
// XXX: We need to send a presence from the contact, so that we
|
||||
@ -159,7 +161,7 @@
|
||||
async (done, _converse) => {
|
||||
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
test_utils.openControlBox();
|
||||
test_utils.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
|
||||
// XXX: We need to send a presence from the contact, so that we
|
||||
@ -173,7 +175,7 @@
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
await test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
|
||||
await u.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
|
||||
let spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||
|
@ -1,14 +1,13 @@
|
||||
(function (root, factory) {
|
||||
define([
|
||||
"jasmine",
|
||||
"converse-core",
|
||||
"mock",
|
||||
"test-utils",
|
||||
"utils",
|
||||
"transcripts"
|
||||
], factory
|
||||
);
|
||||
} (this, function (jasmine, converse, mock, test_utils, utils, transcripts) {
|
||||
} (this, function (jasmine, mock, test_utils, utils, transcripts) {
|
||||
var Strophe = converse.env.Strophe;
|
||||
var _ = converse.env._;
|
||||
var IGNORED_TAGS = [
|
||||
|
@ -15,11 +15,11 @@
|
||||
['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
await test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
await u.waitUntil(() => _converse.chatboxes.length > 1);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
let show_modal_button = view.el.querySelector('.show-user-details-modal');
|
||||
@ -48,7 +48,7 @@
|
||||
['rosterGroupsFetched', 'emojisInitialized'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.waitForRoster(_converse, 'current', 1);
|
||||
_converse.api.trigger('rosterContactsFetched');
|
||||
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
@ -60,9 +60,8 @@
|
||||
const modal = view.user_details_modal;
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 2000);
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback, errback) {
|
||||
errback();
|
||||
});
|
||||
|
||||
spyOn(view.model.contact, 'removeFromRoster').and.callFake((callback, errback) => errback());
|
||||
let remove_contact_button = modal.el.querySelector('button.remove-contact');
|
||||
expect(u.isVisible(remove_contact_button)).toBeTruthy();
|
||||
remove_contact_button.click();
|
||||
|
@ -445,6 +445,14 @@ converse.plugins.add('converse-chatview', {
|
||||
this.insertIntoDOM();
|
||||
this.scrollDown();
|
||||
this.content.addEventListener('scroll', this.markScrolled.bind(this));
|
||||
/**
|
||||
* Triggered whenever a `_converse.ChatBox` instance has fetched its messages from
|
||||
* `sessionStorage` but **NOT** from the server.
|
||||
* @event _converse#afterMessagesFetched
|
||||
* @type {_converse.ChatBoxView | _converse.ChatRoomView}
|
||||
* @example _converse.api.listen.on('afterMessagesFetched', view => { ... });
|
||||
*/
|
||||
_converse.api.trigger('afterMessagesFetched', this);
|
||||
},
|
||||
|
||||
insertIntoDOM () {
|
||||
@ -589,7 +597,7 @@ converse.plugins.add('converse-chatview', {
|
||||
}
|
||||
},
|
||||
|
||||
showHelpMessages (msgs, type, spinner) {
|
||||
showHelpMessages (msgs, type='info', spinner) {
|
||||
msgs.forEach(msg => {
|
||||
this.content.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
@ -997,11 +1005,11 @@ converse.plugins.add('converse-chatview', {
|
||||
}
|
||||
},
|
||||
|
||||
clearMessages (ev) {
|
||||
async clearMessages (ev) {
|
||||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||
const result = confirm(__("Are you sure you want to clear the messages from this conversation?"));
|
||||
if (result === true) {
|
||||
this.model.clearMessages();
|
||||
await this.model.clearMessages();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
@ -1119,7 +1127,7 @@ converse.plugins.add('converse-chatview', {
|
||||
}
|
||||
},
|
||||
|
||||
close (ev) {
|
||||
async close (ev) {
|
||||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||
if (Backbone.history.getFragment() === "converse/chat?jid="+this.model.get('jid')) {
|
||||
_converse.router.navigate('');
|
||||
@ -1130,7 +1138,7 @@ converse.plugins.add('converse-chatview', {
|
||||
this.model.setChatState(_converse.INACTIVE);
|
||||
this.model.sendChatState();
|
||||
}
|
||||
this.model.close();
|
||||
await this.model.close();
|
||||
this.remove();
|
||||
/**
|
||||
* Triggered once a chatbox has been closed.
|
||||
@ -1247,10 +1255,7 @@ converse.plugins.add('converse-chatview', {
|
||||
},
|
||||
|
||||
viewUnreadMessages () {
|
||||
this.model.save({
|
||||
'scrolled': false,
|
||||
'top_visible_message': null
|
||||
});
|
||||
this.model.save({'scrolled': false, 'top_visible_message': null});
|
||||
this.scrollDown();
|
||||
},
|
||||
|
||||
@ -1315,7 +1320,7 @@ converse.plugins.add('converse-chatview', {
|
||||
* @namespace _converse.api.chatviews
|
||||
* @memberOf _converse.api
|
||||
*/
|
||||
'chatviews': {
|
||||
chatviews: {
|
||||
/**
|
||||
* Get the view of an already open chat.
|
||||
* @method _converse.api.chatviews.get
|
||||
@ -1329,13 +1334,9 @@ converse.plugins.add('converse-chatview', {
|
||||
* // To return an array of views, provide an array of JIDs:
|
||||
* _converse.api.chatviews.get(['buddy1@example.com', 'buddy2@example.com'])
|
||||
*/
|
||||
'get' (jids) {
|
||||
get (jids) {
|
||||
if (jids === undefined) {
|
||||
_converse.log(
|
||||
"chatviews.get: You need to provide at least one JID",
|
||||
Strophe.LogLevel.ERROR
|
||||
);
|
||||
return null;
|
||||
return Object.values(_converse.chatboxviews.getAll());
|
||||
}
|
||||
if (isString(jids)) {
|
||||
return _converse.chatboxviews.get(jids);
|
||||
|
@ -85,7 +85,7 @@ converse.plugins.add('converse-controlbox', {
|
||||
ChatBoxes: {
|
||||
model (attrs, options) {
|
||||
const { _converse } = this.__super__;
|
||||
if (attrs.id == 'controlbox') {
|
||||
if (attrs && attrs.id == 'controlbox') {
|
||||
return new _converse.ControlBox(attrs, options);
|
||||
} else {
|
||||
return this.__super__.model.apply(this, arguments);
|
||||
@ -292,14 +292,24 @@ converse.plugins.add('converse-controlbox', {
|
||||
)
|
||||
},
|
||||
|
||||
close (ev) {
|
||||
async close (ev) {
|
||||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||
if (get(ev, 'name') === 'closeAllChatBoxes' &&
|
||||
(_converse.disconnection_cause !== _converse.LOGOUT ||
|
||||
_converse.show_controlbox_by_default)) {
|
||||
return;
|
||||
}
|
||||
if (_converse.sticky_controlbox) {
|
||||
return;
|
||||
}
|
||||
const connection = get(_converse, 'connection', {});
|
||||
if (connection.connected && !connection.disconnecting) {
|
||||
this.model.save({'closed': true});
|
||||
await new Promise((resolve, reject) => {
|
||||
return this.model.save(
|
||||
{'closed': true},
|
||||
{'success': resolve, 'error': reject}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.model.trigger('hide');
|
||||
}
|
||||
@ -591,7 +601,7 @@ converse.plugins.add('converse-controlbox', {
|
||||
|
||||
_converse.api.listen.on('chatBoxesFetched', () => {
|
||||
const controlbox = _converse.chatboxes.get('controlbox') || addControlBox();
|
||||
controlbox.save({connected:true});
|
||||
controlbox.save({'connected': true});
|
||||
});
|
||||
|
||||
const disconnect = function () {
|
||||
|
@ -49,9 +49,12 @@ converse.plugins.add('converse-dragresize', {
|
||||
ChatBox: {
|
||||
initialize () {
|
||||
const { _converse } = this.__super__;
|
||||
const result = this.__super__.initialize.apply(this, arguments),
|
||||
height = this.get('height'), width = this.get('width'),
|
||||
save = this.get('id') === 'controlbox' ? this.set.bind(this) : this.save.bind(this);
|
||||
const result = this.__super__.initialize.apply(this, arguments);
|
||||
const height = this.get('height'), width = this.get('width');
|
||||
const save = this.get('id') === 'controlbox' ?
|
||||
(attrs) => this.set(attrs) :
|
||||
(attrs) => this.save(attrs);
|
||||
|
||||
save({
|
||||
'height': _converse.applyDragResistance(height, this.get('default_height')),
|
||||
'width': _converse.applyDragResistance(width, this.get('default_width')),
|
||||
|
@ -885,7 +885,6 @@ converse.plugins.add('converse-muc-views', {
|
||||
*/
|
||||
if (u.isPersistableModel(this.model)) {
|
||||
this.model.clearUnreadMsgCounter();
|
||||
this.model.save();
|
||||
}
|
||||
this.scrollDown();
|
||||
},
|
||||
@ -925,12 +924,12 @@ converse.plugins.add('converse-muc-views', {
|
||||
* @private
|
||||
* @method _converse.ChatRoomView#close
|
||||
*/
|
||||
close () {
|
||||
async close () {
|
||||
this.hide();
|
||||
if (Backbone.history.getFragment() === "converse/room?jid="+this.model.get('jid')) {
|
||||
_converse.router.navigate('');
|
||||
}
|
||||
this.model.leave();
|
||||
await this.model.leave();
|
||||
return _converse.ChatBoxView.prototype.close.apply(this, arguments);
|
||||
},
|
||||
|
||||
@ -2128,7 +2127,6 @@ converse.plugins.add('converse-muc-views', {
|
||||
const view = _converse.chatboxviews.get('controlbox');
|
||||
if (view && view.roomspanel) {
|
||||
view.roomspanel.model.destroy();
|
||||
view.roomspanel.model.browserStorage._clear();
|
||||
view.roomspanel.remove();
|
||||
delete view.roomspanel;
|
||||
}
|
||||
@ -2197,6 +2195,7 @@ converse.plugins.add('converse-muc-views', {
|
||||
*
|
||||
* @method _converse.api.roomviews.close
|
||||
* @param {(String[]|String)} jids The JID or array of JIDs of the chatroom(s)
|
||||
* @returns { Promise } - Promise which resolves once the views have been closed.
|
||||
*/
|
||||
close (jids) {
|
||||
let views;
|
||||
@ -2207,11 +2206,7 @@ converse.plugins.add('converse-muc-views', {
|
||||
} else if (Array.isArray(jids)) {
|
||||
views = jids.map(jid => _converse.chatboxviews.get(jid));
|
||||
}
|
||||
views.forEach(view => {
|
||||
if (view.is_chatroom && view.model) {
|
||||
view.close();
|
||||
}
|
||||
});
|
||||
return Promise.all(views.map(v => (v.is_chatroom && v.model && v.close())))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -714,9 +714,8 @@ converse.plugins.add('converse-omemo', {
|
||||
if (identifier === null || identifier === undefined) {
|
||||
throw new Error("Can't save identity_key for invalid identifier");
|
||||
}
|
||||
const address = new libsignal.SignalProtocolAddress.fromString(identifier),
|
||||
existing = this.get('identity_key'+address.getName());
|
||||
|
||||
const address = new libsignal.SignalProtocolAddress.fromString(identifier);
|
||||
const existing = this.get('identity_key'+address.getName());
|
||||
const b64_idkey = u.arrayBufferToBase64(identity_key);
|
||||
this.save('identity_key'+address.getName(), b64_idkey)
|
||||
|
||||
@ -986,8 +985,7 @@ converse.plugins.add('converse-omemo', {
|
||||
initialize () {
|
||||
this.devices = new _converse.Devices();
|
||||
const id = `converse.devicelist-${_converse.bare_jid}-${this.get('jid')}`;
|
||||
const storage = _converse.config.get('storage');
|
||||
this.devices.browserStorage = _converse.createStore(id, storage);
|
||||
this.devices.browserStorage = _converse.createStore(id);
|
||||
this.fetchDevices();
|
||||
},
|
||||
|
||||
@ -1096,7 +1094,7 @@ converse.plugins.add('converse-omemo', {
|
||||
|
||||
|
||||
function fetchDeviceLists () {
|
||||
return new Promise((success, error) => _converse.devicelists.fetch({success, error}));
|
||||
return new Promise((success, error) => _converse.devicelists.fetch({success, 'error': (m, e) => error(e)}));
|
||||
}
|
||||
|
||||
async function fetchOwnDevices () {
|
||||
@ -1171,10 +1169,9 @@ converse.plugins.add('converse-omemo', {
|
||||
|
||||
function restoreOMEMOSession () {
|
||||
if (_converse.omemo_store === undefined) {
|
||||
const storage = _converse.config.get('storage'),
|
||||
id = `converse.omemosession-${_converse.bare_jid}`;
|
||||
const id = `converse.omemosession-${_converse.bare_jid}`;
|
||||
_converse.omemo_store = new _converse.OMEMOStore({'id': id});
|
||||
_converse.omemo_store.browserStorage = _converse.createStore(id, storage);
|
||||
_converse.omemo_store.browserStorage = _converse.createStore(id);
|
||||
}
|
||||
return _converse.omemo_store.fetchSession();
|
||||
}
|
||||
@ -1184,9 +1181,8 @@ converse.plugins.add('converse-omemo', {
|
||||
return;
|
||||
}
|
||||
_converse.devicelists = new _converse.DeviceLists();
|
||||
const storage = _converse.config.get('storage'),
|
||||
id = `converse.devicelists-${_converse.bare_jid}`;
|
||||
_converse.devicelists.browserStorage = _converse.createStore(id, storage);
|
||||
const id = `converse.devicelists-${_converse.bare_jid}`;
|
||||
_converse.devicelists.browserStorage = _converse.createStore(id);
|
||||
|
||||
try {
|
||||
await fetchOwnDevices();
|
||||
|
@ -808,9 +808,8 @@ converse.plugins.add('converse-rosterview', {
|
||||
createRosterFilter () {
|
||||
// Create a model on which we can store filter properties
|
||||
const model = new _converse.RosterFilter();
|
||||
model.id = `_converse.rosterfilter${_converse.bare_jid}`;
|
||||
const storage = _converse.config.get('storage');
|
||||
model.browserStorage = _converse.createStore(this.filter.id, storage);
|
||||
model.id = `_converse.rosterfilter-${_converse.bare_jid}`;
|
||||
model.browserStorage = _converse.createStore(model.id);
|
||||
this.filter_view = new _converse.RosterFilterView({'model': model});
|
||||
this.listenTo(this.filter_view.model, 'change', this.updateFilter);
|
||||
this.filter_view.model.fetch();
|
||||
|
@ -96,7 +96,15 @@ converse.plugins.add('converse-uniview', {
|
||||
.forEach(hideChat);
|
||||
|
||||
if (view.model.get('hidden')) {
|
||||
u.safeSave(view.model, {'hidden': false});
|
||||
return new Promise(resolve => {
|
||||
u.safeSave(
|
||||
view.model,
|
||||
{'hidden': false}, {
|
||||
'success': resolve,
|
||||
'failure': resolve
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -127,19 +127,13 @@ converse.plugins.add('converse-bookmarks', {
|
||||
|
||||
fetchBookmarks () {
|
||||
const deferred = u.getResolveablePromise();
|
||||
if (this.browserStorage.records.length > 0) {
|
||||
if (window.sessionStorage.getItem(this.fetched_flag)) {
|
||||
this.fetch({
|
||||
'success': () => deferred.resolve(),
|
||||
'error': () => deferred.resolve()
|
||||
});
|
||||
} else if (! window.sessionStorage.getItem(this.fetched_flag)) {
|
||||
// There aren't any cached bookmarks and the
|
||||
// `fetched_flag` is off, so we query the XMPP server.
|
||||
// If nothing is returned from the XMPP server, we set
|
||||
// the `fetched_flag` to avoid calling the server again.
|
||||
this.fetchBookmarksFromServer(deferred);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
this.fetchBookmarksFromServer(deferred);
|
||||
}
|
||||
return deferred;
|
||||
},
|
||||
@ -231,6 +225,7 @@ converse.plugins.add('converse-bookmarks', {
|
||||
|
||||
onBookmarksReceived (deferred, iq) {
|
||||
this.createBookmarksFromStanza(iq);
|
||||
window.sessionStorage.setItem(this.fetched_flag, true);
|
||||
if (deferred !== undefined) {
|
||||
return deferred.resolve();
|
||||
}
|
||||
@ -301,6 +296,7 @@ converse.plugins.add('converse-bookmarks', {
|
||||
if (_converse.bookmarks !== undefined) {
|
||||
_converse.bookmarks.clearSession({'silent': true});
|
||||
window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
|
||||
delete _converse.bookmarks;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -114,7 +114,6 @@ converse.plugins.add('converse-bosh', {
|
||||
sessionStorage.removeItem(`${id}-${id}`);
|
||||
} else {
|
||||
_converse.bosh_session.destroy();
|
||||
_converse.bosh_session.browserStorage._clear();
|
||||
delete _converse.bosh_session;
|
||||
}
|
||||
});
|
||||
|
@ -18,8 +18,8 @@ function propertySort (array, property) {
|
||||
}
|
||||
|
||||
function generateVerificationString (_converse) {
|
||||
const identities = _converse.api.disco.own.identities.get(),
|
||||
features = _converse.api.disco.own.features.get();
|
||||
const identities = _converse.api.disco.own.identities.get();
|
||||
const features = _converse.api.disco.own.features.get();
|
||||
|
||||
if (identities.length > 1) {
|
||||
propertySort(identities, "category");
|
||||
|
@ -353,8 +353,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
initMessages () {
|
||||
this.messages = new this.messagesCollection();
|
||||
this.messages.chatbox = this;
|
||||
const storage = _converse.config.get('storage');
|
||||
this.messages.browserStorage = _converse.createStore(this.getMessagesCacheKey(), storage);
|
||||
this.messages.browserStorage = _converse.createStore(this.getMessagesCacheKey());
|
||||
this.listenTo(this.messages, 'change:upload', message => {
|
||||
if (message.get('upload') === _converse.SUCCESS) {
|
||||
_converse.api.send(this.createMessageStanza(message));
|
||||
@ -388,27 +387,28 @@ converse.plugins.add('converse-chatboxes', {
|
||||
return this.messages.fetched;
|
||||
},
|
||||
|
||||
clearMessages () {
|
||||
async clearMessages () {
|
||||
try {
|
||||
this.messages.models.forEach(m => m.destroy());
|
||||
await Promise.all(this.messages.models.map(m => m.destroy()));
|
||||
this.messages.reset();
|
||||
} catch (e) {
|
||||
this.messages.trigger('reset');
|
||||
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||
} finally {
|
||||
delete this.messages.fetched;
|
||||
this.messages.browserStorage._clear();
|
||||
}
|
||||
},
|
||||
|
||||
close () {
|
||||
async close () {
|
||||
try {
|
||||
this.destroy();
|
||||
await new Promise((success, reject) => {
|
||||
return this.destroy({success, 'error': (m, e) => reject(e)})
|
||||
});
|
||||
} catch (e) {
|
||||
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||
} finally {
|
||||
if (_converse.clear_messages_on_reconnection) {
|
||||
this.clearMessages();
|
||||
await this.clearMessages();
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1172,9 +1172,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
if (reconnecting) {
|
||||
return;
|
||||
}
|
||||
const storage = _converse.config.get('storage');
|
||||
const id = `converse.chatboxes-${_converse.bare_jid}`;
|
||||
this.browserStorage = _converse.createStore(id, storage);
|
||||
this.browserStorage = _converse.createStore(`converse.chatboxes-${_converse.bare_jid}`);
|
||||
this.registerMessageHandler();
|
||||
this.fetch({
|
||||
'add': true,
|
||||
@ -1202,7 +1200,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
return;
|
||||
}
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(stanza, stanza);
|
||||
chatbox.messages.create(attrs);
|
||||
await chatbox.messages.create(attrs);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1353,6 +1351,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
}
|
||||
jid = Strophe.getBareJidFromJid(jid.toLowerCase());
|
||||
|
||||
await _converse.api.waitUntil('chatBoxesFetched');
|
||||
let chatbox = this.get(Strophe.getBareJidFromJid(jid));
|
||||
if (chatbox) {
|
||||
chatbox.save(attrs);
|
||||
@ -1519,11 +1518,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
* });
|
||||
*/
|
||||
async open (jids, attrs, force) {
|
||||
await Promise.all([
|
||||
_converse.api.waitUntil('rosterContactsFetched'),
|
||||
_converse.api.waitUntil('chatBoxesFetched')
|
||||
]);
|
||||
|
||||
await _converse.api.waitUntil('chatBoxesFetched');
|
||||
if (isString(jids)) {
|
||||
const chat = await _converse.api.chats.create(jids, attrs);
|
||||
if (chat) {
|
||||
@ -1542,7 +1537,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a chat model. The chat should already be open.
|
||||
* Retrieves a chat model. The chat should already be open.
|
||||
*
|
||||
* @method _converse.api.chats.get
|
||||
* @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
|
||||
|
@ -26,6 +26,7 @@ const $msg = strophe.default.$msg;
|
||||
const $pres = strophe.default.$pres;
|
||||
|
||||
Backbone = Backbone.noConflict();
|
||||
BrowserStorage.patch(Backbone);
|
||||
|
||||
dayjs.extend(advancedFormat);
|
||||
|
||||
@ -109,9 +110,20 @@ _converse.VERSION_NAME = "v5.0.5dev";
|
||||
Object.assign(_converse, Backbone.Events);
|
||||
|
||||
_converse.Collection = Backbone.Collection.extend({
|
||||
clearSession (options) {
|
||||
Array.from(this.models).forEach(m => m.destroy(options));
|
||||
this.browserStorage._clear();
|
||||
async clearSession (options={}) {
|
||||
await Promise.all(Array.from(this.models).map(m => {
|
||||
return new Promise(
|
||||
success => m.destroy(
|
||||
Object.assign(options, {
|
||||
success,
|
||||
'error': (m, e) => {
|
||||
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||
success()
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
}));
|
||||
this.reset();
|
||||
}
|
||||
});
|
||||
@ -377,9 +389,40 @@ _converse.isUniView = function () {
|
||||
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
|
||||
};
|
||||
|
||||
|
||||
async function initStorage () {
|
||||
await BrowserStorage.sessionStorageInitialized;
|
||||
|
||||
// Sets up Backbone.BrowserStorage and localForage for the 3 different stores.
|
||||
_converse.localStorage = BrowserStorage.localForage.createInstance({
|
||||
'name': 'local',
|
||||
'description': 'localStorage instance',
|
||||
'driver': [BrowserStorage.localForage.LOCALSTORAGE]
|
||||
});
|
||||
|
||||
_converse.indexedDB = BrowserStorage.localForage.createInstance({
|
||||
'name': 'indexed',
|
||||
'description': 'indexedDB instance',
|
||||
'driver': [BrowserStorage.localForage.INDEXEDDB]
|
||||
});
|
||||
|
||||
_converse.sessionStorage = BrowserStorage.localForage.createInstance({
|
||||
'name': 'session',
|
||||
'description': 'sessionStorage instance',
|
||||
'driver': ['sessionStorageWrapper']
|
||||
});
|
||||
|
||||
_converse.storage = {
|
||||
'session': _converse.sessionStorage,
|
||||
'local': _converse.localStorage,
|
||||
'indexed': _converse.indexedDB
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_converse.createStore = function (id, storage) {
|
||||
const s = storage ? storage : _converse.config.get('storage');
|
||||
return new BrowserStorage[s](id);
|
||||
const s = _converse.storage[storage ? storage : _converse.config.get('storage')];
|
||||
return new Backbone.BrowserStorage(id, s);
|
||||
}
|
||||
|
||||
|
||||
@ -455,8 +498,8 @@ function initClientConfig () {
|
||||
}
|
||||
|
||||
|
||||
function tearDown () {
|
||||
_converse.api.trigger('beforeTearDown');
|
||||
async function tearDown () {
|
||||
await _converse.api.trigger('beforeTearDown', {'synchronous': true});
|
||||
window.removeEventListener('click', _converse.onUserActivity);
|
||||
window.removeEventListener('focus', _converse.onUserActivity);
|
||||
window.removeEventListener('keypress', _converse.onUserActivity);
|
||||
@ -531,7 +574,7 @@ function connect (credentials) {
|
||||
}
|
||||
|
||||
|
||||
function reconnect () {
|
||||
async function reconnect () {
|
||||
_converse.log('RECONNECTING: the connection has dropped, attempting to reconnect.');
|
||||
_converse.setConnectionStatus(
|
||||
Strophe.Status.RECONNECTING,
|
||||
@ -546,7 +589,7 @@ function reconnect () {
|
||||
_converse.api.trigger('will-reconnect');
|
||||
|
||||
_converse.connection.reconnecting = true;
|
||||
tearDown();
|
||||
await tearDown();
|
||||
return _converse.api.user.login();
|
||||
}
|
||||
|
||||
@ -558,7 +601,6 @@ _converse.shouldClearCache = () => (!_converse.config.get('trusted') || _convers
|
||||
function clearSession () {
|
||||
if (_converse.session !== undefined) {
|
||||
_converse.session.destroy();
|
||||
_converse.session.browserStorage._clear();
|
||||
delete _converse.session;
|
||||
}
|
||||
/**
|
||||
@ -669,7 +711,7 @@ async function initSession (jid) {
|
||||
await new Promise(r => _converse.session.fetch({'success': r, 'error': r}));
|
||||
if (_converse.session.get('active')) {
|
||||
_converse.session.clear();
|
||||
_converse.session.save({'id': id});
|
||||
_converse.session.save({id});
|
||||
}
|
||||
saveJIDtoSession(jid);
|
||||
/**
|
||||
@ -822,6 +864,7 @@ function setUpXMLLogging () {
|
||||
|
||||
|
||||
async function finishInitialization () {
|
||||
await initStorage();
|
||||
initClientConfig();
|
||||
initPlugins();
|
||||
_converse.registerGlobalEventHandlers();
|
||||
@ -920,10 +963,15 @@ function unregisterGlobalEventHandlers () {
|
||||
_converse.api.trigger('unregisteredGlobalEventHandlers');
|
||||
}
|
||||
|
||||
function cleanup () {
|
||||
// Looks like _converse.initialized was called again without logging
|
||||
// out or disconnecting in the previous session.
|
||||
// This happens in tests. We therefore first clean up.
|
||||
async function cleanup () {
|
||||
// Make sure everything is reset in case this is a subsequent call to
|
||||
// convesre.initialize (happens during tests).
|
||||
if (_converse.localStorage) {
|
||||
await Promise.all([
|
||||
BrowserStorage.localForage.dropInstance({'name': 'local'}),
|
||||
BrowserStorage.localForage.dropInstance({'name': 'indexed'}),
|
||||
BrowserStorage.localForage.dropInstance({'name': 'session'})]);
|
||||
}
|
||||
Backbone.history.stop();
|
||||
unregisterGlobalEventHandlers();
|
||||
delete _converse.controlboxtoggle;
|
||||
@ -939,7 +987,7 @@ function cleanup () {
|
||||
|
||||
|
||||
_converse.initialize = async function (settings, callback) {
|
||||
cleanup();
|
||||
await cleanup();
|
||||
|
||||
settings = settings !== undefined ? settings : {};
|
||||
PROMISES.forEach(addPromise);
|
||||
@ -1256,7 +1304,7 @@ _converse.api = {
|
||||
const conn_status = _converse.connfeedback.get('connection_status');
|
||||
|
||||
if (_converse.authentication === _converse.ANONYMOUS) {
|
||||
tearDown();
|
||||
await tearDown();
|
||||
clearSession();
|
||||
}
|
||||
if (conn_status === Strophe.Status.CONNFAIL) {
|
||||
@ -1421,8 +1469,7 @@ _converse.api = {
|
||||
complete();
|
||||
}
|
||||
return promise;
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -120,18 +120,24 @@ converse.plugins.add('converse-disco', {
|
||||
_converse.api.trigger('discoExtensionFieldDiscovered', field);
|
||||
},
|
||||
|
||||
fetchFeatures (options) {
|
||||
if (options.ignore_cache || this.features.browserStorage.records.length === 0) {
|
||||
async fetchFeatures (options) {
|
||||
if (options.ignore_cache) {
|
||||
this.queryInfo();
|
||||
} else {
|
||||
this.features.fetch({
|
||||
add: true,
|
||||
success: () => {
|
||||
this.waitUntilFeaturesDiscovered.resolve(this);
|
||||
this.trigger('featuresDiscovered');
|
||||
}
|
||||
});
|
||||
this.identities.fetch({add: true});
|
||||
const store_id = this.features.browserStorage.name;
|
||||
const result = await this.features.browserStorage.store.getItem(store_id);
|
||||
if (result && result.length === 0 || result === null) {
|
||||
this.queryInfo();
|
||||
} else {
|
||||
this.features.fetch({
|
||||
add: true,
|
||||
success: () => {
|
||||
this.waitUntilFeaturesDiscovered.resolve(this);
|
||||
this.trigger('featuresDiscovered');
|
||||
}
|
||||
});
|
||||
this.identities.fetch({add: true});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -259,7 +265,7 @@ converse.plugins.add('converse-disco', {
|
||||
function initStreamFeatures () {
|
||||
const bare_jid = Strophe.getBareJidFromJid(_converse.jid);
|
||||
const id = `converse.stream-features-${bare_jid}`;
|
||||
if (!_converse.stream_features || _converse.stream_features.browserStorage.id !== id) {
|
||||
if (!_converse.stream_features || _converse.stream_features.browserStorage.name !== id) {
|
||||
_converse.stream_features = new _converse.Collection();
|
||||
_converse.stream_features.browserStorage = _converse.createStore(id, "session");
|
||||
_converse.stream_features.fetch({
|
||||
@ -281,6 +287,9 @@ converse.plugins.add('converse-disco', {
|
||||
* @example _converse.api.listen.on('streamFeaturesAdded', () => { ... });
|
||||
*/
|
||||
_converse.api.trigger('streamFeaturesAdded');
|
||||
},
|
||||
error (m, e) {
|
||||
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -345,15 +354,17 @@ converse.plugins.add('converse-disco', {
|
||||
|
||||
/******************** Event Handlers ********************/
|
||||
|
||||
// Re-create promise upon reconnection
|
||||
_converse.api.listen.on('userSessionInitialized', initStreamFeatures);
|
||||
_converse.api.listen.on('beforeResourceBinding', initStreamFeatures);
|
||||
|
||||
_converse.api.listen.on('reconnected', initializeDisco);
|
||||
_converse.api.listen.on('connected', initializeDisco);
|
||||
|
||||
_converse.api.listen.on('beforeTearDown', () => {
|
||||
_converse.api.listen.on('beforeTearDown', async () => {
|
||||
_converse.api.promises.add('streamFeaturesAdded')
|
||||
if (_converse.stream_features) {
|
||||
_converse.stream_features.clearSession();
|
||||
await _converse.stream_features.clearSession();
|
||||
delete _converse.stream_features;
|
||||
}
|
||||
});
|
||||
|
@ -388,7 +388,6 @@ converse.plugins.add('converse-emoji', {
|
||||
/************************ BEGIN Event Handlers ************************/
|
||||
_converse.api.listen.on('clearSession', () => {
|
||||
if (_converse.emojipicker) {
|
||||
_converse.emojipicker.browserStorage._clear();
|
||||
_converse.emojipicker.destroy();
|
||||
delete _converse.emojipicker
|
||||
}
|
||||
|
@ -253,16 +253,14 @@ converse.plugins.add('converse-mam', {
|
||||
chat.fetchNewestMessages();
|
||||
}
|
||||
});
|
||||
|
||||
_converse.api.listen.on('afterMessagesFetched', chat => {
|
||||
// XXX: We don't want to query MAM every time this is triggered
|
||||
// since it's not necessary when the chat is restored from cache.
|
||||
// (given that BOSH or SMACKS will ensure that you get messages
|
||||
// sent during the reload).
|
||||
//
|
||||
// With MUCs we can listen for `enteredNewRoom` but for
|
||||
// one-on-one we have to use this hacky solutoin for now.
|
||||
// `chat_state` is `undefined` only for newly created chats.
|
||||
if (chat.get('type') === _converse.PRIVATE_CHAT_TYPE && chat.get('chat_state') === undefined) {
|
||||
// With MUCs we can listen for `enteredNewRoom`.
|
||||
if (chat.get('type') === _converse.PRIVATE_CHAT_TYPE && !_converse.connection.restored) {
|
||||
chat.fetchNewestMessages();
|
||||
}
|
||||
});
|
||||
|
@ -84,10 +84,17 @@ converse.plugins.add('converse-muc', {
|
||||
dependencies: ["converse-chatboxes", "converse-disco", "converse-controlbox"],
|
||||
|
||||
overrides: {
|
||||
tearDown () {
|
||||
const { _converse } = this.__super__;
|
||||
const groupchats = this.chatboxes.where({'type': _converse.CHATROOMS_TYPE});
|
||||
_.each(groupchats, gc => u.safeSave(gc, {'connection_status': converse.ROOMSTATUS.DISCONNECTED}));
|
||||
this.__super__.tearDown.call(this, arguments);
|
||||
},
|
||||
|
||||
ChatBoxes: {
|
||||
model (attrs, options) {
|
||||
const { _converse } = this.__super__;
|
||||
if (attrs.type == _converse.CHATROOMS_TYPE) {
|
||||
if (attrs && attrs.type == _converse.CHATROOMS_TYPE) {
|
||||
return new _converse.ChatRoom(attrs, options);
|
||||
} else {
|
||||
return this.__super__.model.apply(this, arguments);
|
||||
@ -528,11 +535,15 @@ converse.plugins.add('converse-muc', {
|
||||
* registered for this groupchat.
|
||||
*/
|
||||
if (this.message_handler) {
|
||||
_converse.connection.deleteHandler(this.message_handler);
|
||||
if (_converse.connection) {
|
||||
_converse.connection.deleteHandler(this.message_handler);
|
||||
}
|
||||
delete this.message_handler;
|
||||
}
|
||||
if (this.presence_handler) {
|
||||
_converse.connection.deleteHandler(this.presence_handler);
|
||||
if (_converse.connection) {
|
||||
_converse.connection.deleteHandler(this.presence_handler);
|
||||
}
|
||||
delete this.presence_handler;
|
||||
}
|
||||
return this;
|
||||
@ -612,14 +623,13 @@ converse.plugins.add('converse-muc', {
|
||||
* @method _converse.ChatRoom#leave
|
||||
* @param { string } [exit_msg] - Message to indicate your reason for leaving
|
||||
*/
|
||||
leave (exit_msg) {
|
||||
async leave (exit_msg) {
|
||||
this.features.destroy();
|
||||
this.occupants.browserStorage._clear();
|
||||
this.occupants.reset();
|
||||
this.occupants.clearSession();
|
||||
if (_converse.disco_entities) {
|
||||
const disco_entity = _converse.disco_entities.get(this.get('jid'));
|
||||
if (disco_entity) {
|
||||
disco_entity.destroy();
|
||||
await new Promise((success, error) => disco_entity.destroy({success, error}));
|
||||
}
|
||||
}
|
||||
if (_converse.api.connection.connected()) {
|
||||
@ -629,10 +639,11 @@ converse.plugins.add('converse-muc', {
|
||||
this.removeHandlers();
|
||||
},
|
||||
|
||||
close () {
|
||||
async close () {
|
||||
try {
|
||||
this.features.destroy();
|
||||
this.features.browserStorage._clear();
|
||||
await new Promise((success, reject) => {
|
||||
return this.features.destroy({success, 'error': (m, e) => reject(e)})
|
||||
});
|
||||
} catch (e) {
|
||||
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
@ -838,9 +849,10 @@ converse.plugins.add('converse-muc', {
|
||||
}
|
||||
const fields = await _converse.api.disco.getFields(this.get('jid'));
|
||||
this.save({
|
||||
'name': identity && identity.get('name'),
|
||||
'description': _.get(fields.findWhere({'var': "muc#roominfo_description"}), 'attributes.value')
|
||||
});
|
||||
'name': identity && identity.get('name'),
|
||||
'description': _.get(fields.findWhere({'var': "muc#roominfo_description"}), 'attributes.value')
|
||||
}
|
||||
);
|
||||
|
||||
const features = await _converse.api.disco.getFeatures(this.get('jid'));
|
||||
const attrs = Object.assign(
|
||||
@ -857,6 +869,7 @@ converse.plugins.add('converse-muc', {
|
||||
}
|
||||
attrs[fieldname.replace('muc_', '')] = true;
|
||||
});
|
||||
attrs.description = _.get(fields.findWhere({'var': "muc#roominfo_description"}), 'attributes.value');
|
||||
this.features.save(attrs);
|
||||
},
|
||||
|
||||
@ -1012,33 +1025,6 @@ converse.plugins.add('converse-muc', {
|
||||
return this.occupants.findWhere({'jid': _converse.bare_jid});
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse the presence stanza for the current user's affiliation and
|
||||
* role and save them on the relevant {@link _converse.ChatRoomOccupant}
|
||||
* instance.
|
||||
* @private
|
||||
* @method _converse.ChatRoom#saveAffiliationAndRole
|
||||
* @param { XMLElement } pres - A <presence> stanza.
|
||||
*/
|
||||
saveAffiliationAndRole (pres) {
|
||||
const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
|
||||
const is_self = (pres.querySelector("status[code='110']") !== null);
|
||||
if (is_self && item) {
|
||||
const affiliation = item.getAttribute('affiliation');
|
||||
const role = item.getAttribute('role');
|
||||
const changes = {};
|
||||
if (affiliation) {
|
||||
changes['affiliation'] = affiliation;
|
||||
}
|
||||
if (role) {
|
||||
changes['role'] = role;
|
||||
}
|
||||
if (!_.isEmpty(changes)) {
|
||||
this.getOwnOccupant().save(changes);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Send an IQ stanza specifying an affiliation change.
|
||||
* @private
|
||||
@ -1265,8 +1251,7 @@ converse.plugins.add('converse-muc', {
|
||||
},
|
||||
|
||||
/**
|
||||
* Given a presence stanza, update the occupant model
|
||||
* based on its contents.
|
||||
* Given a presence stanza, update the occupant model based on its contents.
|
||||
* @private
|
||||
* @method _converse.ChatRoom#updateOccupantsOnPresence
|
||||
* @param { XMLElement } pres - The presence stanza
|
||||
@ -1572,7 +1557,13 @@ converse.plugins.add('converse-muc', {
|
||||
!this.ignorableCSN(attrs) &&
|
||||
(attrs['chat_state'] || !u.isEmptyMessage(attrs))) {
|
||||
|
||||
const msg = this.correctMessage(attrs) || this.messages.create(attrs);
|
||||
const msg = this.correctMessage(attrs) ||
|
||||
await new Promise((success, reject) => {
|
||||
this.messages.create(
|
||||
attrs,
|
||||
{ success, 'erorr': (m, e) => reject(e) }
|
||||
)
|
||||
});
|
||||
this.incrementUnreadMsgCounter(msg);
|
||||
}
|
||||
_converse.api.trigger('message', {'stanza': original_stanza, 'chatbox': this});
|
||||
@ -1802,7 +1793,6 @@ converse.plugins.add('converse-muc', {
|
||||
this.save('connection_status', converse.ROOMSTATUS.ENTERED);
|
||||
}
|
||||
this.updateOccupantsOnPresence(stanza);
|
||||
this.saveAffiliationAndRole(stanza);
|
||||
|
||||
if (stanza.getAttribute('type') === 'unavailable') {
|
||||
this.handleDisconnection(stanza);
|
||||
@ -1839,6 +1829,7 @@ converse.plugins.add('converse-muc', {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.save({'connection_status': converse.ROOMSTATUS.ENTERED});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1983,6 +1974,12 @@ converse.plugins.add('converse-muc', {
|
||||
this.create(attrs);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Triggered once the member lists for this MUC have been fetched and processed.
|
||||
* @event _converse#membersFetched
|
||||
* @example _converse.api.listen.on('membersFetched', () => { ... });
|
||||
*/
|
||||
_converse.api.trigger('membersFetched');
|
||||
},
|
||||
|
||||
findOccupant (data) {
|
||||
@ -2142,7 +2139,7 @@ converse.plugins.add('converse-muc', {
|
||||
*/
|
||||
return _converse.chatboxes
|
||||
.filter(m => (m.get('type') === _converse.CHATROOMS_TYPE))
|
||||
.forEach(m => m.save('connection_status', converse.ROOMSTATUS.DISCONNECTED))
|
||||
.forEach(m => m.save({'connection_status': converse.ROOMSTATUS.DISCONNECTED}));
|
||||
}
|
||||
_converse.api.listen.on('disconnected', disconnectChatRooms);
|
||||
|
||||
@ -2267,15 +2264,14 @@ converse.plugins.add('converse-muc', {
|
||||
room && room.maybeShow(force);
|
||||
return room;
|
||||
} else {
|
||||
return jids.map(async jid => {
|
||||
const room = await _converse.api.rooms.create(jid, attrs);
|
||||
room.maybeShow(force);
|
||||
});
|
||||
const rooms = await Promise.all(jids.map(jid => _converse.api.rooms.create(jid, attrs)));
|
||||
rooms.forEach(r => r.maybeShow(force));
|
||||
return rooms;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object representing a MUC chatroom (aka groupchat)
|
||||
* Fetches the object representing a MUC chatroom (aka groupchat)
|
||||
*
|
||||
* @method _converse.api.rooms.get
|
||||
* @param {string} [jid] The room JID (if not specified, all rooms will be returned).
|
||||
|
@ -684,11 +684,10 @@ converse.plugins.add('converse-roster', {
|
||||
const jid = item.getAttribute('jid');
|
||||
if (this.isSelf(jid)) { return; }
|
||||
|
||||
const contact = this.get(jid),
|
||||
subscription = item.getAttribute("subscription"),
|
||||
ask = item.getAttribute("ask"),
|
||||
groups = _.map(item.getElementsByTagName('group'), Strophe.getText);
|
||||
|
||||
const contact = this.get(jid);
|
||||
const subscription = item.getAttribute("subscription");
|
||||
const ask = item.getAttribute("ask");
|
||||
const groups = Array.from(item.getElementsByTagName('group')).map(e => e.textContent);
|
||||
if (!contact) {
|
||||
if ((subscription === "none" && ask === null) || (subscription === "remove")) {
|
||||
return; // We're lazy when adding contacts.
|
||||
@ -959,7 +958,6 @@ converse.plugins.add('converse-roster', {
|
||||
if (_converse.shouldClearCache()) {
|
||||
if (_converse.roster) {
|
||||
_.invoke(_converse, 'roster.data.destroy');
|
||||
_.invoke(_converse, 'roster.data.browserStorage._clear');
|
||||
_converse.roster.clearSession();
|
||||
delete _converse.roster;
|
||||
}
|
||||
@ -1024,7 +1022,7 @@ converse.plugins.add('converse-roster', {
|
||||
* @namespace _converse.api.contacts
|
||||
* @memberOf _converse.api
|
||||
*/
|
||||
'contacts': {
|
||||
contacts: {
|
||||
/**
|
||||
* This method is used to retrieve roster contacts.
|
||||
*
|
||||
|
@ -225,7 +225,6 @@ converse.plugins.add('converse-status', {
|
||||
_converse.api.listen.on('clearSession', () => {
|
||||
if (_converse.shouldClearCache() && _converse.xmppstatus) {
|
||||
_converse.xmppstatus.destroy();
|
||||
_converse.xmppstatus.browserStorage._clear();
|
||||
delete _converse.xmppstatus;
|
||||
}
|
||||
});
|
||||
|
106
src/headless/package-lock.json
generated
106
src/headless/package-lock.json
generated
@ -1,9 +1,23 @@
|
||||
{
|
||||
"name": "@converse/headless",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"backbone": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz",
|
||||
"integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"underscore": ">=1.8.3"
|
||||
}
|
||||
},
|
||||
"backbone.browserStorage": {
|
||||
"version": "github:conversejs/backbone.browserStorage#4fcb17861023becb3b25dec7b3238253873c8cd6",
|
||||
"from": "github:conversejs/backbone.browserStorage#4fcb17861023becb3b25dec7b3238253873c8cd6",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
@ -15,6 +29,96 @@
|
||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
|
||||
"integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==",
|
||||
"dev": true
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
|
||||
"dev": true
|
||||
},
|
||||
"jed": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
|
||||
"integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=",
|
||||
"dev": true
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"localforage": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
|
||||
"integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lie": "3.1.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"dev": true
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.19.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
|
||||
"integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pluggable.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pluggable.js/-/pluggable.js-2.0.0.tgz",
|
||||
"integrity": "sha512-FgrSayXWfQQWL+RSDiCAFZbkEsY7hTZCiSuN9Ar/mcHpesxOPfrSzJKp+YbimOt9QFtSd+lR8Uob5tgkdQSOzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"strophe.js": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.3.2.tgz",
|
||||
"integrity": "sha512-N6n93B0+0/qRazWUtgunJNE3DTfEpz363i17Uvnqh0lvl9iATnMtSoZtKjqN3reKPtjtBpbBRMWAQJRc688QkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"strophejs-plugin-ping": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/strophejs-plugin-ping/-/strophejs-plugin-ping-0.0.3.tgz",
|
||||
"integrity": "sha512-HS/ArEGKXfu36fihjUSfjqmqOSyppQTJUbrkfEtOBRJmnaP3LsRRe5T2S3dmCdsWHKORaJYc/OHSKfFlxHPdqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"strophe.js": "^1.2.12"
|
||||
}
|
||||
},
|
||||
"strophejs-plugin-rsm": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/strophejs-plugin-rsm/-/strophejs-plugin-rsm-0.0.2.tgz",
|
||||
"integrity": "sha512-Yn/VpxNz3Gkb790rJkwMyjlwHWCjWA9UxIl5kwGnsr7Ofo1MHztgyQ8XwQF1DGFp3Y4oiXbjZ/whG3S/cIgIew==",
|
||||
"dev": true
|
||||
},
|
||||
"twemoji": {
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-11.3.0.tgz",
|
||||
"integrity": "sha512-xN/vlR6+gDmfjt6LInAqwGAv3Agwrmzx5TD1jEFwKS19IOGDrX0/3OB8GP1wUYPVIdkaer5hw6qd+52jzvz0Lg==",
|
||||
"dev": true
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
|
||||
"integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
|
||||
"dev": true
|
||||
},
|
||||
"urijs": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz",
|
||||
"integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,10 @@
|
||||
"gitHead": "9641dcdc820e029b05930479c242d2b707bbe8e2",
|
||||
"devDependencies": {
|
||||
"backbone": "1.4",
|
||||
"backbone.browserStorage": "0.0.5",
|
||||
"backbone.browserStorage": "conversejs/backbone.browserStorage#2d0ceaa2f38eedc60122bb0aa23c826dc37a9194",
|
||||
"filesize": "^4.1.2",
|
||||
"jed": "1.1.1",
|
||||
"localforage": "^1.7.3",
|
||||
"lodash": "^4.17.15",
|
||||
"pluggable.js": "2.0.1",
|
||||
"strophe.js": "1.3.4",
|
||||
|
@ -437,11 +437,11 @@ u.onMultipleEvents = function (events=[], callback) {
|
||||
events.forEach(e => e.object.on(e.event, handler));
|
||||
};
|
||||
|
||||
u.safeSave = function (model, attributes) {
|
||||
u.safeSave = function (model, attributes, options) {
|
||||
if (u.isPersistableModel(model)) {
|
||||
model.save(attributes);
|
||||
model.save(attributes, options);
|
||||
} else {
|
||||
model.set(attributes);
|
||||
model.set(attributes, options);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
<div class="list-container list-container--openrooms {{{ !o.rooms.length && 'hidden' || '' }}}">
|
||||
|
||||
<a href="#" class="list-toggle open-rooms-toggle controlbox-padded" title="{{{o.desc_rooms}}}">
|
||||
<span class="fa {[ if (o.toggle_state === o._converse.OPENED) { ]} fa-caret-down {[ } else { ]} fa-caret-right {[ } ]}">
|
||||
</span> {{{o.label_rooms}}}</a>
|
||||
<span class="fa {[ if (o.toggle_state === o._converse.OPENED) { ]} fa-caret-down {[ } else { ]} fa-caret-right {[ } ]}"></span>{{{o.label_rooms}}}</a>
|
||||
|
||||
<div class="items-list rooms-list open-rooms-list {{{ o.collapsed && 'collapsed' }}}">
|
||||
{[o.rooms.forEach(function (room) { ]}
|
||||
|
@ -76,13 +76,37 @@
|
||||
'Escalus, prince of Verona', 'The Nurse', 'Paris'
|
||||
];
|
||||
mock.pend_names = [
|
||||
'Lord Capulet', 'Lady Capulet', 'Servant'
|
||||
];
|
||||
mock.cur_names = [
|
||||
'Mercutio', 'Juliet Capulet', 'Lady Montague', 'Lord Montague', 'Friar Laurence',
|
||||
'Tybalt', 'Lady Capulet', 'Benviolo', 'Balthasar',
|
||||
'Peter', 'Abram', 'Sampson', 'Gregory', 'Potpan', 'Friar John'
|
||||
'Lord Capulet', 'Guard', 'Servant'
|
||||
];
|
||||
mock.current_contacts_map = {
|
||||
'Mercutio': ['Colleagues', 'friends & acquaintences'],
|
||||
'Juliet Capulet': ['friends & acquaintences'],
|
||||
'Lady Montague': ['Colleagues', 'Family'],
|
||||
'Lord Montague': ['Family'],
|
||||
'Friar Laurence': ['friends & acquaintences'],
|
||||
'Tybalt': ['friends & acquaintences'],
|
||||
'Lady Capulet': ['ænemies'],
|
||||
'Benviolo': ['friends & acquaintences'],
|
||||
'Balthasar': ['Colleagues'],
|
||||
'Peter': ['Colleagues'],
|
||||
'Abram': ['Colleagues'],
|
||||
'Sampson': ['Colleagues'],
|
||||
'Gregory': ['friends & acquaintences'],
|
||||
'Potpan': [],
|
||||
'Friar John': []
|
||||
};
|
||||
|
||||
const map = mock.current_contacts_map;
|
||||
const groups_map = {};
|
||||
Object.keys(map).forEach(k => {
|
||||
const groups = map[k].length ? map[k] : ["Ungrouped"];
|
||||
Object.values(groups).forEach(g => {
|
||||
groups_map[g] = groups_map[g] ? [...groups_map[g], k] : [k]
|
||||
});
|
||||
});
|
||||
mock.groups_map = groups_map;
|
||||
|
||||
mock.cur_names = Object.keys(mock.current_contacts_map);
|
||||
mock.num_contacts = mock.req_names.length + mock.pend_names.length + mock.cur_names.length;
|
||||
|
||||
mock.groups = {
|
||||
@ -195,42 +219,39 @@
|
||||
'no_trimming': true,
|
||||
'play_sounds': false,
|
||||
'use_emojione': false,
|
||||
'view_mode': mock.view_mode,
|
||||
'view_mode': mock.view_mode
|
||||
}, settings || {}));
|
||||
|
||||
_converse.ChatBoxViews.prototype.trimChat = function () {};
|
||||
|
||||
_converse.api.vcard.get = function (model, force) {
|
||||
return new Promise(resolve => {
|
||||
let jid;
|
||||
if (_.isString(model)) {
|
||||
jid = model;
|
||||
} else if (!model.get('vcard_updated') || force) {
|
||||
jid = model.get('jid') || model.get('muc_jid');
|
||||
}
|
||||
let fullname;
|
||||
if (!jid || jid == 'romeo@montague.lit') {
|
||||
jid = 'romeo@montague.lit';
|
||||
fullname = 'Romeo Montague' ;
|
||||
} else {
|
||||
const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
|
||||
const last = name.length-1;
|
||||
name[0] = name[0].charAt(0).toUpperCase()+name[0].slice(1);
|
||||
name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
|
||||
fullname = name.join(' ');
|
||||
}
|
||||
const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
|
||||
const result = {
|
||||
'vcard': vcard,
|
||||
'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
|
||||
'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
|
||||
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
|
||||
'url': _.get(vcard.querySelector('URL'), 'textContent'),
|
||||
'vcard_updated': dayjs().format(),
|
||||
'vcard_error': undefined
|
||||
};
|
||||
resolve(result);
|
||||
}).catch(e => _converse.log(e, Strophe.LogLevel.FATAL));
|
||||
let jid;
|
||||
if (_.isString(model)) {
|
||||
jid = model;
|
||||
} else if (!model.get('vcard_updated') || force) {
|
||||
jid = model.get('jid') || model.get('muc_jid');
|
||||
}
|
||||
let fullname;
|
||||
if (!jid || jid == 'romeo@montague.lit') {
|
||||
jid = 'romeo@montague.lit';
|
||||
fullname = 'Romeo Montague' ;
|
||||
} else {
|
||||
const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
|
||||
const last = name.length-1;
|
||||
name[0] = name[0].charAt(0).toUpperCase()+name[0].slice(1);
|
||||
name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
|
||||
fullname = name.join(' ');
|
||||
}
|
||||
const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
|
||||
return {
|
||||
'vcard': vcard,
|
||||
'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
|
||||
'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
|
||||
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
|
||||
'url': _.get(vcard.querySelector('URL'), 'textContent'),
|
||||
'vcard_updated': dayjs().format(),
|
||||
'vcard_error': undefined
|
||||
};
|
||||
};
|
||||
if (_.get(settings, 'auto_login') !== false) {
|
||||
_converse.api.user.login('romeo@montague.lit/orchard', 'secret');
|
||||
|
@ -31,10 +31,10 @@ require.config(config);
|
||||
|
||||
var specs = [
|
||||
"jasmine",
|
||||
//"spec/transcripts",
|
||||
// "spec/transcripts",
|
||||
// "spec/profiling",
|
||||
"spec/spoilers",
|
||||
"spec/roomslist",
|
||||
"spec/profiling",
|
||||
"spec/utils",
|
||||
"spec/converse",
|
||||
"spec/bookmarks",
|
||||
|
135
tests/utils.js
135
tests/utils.js
@ -47,17 +47,14 @@
|
||||
return req;
|
||||
};
|
||||
|
||||
utils.closeAllChatBoxes = function (converse) {
|
||||
var i, chatbox;
|
||||
for (i=converse.chatboxes.models.length-1; i>-1; i--) {
|
||||
chatbox = converse.chatboxes.models[i];
|
||||
converse.chatboxviews.get(chatbox.get('id')).close();
|
||||
}
|
||||
return this;
|
||||
utils.closeAllChatBoxes = function (_converse) {
|
||||
return Promise.all(_converse.chatboxviews.map(view => view.close()));
|
||||
};
|
||||
|
||||
utils.openControlBox = function () {
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
utils.openControlBox = async function (_converse) {
|
||||
const model = await _converse.api.chats.open('controlbox');
|
||||
await u.waitUntil(() => model.get('connected'));
|
||||
var toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
@ -68,9 +65,9 @@
|
||||
};
|
||||
|
||||
utils.closeControlBox = function () {
|
||||
var controlbox = document.querySelector("#controlbox");
|
||||
const controlbox = document.querySelector("#controlbox");
|
||||
if (u.isVisible(controlbox)) {
|
||||
var button = controlbox.querySelector(".close-chatbox-button");
|
||||
const button = controlbox.querySelector(".close-chatbox-button");
|
||||
if (!_.isNull(button)) {
|
||||
button.click();
|
||||
}
|
||||
@ -116,15 +113,19 @@
|
||||
return views;
|
||||
};
|
||||
|
||||
utils.openChatBoxFor = function (_converse, jid) {
|
||||
utils.openChatBoxFor = async function (_converse, jid) {
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
_converse.roster.get(jid).trigger("open");
|
||||
return u.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
|
||||
};
|
||||
|
||||
utils.openChatRoomViaModal = async function (_converse, jid, nick='') {
|
||||
// Opens a new chatroom
|
||||
utils.openControlBox(_converse);
|
||||
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
|
||||
const model = await _converse.api.chats.open('controlbox');
|
||||
await u.waitUntil(() => model.get('connected'));
|
||||
utils.openControlBox();
|
||||
const view = await _converse.chatboxviews.get('controlbox');
|
||||
const roomspanel = view.roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
utils.closeControlBox(_converse);
|
||||
const modal = roomspanel.add_room_modal;
|
||||
@ -281,6 +282,7 @@
|
||||
});
|
||||
_converse.connection._dataRecv(utils.createRequest(owner_list_stanza));
|
||||
}
|
||||
return new Promise(resolve => _converse.api.listen.on('membersFetched', resolve));
|
||||
};
|
||||
|
||||
utils.receiveOwnMUCPresence = function (_converse, muc_jid, nick) {
|
||||
@ -296,7 +298,8 @@
|
||||
}).up()
|
||||
.c('status').attrs({code:'110'});
|
||||
_converse.connection._dataRecv(utils.createRequest(presence));
|
||||
}
|
||||
// return utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||
};
|
||||
|
||||
|
||||
utils.openAndEnterChatRoom = async function (_converse, muc_jid, nick, features=[], members=[]) {
|
||||
@ -318,19 +321,36 @@
|
||||
};
|
||||
|
||||
utils.clearChatBoxMessages = function (converse, jid) {
|
||||
var view = converse.chatboxviews.get(jid);
|
||||
const view = converse.chatboxviews.get(jid);
|
||||
view.el.querySelector('.chat-content').innerHTML = '';
|
||||
view.model.messages.reset();
|
||||
view.model.messages.browserStorage._clear();
|
||||
return view.model.messages.clearSession();
|
||||
};
|
||||
|
||||
utils.createContacts = function (converse, type, length) {
|
||||
utils.createContact = async function (_converse, name, ask, requesting, subscription) {
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
if (_converse.roster.get(jid)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const contact = await new Promise((success, error) => {
|
||||
_converse.roster.create({
|
||||
'ask': ask,
|
||||
'fullname': name,
|
||||
'jid': jid,
|
||||
'requesting': requesting,
|
||||
'subscription': subscription
|
||||
}, {success, error});
|
||||
});
|
||||
return contact;
|
||||
};
|
||||
|
||||
utils.createContacts = async function (_converse, type, length) {
|
||||
/* Create current (as opposed to requesting or pending) contacts
|
||||
* for the user's roster.
|
||||
*
|
||||
* These contacts are not grouped. See below.
|
||||
*/
|
||||
var names, jid, subscription, requesting, ask;
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
let names, subscription, requesting, ask;
|
||||
if (type === 'requesting') {
|
||||
names = mock.req_names;
|
||||
subscription = 'none';
|
||||
@ -347,33 +367,18 @@
|
||||
requesting = false;
|
||||
ask = null;
|
||||
} else if (type === 'all') {
|
||||
this.createContacts(converse, 'current')
|
||||
.createContacts(converse, 'requesting')
|
||||
.createContacts(converse, 'pending');
|
||||
await this.createContacts(_converse, 'current');
|
||||
await this.createContacts(_converse, 'requesting')
|
||||
await this.createContacts(_converse, 'pending');
|
||||
return this;
|
||||
} else {
|
||||
throw Error("Need to specify the type of contact to create");
|
||||
}
|
||||
|
||||
if (typeof length === 'undefined') {
|
||||
length = names.length;
|
||||
}
|
||||
for (var i=0; i<length; i++) {
|
||||
jid = names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
if (!converse.roster.get(jid)) {
|
||||
converse.roster.create({
|
||||
'ask': ask,
|
||||
'name': names[i],
|
||||
'jid': jid,
|
||||
'requesting': requesting,
|
||||
'subscription': subscription
|
||||
});
|
||||
}
|
||||
}
|
||||
return this;
|
||||
const promises = names.slice(0, length).map(n => this.createContact(_converse, n, ask, requesting, subscription));
|
||||
await Promise.all(promises);
|
||||
};
|
||||
|
||||
utils.waitForRoster = async function (_converse, type='current', length, include_nick=true) {
|
||||
utils.waitForRoster = async function (_converse, type='current', length=-1, include_nick=true, grouped=true) {
|
||||
const iq = await u.waitUntil(() =>
|
||||
_.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
@ -388,44 +393,36 @@
|
||||
'xmlns': 'jabber:iq:roster'
|
||||
});
|
||||
if (type === 'pending' || type === 'all') {
|
||||
mock.pend_names.slice(0, length).map(name =>
|
||||
const pend_names = (length > -1) ? mock.pend_names.slice(0, length) : mock.pend_names;
|
||||
pend_names.map(name =>
|
||||
result.c('item', {
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
name: include_nick ? name : undefined,
|
||||
subscription: 'to'
|
||||
}).up()
|
||||
);
|
||||
} else if (type === 'current' || type === 'all') {
|
||||
mock.cur_names.slice(0, length).map(name =>
|
||||
result.c('item', {
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
name: include_nick ? name : undefined,
|
||||
subscription: 'both'
|
||||
subscription: 'none',
|
||||
ask: 'subscribe'
|
||||
}).up()
|
||||
);
|
||||
}
|
||||
if (type === 'current' || type === 'all') {
|
||||
const cur_names = Object.keys(mock.current_contacts_map);
|
||||
const names = (length > -1) ? cur_names.slice(0, length) : cur_names;
|
||||
names.forEach(name => {
|
||||
result.c('item', {
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
name: include_nick ? name : undefined,
|
||||
subscription: 'both',
|
||||
ask: null
|
||||
});
|
||||
if (grouped) {
|
||||
mock.current_contacts_map[name].forEach(g => result.c('group').t(g).up());
|
||||
}
|
||||
result.up();
|
||||
});
|
||||
}
|
||||
_converse.connection._dataRecv(utils.createRequest(result));
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
};
|
||||
|
||||
utils.createGroupedContacts = function (converse) {
|
||||
/* Create grouped contacts
|
||||
*/
|
||||
let i=0, j=0;
|
||||
_.each(_.keys(mock.groups), function (name) {
|
||||
j = i;
|
||||
for (i=j; i<j+mock.groups[name]; i++) {
|
||||
converse.roster.create({
|
||||
'jid': mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
'subscription': 'both',
|
||||
'ask': null,
|
||||
'groups': name === 'ungrouped'? [] : [name],
|
||||
'name': mock.cur_names[i]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
utils.createChatMessage = function (_converse, sender_jid, message) {
|
||||
return $msg({
|
||||
from: sender_jid,
|
||||
|
Loading…
Reference in New Issue
Block a user