Commit 1443fdd4 authored by JC Brand's avatar JC Brand

(WIP) Wait for promises before opening chats in API methods

parent 41154614
This diff is collapsed.
......@@ -816,86 +816,75 @@ Note, for MUC chatrooms, you need to use the "rooms" grouping instead.
get
~~~
Returns an object representing a chatbox. The chatbox should already be open.
Returns an object representing a chat. The chat should already be open.
To return a single chatbox, provide the JID of the contact you're chatting
with in that chatbox:
To return a single chat, provide the JID of the contact you're chatting
with in that chat:
.. code-block:: javascript
_converse.api.chats.get('buddy@example.com')
To return an array of chatboxes, provide an array of JIDs:
To return an array of chats, provide an array of JIDs:
.. code-block:: javascript
_converse.api.chats.get(['buddy1@example.com', 'buddy2@example.com'])
To return all open chatboxes, call the method without any JIDs::
To return all open chats, call the method without any JIDs::
_converse.api.chats.get()
open
~~~~
Opens a chatbox and returns a `Backbone.View <http://backbonejs.org/#View>`_ object
representing a chatbox.
Opens a new chat.
It returns an promise which will resolve with a `Backbone.Model <https://backbonejs.org/#Model>`_ representing the chat.
Note that converse doesn't allow opening chats with users who aren't in your roster
(unless you have set :ref:`allow_non_roster_messaging` to ``true``).
Before opening a chat, you should first wait until the roster has been populated.
This is the :ref:`rosterContactsFetched` event/promise.
Besides that, it's a good idea to also first wait until already opened chatboxes
(which are cached in sessionStorage) have also been fetched from the cache.
This is the :ref:`chatBoxesFetched` event/promise.
These two events fire only once per session, so they're also available as promises.
So, to open a single chatbox:
So, to open a single chat:
.. code-block:: javascript
converse.plugins.add('myplugin', {
initialize: function() {
var _converse = this._converse;
Promise.all([
_converse.api.waitUntil('rosterContactsFetched'),
_converse.api.waitUntil('chatBoxesFetched')
]).then(function() {
initialize: function() {
var _converse = this._converse;
// Note, buddy@example.org must be in your contacts roster!
_converse.api.chats.open('buddy@example.com')
});
}
_converse.api.chats.open('buddy@example.com').then((chat) => {
// Now you can do something with the chat model
});
}
});
To return an array of chatboxes, provide an array of JIDs:
To return an array of chats, provide an array of JIDs:
.. code-block:: javascript
converse.plugins.add('myplugin', {
initialize: function () {
var _converse = this._converse;
Promise.all([
_converse.api.waitUntil('rosterContactsFetched'),
_converse.api.waitUntil('chatBoxesFetched')
]).then(function() {
// Note, these users must first be in your contacts roster!
_converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com'])
// Note, these users must first be in your contacts roster!
_converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then((chats) => {
// Now you can do something with the chat models
});
}
});
*The returned chatbox object contains the following methods:*
*The returned chat object contains the following methods:*
+-------------------+------------------------------------------+
| Method | Description |
+===================+==========================================+
| close | Close the chatbox. |
| close | Close the chat. |
+-------------------+------------------------------------------+
| focus | Focuses the chatbox textarea |
| focus | Focuses the chat textarea |
+-------------------+------------------------------------------+
| model.endOTR | End an OTR (Off-the-record) session. |
+-------------------+------------------------------------------+
......@@ -903,13 +892,13 @@ To return an array of chatboxes, provide an array of JIDs:
+-------------------+------------------------------------------+
| model.initiateOTR | Start an OTR (off-the-record) session. |
+-------------------+------------------------------------------+
| model.maximize | Minimize the chatbox. |
| model.maximize | Minimize the chat. |
+-------------------+------------------------------------------+
| model.minimize | Maximize the chatbox. |
| model.minimize | Maximize the chat. |
+-------------------+------------------------------------------+
| model.set | Set an attribute (i.e. mutator). |
+-------------------+------------------------------------------+
| show | Opens/shows the chatbox. |
| show | Opens/shows the chat. |
+-------------------+------------------------------------------+
*The get and set methods can be used to retrieve and change the following attributes:*
......@@ -917,9 +906,9 @@ To return an array of chatboxes, provide an array of JIDs:
+-------------+-----------------------------------------------------+
| Attribute | Description |
+=============+=====================================================+
| height | The height of the chatbox. |
| height | The height of the chat. |
+-------------+-----------------------------------------------------+
| url | The URL of the chatbox heading. |
| url | The URL of the chat heading. |
+-------------+-----------------------------------------------------+
The **chatviews** grouping
......@@ -1014,7 +1003,7 @@ The **rooms** grouping
get
~~~
Returns an object representing a multi user chatbox (room).
Returns an object representing a multi user chat (room).
It takes 3 parameters:
* the room JID (if not specified, all rooms will be returned).
......@@ -1046,7 +1035,7 @@ It takes 3 parameters:
open
~~~~
Opens a multi user chatbox and returns an object representing it.
Opens a multi user chat and returns an object representing it.
Similar to the ``chats.get`` API.
It takes 2 parameters:
......@@ -1055,7 +1044,7 @@ It takes 2 parameters:
* A map (object) containing any extra room attributes. For example, if you want
to specify the nickname, use ``{'nick': 'bloodninja'}``.
To open a single multi user chatbox, provide the JID of the room:
To open a single multi user chat, provide the JID of the room:
.. code-block:: javascript
......@@ -1328,7 +1317,7 @@ Parameters:
Returns a Promise which results with the VCard data for a particular JID or for
a `Backbone.Model` instance which represents an entity with a JID (such as a roster contact,
chatbox or chatroom occupant).
chat or chatroom occupant).
If a `Backbone.Model` instance is passed in, then it must have either a `jid`
attribute or a `muc_jid` attribute.
......
......@@ -2978,9 +2978,9 @@
"dev": true
},
"bootstrap.native": {
"version": "2.0.22",
"resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-2.0.22.tgz",
"integrity": "sha512-eypi4y1eKJoRt8cTwkZCI3QQ7W04rbv4VU1nBjBshqNXkONI7jO6tG3qZTwq9Zd+gDoeaQASyk6V185y+Y7KHQ==",
"version": "2.0.23",
"resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-2.0.23.tgz",
"integrity": "sha512-bcbVgqIjRkyiHd6DN8Y18BYjJTKvvnN3Msb7Yh6K5vGGsjRT3gV0IFKR3rcEYgJ5Kvg1egL9exIfN/Hvwn4wNA==",
"dev": true
},
"bourbon": {
......
......@@ -19,32 +19,35 @@
it("has a /help command to show the available commands",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current');
test_utils.createContacts(_converse, 'current', 1);
_converse.emit('rosterContactsFetched');
test_utils.openControlBox();
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid);
test_utils.sendMessage(view, '/help');
test_utils.waitUntil(() => _converse.chatboxes.length == 2).then(() => {
var view = _converse.chatboxviews.get(contact_jid);
test_utils.sendMessage(view, '/help');
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info:not(.chat-date)'), 0);
expect(info_messages.length).toBe(3);
expect(info_messages.pop().textContent).toBe('/help: Show this menu');
expect(info_messages.pop().textContent).toBe('/me: Write in the third person');
expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info:not(.chat-date)'), 0);
expect(info_messages.length).toBe(3);
expect(info_messages.pop().textContent).toBe('/help: Show this menu');
expect(info_messages.pop().textContent).toBe('/me: Write in the third person');
expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
var msg = $msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello world').tree();
_converse.chatboxes.onMessage(msg);
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
done();
var msg = $msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello world').tree();
_converse.chatboxes.onMessage(msg);
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
done();
});
}));
......@@ -108,38 +111,48 @@
});
}));
it("is created when you click on a roster item",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
it("is created when you click on a roster item", mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox();
var i, $el, jid, chatboxview;
let jid, online_contacts;
// openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created.
expect(_converse.chatboxes.length).toEqual(1);
spyOn(_converse.chatboxviews, 'trimChats');
expect($("#conversejs .chatbox").length).toBe(1); // Controlbox is open
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(1); // Controlbox is open
test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('.roster-group li').length;
}, 700).then(function () {
var online_contacts = $(_converse.rosterview.el).find('.roster-group .current-xmpp-contact a.open-chat');
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700).then(function () {
online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
expect(online_contacts.length).toBe(15);
for (i=0; i<online_contacts.length; i++) {
$el = $(online_contacts[i]);
jid = $el.text().trim().replace(/ /g,'.').toLowerCase() + '@localhost';
$el[0].click();
chatboxview = _converse.chatboxviews.get(jid);
expect(_converse.chatboxes.length).toEqual(i+2);
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// Check that new chat boxes are created to the left of the
// controlbox (but to the right of all existing chat boxes)
expect($("#conversejs .chatbox").length).toBe(i+2);
expect($("#conversejs .chatbox")[1].id).toBe(chatboxview.model.get('box_id'));
}
const el = online_contacts[0];
jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@localhost';
el.click();
return test_utils.waitUntil(() => _converse.chatboxes.length == 2);
}).then(() => {
const chatboxview = _converse.chatboxviews.get(jid);
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// Check that new chat boxes are created to the left of the
// controlbox (but to the right of all existing chat boxes)
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(2);
expect(document.querySelectorAll("#conversejs .chatbox")[1].id).toBe(chatboxview.model.get('box_id'));
online_contacts[1].click();
return test_utils.waitUntil(() => _converse.chatboxes.length == 3);
}).then(() => {
const el = online_contacts[1];
const new_jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@localhost';
const chatboxview = _converse.chatboxviews.get(jid);
const new_chatboxview = _converse.chatboxviews.get(new_jid);
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// Check that new chat boxes are created to the left of the
// controlbox (but to the right of all existing chat boxes)
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(3);
expect(document.querySelectorAll("#conversejs .chatbox")[2].id).toBe(chatboxview.model.get('box_id'));
expect(document.querySelectorAll("#conversejs .chatbox")[1].id).toBe(new_chatboxview.model.get('box_id'));
done();
});
}));
......
......@@ -66,47 +66,50 @@
it("shows the number of unread mentions received",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'all').openControlBox();
_converse.emit('rosterContactsFetched');
var contacts_panel = _converse.chatboxviews.get('controlbox').contactspanel;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, sender_jid);
var 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();
var msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello again').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
chatview.model.set({'minimized': false});
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
done();
return test_utils.waitUntil(() => _converse.chatboxes.length).then(() => {
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();
var msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('hello again').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
chatview.model.set({'minimized': false});
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
done();
});
}));
});
......
(function (root, factory) {
define([
"jquery",
"jasmine",
"mock",
"test-utils"], factory);
} (this, function ($, jasmine, mock, test_utils) {
var b64_sha1 = converse.env.b64_sha1;
var _ = converse.env._;
} (this, function (jasmine, mock, test_utils) {
const b64_sha1 = converse.env.b64_sha1,
_ = converse.env._,
u = converse.env.utils;
describe("Converse", function() {
......@@ -274,59 +274,72 @@
describe("The \"chats\" API", function() {
it("has a method 'get' which returns the chatbox model", mock.initConverseWithPromises(
null, ['rosterInitialized'], {}, function (done, _converse) {
it("has a method 'get' which returns the promise that resolves to a chat model", mock.initConverseWithPromises(
null, ['rosterInitialized', 'chatBoxesInitialized'], {}, function (done, _converse) {
test_utils.openControlBox();
test_utils.createContacts(_converse, 'current');
test_utils.createContacts(_converse, 'current', 2);
_converse.emit('rosterContactsFetched');
// Test on chat that doesn't exist.
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// Test on chat that's not open
var box = _converse.api.chats.get(jid);
let box = _converse.api.chats.get(jid);
expect(typeof box === 'undefined').toBeTruthy();
var chatboxview = _converse.chatboxviews.get(jid);
// Test for single JID
expect(_converse.chatboxes.length).toBe(1);
// Test for one JID
test_utils.openChatBoxFor(_converse, jid);
box = _converse.api.chats.get(jid);
test_utils.waitUntil(() => _converse.chatboxes.length == 1).then(() => {
box = _converse.api.chats.get(jid);
expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid));
const chatboxview = _converse.chatboxviews.get(jid);
expect(u.isVisible(chatboxview.el)).toBeTruthy();
// Test for multiple JIDs
test_utils.openChatBoxFor(_converse, jid2);
return test_utils.waitUntil(() => _converse.chatboxes.length == 2);
}).then(() => {
const list = _converse.api.chats.get([jid, jid2]);
expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
done();
}).catch(_.partial(console.error, _));
}));
it("has a method 'open' which opens and returns promise that resolves to a chat model", mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesInitialized'], {}, function (done, _converse) {
test_utils.openControlBox();
test_utils.createContacts(_converse, 'current', 2);
_converse.emit('rosterContactsFetched');
const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// Test on chat that doesn't exist.
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
return _converse.api.chats.open(jid).then((box) => {
expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid));
chatboxview = _converse.chatboxviews.get(jid);
expect($(chatboxview.el).is(':visible')).toBeTruthy();
expect(
_.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
const chatboxview = _converse.chatboxviews.get(jid);
expect(u.isVisible(chatboxview.el)).toBeTruthy();
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, jid2);
var list = _converse.api.chats.get([jid, jid2]);
return _converse.api.chats.open([jid, jid2]);
}).then((list) => {
expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
done();
}));
it("has a method 'open' which opens and returns the chatbox model", mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
test_utils.openControlBox();
test_utils.createContacts(_converse, 'current');
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var chatboxview;
// Test on chat that doesn't exist.
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
var box = _converse.api.chats.open(jid);
expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid));
expect(
_.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
chatboxview = _converse.chatboxviews.get(jid);
expect($(chatboxview.el).is(':visible')).toBeTruthy();
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = _converse.api.chats.open([jid, jid2]);
expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
done();
});
}));
});
......
(function (root, factory) {
define(["jquery", "jasmine", "mock", "test-utils"], factory);
} (this, function ($, jasmine, mock, test_utils) {
var _ = converse.env._;
var $msg = converse.env.$msg;
const _ = converse.env._;
const $msg = converse.env.$msg;
const u = converse.env.utils;
describe("The Minimized Chats Widget", function () {
......@@ -62,9 +63,8 @@
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
_converse.minimized_chats.el.querySelector('#toggle-minimized-chats').click();
return test_utils.waitUntil(function () {
return $(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')).is(':visible');
}, 500).then(function () {
return test_utils.waitUntil(() => u.isVisible(u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout'))))
.then(function () {
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
done();
});
......@@ -72,70 +72,79 @@
it("shows the number messages received to minimized chats",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
test_utils.openControlBox();
_converse.minimized_chats.toggleview.model.browserStorage._clear();
_converse.minimized_chats.initToggle();
var i, contact_jid, chatview, msg;
_converse.minimized_chats.toggleview.model.set({'collapsed': true});
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeFalsy();
const unread_el = _converse.minimized_chats.toggleview.el.querySelector('.unread-message-count');
expect(_.isNull(unread_el)).toBe(true);
for (i=0; i<3; i++) {
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
chatview = _converse.chatboxviews.get(contact_jid);
chatview.model.set({'minimized': true});
msg = $msg({
}
return test_utils.waitUntil(() => _converse.chatboxes.length == 4).then(() => {
for (i=0; i<3; i++) {
chatview = _converse.chatboxviews.get(contact_jid);
chatview.model.set({'minimized': true});
msg = $msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('This message is sent to a minimized chatbox').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeTruthy();
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i+1).toString());
}
// Chat state notifications don't increment the unread messages counter
// <composing> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').t('This message is sent to a minimized chatbox').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeTruthy();
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i+1).toString());
}
// Chat state notifications don't increment the unread messages counter
// <composing> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('composing', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <paused> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('paused', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <gone> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('gone', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <inactive> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('inactive', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
done();
}).c('composing', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <paused> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('paused', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <gone> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('gone', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
// <inactive> state
_converse.chatboxes.onMessage($msg({
from: contact_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('inactive', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
done();
});
}));
it("shows the number messages received to minimized groupchats",
......
......@@ -16,22 +16,23 @@
it("can be used to remove a contact",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
let view, show_modal_button, modal;
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
const show_modal_button = view.el.querySelector('.show-user-details-modal');
expect(u.isVisible(show_modal_button)).toBeTruthy();
show_modal_button.click();
const modal = view.user_details_modal;
test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
.then(function () {
return test_utils.waitUntil(() => _converse.chatboxes.length).then(() => {
view = _converse.chatboxviews.get(contact_jid);
show_modal_button = view.el.querySelector('.show-user-details-modal');
expect(u.isVisible(show_modal_button)).toBeTruthy();
show_modal_button.click();
modal = view.user_details_modal;
return test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
}).then(function () {
spyOn(window, 'confirm').and.returnValue(true);
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback) {
callback();
......
......@@ -69,12 +69,7 @@
Strophe.LogLevel.WARN
);
}
Promise.all([
_converse.api.waitUntil('rosterContactsFetched'),
_converse.api.waitUntil('chatBoxesFetched')
]).then(() => {
_converse.api.chats.open(jid);
});
_converse.api.chats.open(jid);
}
_converse.router.route('converse/chat?jid=:jid', openChat);
......@@ -905,15 +900,22 @@
});
},
'open' (jids, attrs) {
if (_.isUndefined(jids)) {
_converse.log("chats.open: You need to provide at least one JID", Strophe.LogLevel.ERROR);
return null;
} else if (_.isString(jids)) {
const chatbox = _converse.api.chats.create(jids, attrs);
chatbox.trigger('show');
return chatbox;
}
return _.map(jids, (jid) => _converse.api.chats.create(jid, attrs).trigger('show'));
return new Promise((resolve, reject) => {
Promise.all([
_converse.api.waitUntil('rosterContactsFetched'),
_converse.api.waitUntil('chatBoxesFetched')
]).then(() => {
if (_.isUndefined(jids)) {
const err_msg = "chats.open: You need to provide at least one JID";
_converse.log(err_msg, Strophe.LogLevel.ERROR);
reject(new Error(err_msg));
} else if (_.isString(jids)) {
resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
} else {
resolve(_.map(jids, (jid) => _converse.api.chats.create(jid, attrs).trigger('show')));
}
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
});
},
'get' (jids) {
if (_.isUndefined(jids)) {
......
......@@ -1254,14 +1254,23 @@
}
return _.map(jids, _.partial(createChatRoom, _, attrs));
},
'open' (jids, attrs) {
if (_.isUndefined(jids)) {
throw new TypeError('rooms.open: You need to provide at least one JID');
} else if (_.isString(jids)) {
return _converse.api.rooms.create(jids, attrs).trigger('show');
}
return _.map(jids, (jid) => _converse.api.rooms.create(jid, attrs).trigger('show'));
return new Promise((resolve, reject) => {
_converse.api.waitUntil('chatBoxesFetched').then(() => {
if (_.isUndefined(jids)) {
const err_msg = 'rooms.open: You need to provide at least one JID';
_converse.log(err_msg, Strophe.LogLevel.ERROR);
reject(new TypeError(err_msg));
} else if (_.isString(jids)) {
resolve(_converse.api.rooms.create(jids, attrs).trigger('show'));
} else {
resolve(_.map(jids, (jid) => _converse.api.rooms.create(jid, attrs).trigger('show')));
}
});
});
},
'get' (jids, attrs, create) {
if (_.isString(attrs)) {
attrs = {'nick': attrs};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment